Source to bsd/hfs/hfscommon/Misc/HFSInstrumentation.c


Enter a symbol's name here to quickly find it.

/*
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
 * Reserved.  This file contains Original Code and/or Modifications of
 * Original Code as defined in and that are subject to the Apple Public
 * Source License Version 1.0 (the 'License').  You may not use this file
 * except in compliance with the License.  Please obtain a copy of the
 * License at http://www.apple.com/publicsource and read it before using
 * this file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License."
 * 
 * @APPLE_LICENSE_HEADER_END@
 */

/*
	File:		HFSInstrumentation.c

	Contains:	Code for instrumenting the File Manager

	Version:	HFS Plus 1.0

	Written by:	Mark Day

	Copyright:	� 1997 by Apple Computer, Inc., all rights reserved.

	File Ownership:

		DRI:				Mark Day

		Other Contacts:		Don Brady, Deric Horn

		Technology:			xxx put technology here xxx

	Writers:

		(DSH)	Deric Horn
		(djb)	Don Brady
		(msd)	Mark Day

	Change History (most recent first):

	   <CS5>	 7/21/97	djb		Add STLogStartTime and STLogEndTime routines for summary traces.
	   <CS4>	 7/16/97	DSH		FilesInternal.i renamed FileMgrInternal.i to avoid name
									collision
	   <CS3>	  5/9/97	djb		Include LowMemPriv.h
	   <CS2>	  5/7/97	djb		Add support for summary traces.
	   <CS1>	 4/24/97	djb		first checked in
	  <HFS5>	 2/27/97	msd		By default, disable the HFS instrumentation nodes. They can be
									turned on at runtime with the instrumentation viewer.
	  <HFS4>	 2/26/97	msd		Add nodes for HFS:Extents, and add data descriptor for an
									extent.
	  <HFS3>	  2/6/97	msd		Add a format descriptor for to help with logging FSSpec's.
	  <HFS2>	 1/21/97	msd		Create the HFS and VSM nodes in the instrumentation tree.
	  <HFS1>	 1/17/97	msd		first checked in
		<0>		 1/16/97	msd		First written.

*/

#if ( PRAGMA_LOAD_SUPPORTED )
        #pragma	load	PrecompiledHeaders
#else
        #if TARGET_OS_MAC
	#include	<Gestalt.h>
	#include	<LowMemPriv.h>
	#include	<Types.h>
        #else
	#include "../../hfs.h"
        #include "../headers/system/MacOSStubs.h"
        #endif 	/* TARGET_OS_MAC */
#endif	/* PRAGMA_LOAD_SUPPORTED */

#include	"../headers/FileMgrInternal.h"
#include	"../headers/system/HFSInstrumentation.h"


void GetTimeBase(UInt64 *timeBase);



void InitHFSInstrumentation(void);


void InitHFSInstrumentation(void)
{
#if TARGET_OS_MAC
	OSStatus				err;
	InstTraceClassRef		catSearch;
	FSVarsRec				*fsVars;
	InstPathClassRef		pathClass;
	InstDataDescriptorRef	specDescriptor;
	InstDataDescriptorRef	extentDescriptor;
	
        fsVars = (FSVarsRec*) LMGetFSMVars();
	
	err = InstInitialize68K();
	if (err != noErr) DebugStr("\pError from InstInitialize68K");
	
	err = InstCreatePathClass( kInstRootClassRef, "HFS", kInstEnableClassMask, &pathClass);
	if (err != noErr) DebugStr("\pError from InstCreatePathClass");
	
	if ( HFSInstrumentation )
	{
		err = InstCreatePathClass( kInstRootClassRef, "HFS:VSM", kInstEnableClassMask, &pathClass);
		if (err != noErr) DebugStr("\pError from InstCreatePathClass");
		err = InstCreatePathClass( kInstRootClassRef, "HFS:Extents", kInstEnableClassMask, &pathClass);
		if (err != noErr) DebugStr("\pError from InstCreatePathClass");
												
		err = InstCreateTraceClass(kInstRootClassRef, "HFS:CatSearch", 'srch', kInstEnableClassMask, &catSearch);
		if (err != noErr) DebugStr("\pError from InstCreateTraceClass");
		
		fsVars->later[0] = (UInt32) catSearch;
		
		err = InstCreateDataDescriptor( "[vol: %d, parID: %08lX, name: %s]", &specDescriptor);
		if (err != noErr) DebugStr("\pError from InstCreateDataDescriptor");
	
		fsVars->later[1] = (UInt32) specDescriptor;
		
		err = InstCreateDataDescriptor( "fileID: %8lX, start: %8lX, num: %8lX, FABN: %8lX", &extentDescriptor);
		if (err != noErr) DebugStr("\pError from InstCreateDataDescriptor");
	
		fsVars->later[2] = (UInt32) extentDescriptor;
	}
#endif
}


void STLogStartTime(UInt32 selector)
{
#if TARGET_OS_MAC
	FSVarsRec *fsVars;

	fsVars = (FSVarsRec*) LMGetFSMVars();

	if ( fsVars->gNativeCPUtype >= gestaltCPU601 )
	{
		CallProfile *p;

		p = &fsVars->gCallProfile[selector];
		
		if (p->refCount++ == 0)
			GetTimeBase(&p->startBase);		// record start time for first call (recursive calls are ignored)
	}
#else
#pragma unused(selector)
#endif 	/* TARGET_OS_MAC */
}


void STLogEndTime(UInt32 selector, OSErr error)
{
#if TARGET_OS_MAC
	FSVarsRec	*fsVars;

	fsVars = (FSVarsRec*) LMGetFSMVars();

	if ( fsVars->gNativeCPUtype >= gestaltCPU601 )
	{
		CallProfile *p;
		UInt64		timebase;		// in nanoseconds
		UInt32		elaspedTime;

		p = &fsVars->gCallProfile[selector];
		p->refCount--;
		
		if ( p->refCount != 0 )
			return;		// this is a recursive call, so skip
		
		GetTimeBase(&timebase);
		timebase = U64Subtract(timebase, p->startBase);
		

		// check if gTimeBaseFactor has been set up yet...
		if ( fsVars->gTimeBaseFactor == 0 )
		{
			long	response;
			OSErr	result;
			
			result = Gestalt( gestaltNativeCPUtype, &response );		
			if (result)  return;		// gTimeBaseFactor not ready yet so bail
	
			if ( fsVars->gNativeCPUtype == gestaltCPU601 )
			{
				fsVars->gTimeBaseFactor = (UInt32) 1000;		// convert from nanosec to �sec
			}
			else // 603 or 604 (ie has real TimeBase register)
			{
				result = Gestalt( gestaltBusClkSpeed, &response );
				if (result)  return;	// gTimeBaseFactor not ready yet so bail
	
				fsVars->gTimeBaseFactor = (UInt32) response / (UInt32) 4000000;		// calc �sec conversion factor
			}
		}
	
		if ( timebase.hi == 0 )
			elaspedTime = timebase.lo / fsVars->gTimeBaseFactor;
		else
			return;		// this time is too long (we're probally in the debugger!)

		
		if ( elaspedTime > p->maxTime )
			 p->maxTime = elaspedTime;
	
		if ( elaspedTime < p->minTime || p->minTime == 0 )
			 p->minTime = elaspedTime;
			 
		p->callCount++;
		
		if ( error != 0 )
			p->errCount++;
		
		timebase.lo = elaspedTime;
		timebase.hi = 0;
		p->totalTime = U64Add(p->totalTime, timebase);
	}
#else
#pragma unused(selector,error)
#endif 	/* TARGET_OS_MAC */
}