📄 prof.c
字号:
/* -*-C-*- * * $Revision: 1.1 $ * $Author: rivimey $ * $Date: 1999/03/11 11:53:42 $ * * Copyright (c) 1995 Advanced RISC Machines Limited * All Rights Reserved. * * prof.c: Implementation of ADP_Profile subreasons. */#include "angel.h"#include "devconf.h"#include "adp.h"#include "channels.h"#include "debug.h"#include "debugos.h"#include "debughwi.h"#include "logging.h"#include "msgbuild.h"#include "support.h"#include "prof.h"#include "serlock.h"#include "timerd.h"AngelProfileState angel_profilestate;#if PROFILE_SUPPORTED && TIMER_SUPPORTED/**********************************************************************/static int profiling_enabled = FALSE;static int prof_timer;extern void Angel_ProfileHit(int data, unsigned empty_stack);void Angel_ProfileTimerInitialise(void){ prof_timer = 0; profiling_enabled = FALSE; LogInfo(LOG_PROF, ( "Profiling Initialised\n"));}/* We have to set the timer to the requested interval */void Angel_ProfileTimerStart(int interval){ profiling_enabled = TRUE; prof_timer = Timer_NewTimer(interval, TF_RELOAD, Angel_ProfileHit, 0); LogInfo(LOG_PROF, ( "Profiling Started\n"));}void Angel_ProfileTimerStop(void){ /* just delete the timer */ if (profiling_enabled) Timer_DeleteTimer(prof_timer); profiling_enabled = FALSE; LogInfo(LOG_PROF, ( "Profiling Stopped\n"));}void Angel_ProfileHit(int data, unsigned empty_stack){ unsigned pc; IGNORE(data); IGNORE(empty_stack); if (profiling_enabled) { pc = Angel_InterruptedPC(); if (angel_profilestate.enabled) { unsigned *map = angel_profilestate.map; int size = angel_profilestate.numentries; int low = 0, high = size-1; if (map[low] <= pc && pc < map[high]) { int i; for (;;) { i = (high + low) / 2; if (pc >= map[i]) { if (pc < map[i+1]) { i++; break; } else low = i; } else if (pc >= map[i-1]) break; else high = i; } angel_profilestate.counts[i-1]++; } } }}/**********************************************************************/static void free_buffer(p_Buffer * buffer){ angel_ChannelReleaseBuffer(*buffer); *buffer = NULL;}static int profile_supported(p_Buffer * buffer, void *stateptr){ /* Check whether profiling is available. */ IGNORE(stateptr); if (angelOS_ReturnInfo()->infoBitset & ADP_Info_Target_Profiling) { int debugID, OSinfo1, OSinfo2; unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2); free_buffer(buffer); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Profile | TtoH), debugID, OSinfo1, OSinfo2, ADP_Profile_Supported, RDIError_NoError); } else return -1;}static int profile_stop(p_Buffer * buffer, void *stateptr){ int debugID, OSinfo1, OSinfo2; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2); free_buffer(buffer); angel_profilestate.enabled = NO; Angel_ProfileTimerStop(); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Profile | TtoH), debugID, OSinfo1, OSinfo2, ADP_Profile_Stop, RDIError_NoError);}static int profile_start(p_Buffer * buffer, void *stateptr){ int debugID, OSinfo1, OSinfo2, subreason; int interval; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &interval); free_buffer(buffer); Angel_ProfileTimerStart(interval); angel_profilestate.enabled = YES; return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Profile | TtoH), debugID, OSinfo1, OSinfo2, ADP_Profile_Start, RDIError_NoError);}static int profile_writemap(p_Buffer * buffer, void *stateptr){ int debugID, OSinfo1, OSinfo2; word subreason, totalcount, wordoffset, wordcount; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &totalcount, &wordcount, &wordoffset); if (angel_profilestate.numentries != totalcount) { unsigned *counts = NULL; int mapsize = sizeof(int) * (totalcount + 1); int i;#if defined(Angel_ProfileAreaSize) && (Angel_ProfileAreaSize > 0) /* If there's a separate area configured for profiling to use, use it */ if (2 * mapsize <= Angel_ProfileAreaSize) {#if Angel_ProfileAreaIsRelativeToTopOfMemory counts = (unsigned *)(Angel_TopOfMemory + Angel_ProfileAreaBaseOffsetFromTopOfMemory);#else counts = (unsigned *)Angel_FixedProfileAreaBase;#endif } else counts = NULL;#else /* Otherwise, grab a block of heap, from the top of the heap */ if (angel_heapstackdesc.heapbase == 0 || ((2 * mapsize) < (angel_heapstackdesc.heaplimit - angel_heapstackdesc.heapbase))) { counts = (unsigned *)(angel_heapstackdesc.heaplimit - (2 * mapsize)); angel_heapstackdesc.heaplimit = counts; } else counts = NULL;#endif if (counts == NULL) { free_buffer(buffer); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Profile | TtoH), debugID, OSinfo1, OSinfo2, ADP_Profile_WriteMap, RDIError_OutOfStore); } angel_profilestate.counts = counts; angel_profilestate.map = (unsigned *)((char *)counts + mapsize); for (i = totalcount; i >= 0; i--) counts[i] = 0; angel_profilestate.numentries = totalcount; } __rt_memcpy(&angel_profilestate.map[wordoffset], BUFFERDATA(*buffer) + ADP_ProfileWriteHeaderSize, wordcount * sizeof(int)); free_buffer(buffer); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Profile | TtoH), debugID, OSinfo1, OSinfo2, ADP_Profile_WriteMap, RDIError_NoError);}static int profile_readmap(p_Buffer * buffer, void *stateptr){ /* Reads a number of words from the profiling map. */ p_Buffer rbuff; int debugID, OSinfo1, OSinfo2; word subreason, wordoffset, wordcount; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &wordoffset, &wordcount); free_buffer(buffer); rbuff = angel_ChannelAllocBuffer(Angel_ChanBuffSize); if (rbuff != NULL) { int count = msgbuild(BUFFERDATA(rbuff), "%w%w%w%w%w%w", (ADP_Profile | TtoH), debugID, OSinfo1, OSinfo2, ADP_Profile_ReadMap, RDIError_NoError); __rt_memcpy(BUFFERDATA(rbuff) + ADP_ProfileReadHeaderSize, &angel_profilestate.counts[wordoffset], wordcount * sizeof(int)); count += wordcount * sizeof(int); angel_ChannelSend(CH_DEFAULT_DEV, CI_HADP, rbuff, count); } else LogError(LOG_PROF, ( "Couldn't allocate buffer in 'profile_readmap'.\n")); return 0;}static int profile_clearcounts(p_Buffer * buffer, void *stateptr){ int debugID, OSinfo1, OSinfo2; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2); free_buffer(buffer); { int i; unsigned *map = angel_profilestate.counts; for (i = angel_profilestate.numentries; i >= 0; i--) map[i] = 0; } return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Profile | TtoH), debugID, OSinfo1, OSinfo2, ADP_Profile_ClearCounts, RDIError_NoError);}#else /* PROFILE_SUPPORTED */static int profile_supported(p_Buffer * buffer, void *stateptr){ IGNORE(buffer); IGNORE(stateptr); return -1;}static int profile_stop(p_Buffer * buffer, void *stateptr){ IGNORE(buffer); IGNORE(stateptr); return -1;}static int profile_start(p_Buffer * buffer, void *stateptr){ IGNORE(buffer); IGNORE(stateptr); return -1;}static int profile_writemap(p_Buffer * buffer, void *stateptr){ IGNORE(buffer); IGNORE(stateptr); return -1;}static int profile_readmap(p_Buffer * buffer, void *stateptr){ IGNORE(buffer); IGNORE(stateptr); return -1;}static int profile_clearcounts(p_Buffer * buffer, void *stateptr){ IGNORE(buffer); IGNORE(stateptr); return -1;}#endif /* PROFILE_SUPPORTED */const handler_function_pointer profile_hfptr[] ={ profile_supported, profile_stop, profile_start, profile_writemap, profile_readmap, profile_clearcounts};const int profile_hfptr_max =sizeof(profile_hfptr) / sizeof(handler_function_pointer);/* EOF prof.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -