123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- MODULE HierarchicalProfiler0; (** AUTHOR "staubesv"; PURPOSE "Platform-specific part of the hierarchical profiler"; *)
- IMPORT
- SYSTEM, Machine, Objects, Modules, Kernel;
- CONST
- HandlerNotInstalled = 0;
- HandlerInstalled = 1;
- (* Time to wait when unloading the module before it is actually unloaded. This avoids that a pending interrupt
- calls 'HandleTimer' when the module is already unloaded. *)
- WaitTime = 100; (* ms *)
- TYPE
- Callback = PROCEDURE (id : LONGINT; process : Objects.Process; pc, bp, lowAdr, highAdr : ADDRESS);
- VAR
- callback : Callback;
- state : LONGINT;
- (* First level interrupt handler. Called 1000 times per second by each processor *)
- PROCEDURE HandleTimer(id: LONGINT; CONST state: Machine.State);
- VAR process : Objects.Process;
- BEGIN
- process := Objects.running[id];
- callback(id, process, state.PC, state.BP, state.SP, LONGINT(0FFFFFFFFH));
- END HandleTimer;
- (** Start profiling. If the profiler is already running, it is stopped and the sample data is discarded before re-starting it *)
- PROCEDURE Enable*(proc : Callback);
- BEGIN {EXCLUSIVE}
- ASSERT(proc # NIL);
- ASSERT(state = HandlerNotInstalled);
- Machine.InstallEventHandler(HandleTimer);
- state := HandlerInstalled;
- callback := proc;
- END Enable;
- (** Stop profiling. The profile data is not discarded. It can be retrieved using the procedure 'GetProfile' *)
- PROCEDURE Disable*;
- VAR timer : Kernel.Timer;
- BEGIN {EXCLUSIVE}
- ASSERT(state = HandlerInstalled);
- Machine.InstallEventHandler(NIL);
- NEW(timer); timer.Sleep(WaitTime);
- END Disable;
- PROCEDURE Cleanup;
- BEGIN
- Machine.InstallEventHandler(NIL);
- END Cleanup;
- BEGIN
- callback := NIL;
- state := HandlerNotInstalled;
- Modules.InstallTermHandler(Cleanup);
- END HierarchicalProfiler0.
|