Bläddra i källkod

Removed Limit of 50 retries in thread Resume, some improvements in profiler/gc coexistence

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7123 8c9fc860-2736-0410-a75d-ab315db34111
skoster 8 år sedan
förälder
incheckning
0b1baa2c84

+ 4 - 2
source/Generic.Linux.I386.Unix.Mod

@@ -807,7 +807,9 @@ VAR
 	    resume_done := 0; n := 1;
 	    res := pthread_kill( thr, T_SIGRESUME );
 
-	    WHILE (resume_done # 1) & (n < 50) DO ThrSleep(1); INC(n) END;
+	 (*   WHILE (resume_done # 1) & (n < 50) DO ThrSleep(1); INC(n) END; *)
+		WHILE (resume_done # 1)  DO ThrSleep(1); END;
+
 	    res := pthread_mutex_unlock( ADDRESS OF suspend_mutex );
 	END ThrResume;
 
@@ -819,7 +821,7 @@ VAR
 		IF suspendHandler # NIL THEN suspendHandler(S.VAL(Ucontext,ucp)) END;
 	    res := sigfillset( ADDRESS OF block );
 	    sigdelset(  ADDRESS OF block, T_SIGRESUME );
-	    suspend_done := 1;
+	    suspend_done := 1;   (*this is ok because ThrSuspend is protected by a mutex*)
 	    res := sigsuspend(  ADDRESS OF block ); (* await T_SIGRESUME *)
 	    resume_done := 1;
 	END suspend_handler;

+ 6 - 10
source/Generic.Unix.Objects.Mod

@@ -186,7 +186,7 @@ TYPE
 		context*: Unix.McontextDesc;
 		id-				: LONGINT;
 		body			: Body;
-		mode-		: LONGINT;
+		mode-		: LONGINT; (*states: 	Unknown,  Ready, Running, AwaitingLock,	AwaitingCond, AwaitingEvent,  Terminated as defined in the constants *)
 		flags-			: SET;
 		priority-		: LONGINT;	(* only effective if Aos is running SUID root *)
 		succ			: Process;   		  	(* in ProcessQueue *)
@@ -198,7 +198,6 @@ TYPE
 		procID-		: LONGINT;				(* processor ID where running, not used in UnixAos *)
 		state-			: Machine.State;		(*! not used in UnixAos! *)
 		state0	: ARRAY 2048 OF CHAR;		(* thread state at body start, used for restart after trap *)
-					
 				
 		PROCEDURE FindRoots*;
 		VAR sp, ptr, bp, n, a0, a1, adr: ADDRESS; desc: Modules.ProcedureDescPointer; i: LONGINT; p {UNTRACED}: ANY;
@@ -595,16 +594,13 @@ TYPE
 	BEGIN
 		ASSERT( process # NIL );
 		NEW(time);
-		(*res:=Unix.clock_gettime(3,time);
-		cpuCycles[0]:=time.usec;*)
-		cpuCycles[0]:=5;
-		(*todo*)
+		res:=Unix.clock_gettime(3,time); (*constant 3 for clock_thread_cputime_id*)
+		FOR i := 0 TO Machine.MaxCPU-1 DO  
+			cpuCycles[i] := 0  
+		END;
 		
-		(*FOR i := 0 TO Machine.MaxCPU-1 DO  
+		cpuCycles[0]:=time.usec;
 		
-			cpuCycles[i] := 0  
-			
-		END;*)
 	END GetCpuCycles;
 	
 	

+ 20 - 10
source/Unix.HierarchicalProfiler0.Mod

@@ -1,7 +1,7 @@
 MODULE HierarchicalProfiler0; (** AUTHOR "skoster"; PURPOSE "UnixAOS platform-specific part of the hierarchical profiler"; *)
 
 IMPORT
-	SYSTEM, Kernel, Unix, Objects, Modules, ProcessInfo;
+	SYSTEM, Kernel, Unix, Objects, Modules, ProcessInfo, Heaps;
 
 CONST
 	Initialized = 0;
@@ -25,6 +25,7 @@ TYPE
 		me : Objects.Process;
 		state : LONGINT;
 		timer: Kernel.Timer;
+		NormalGC: PROCEDURE; (*gc that is currently used*)
 
 		PROCEDURE &Init;
 		BEGIN
@@ -34,6 +35,7 @@ TYPE
 			NEW(times); Clear(times);
 			NEW(oldTimes); Clear(oldTimes);
 		END Init;
+	
 
 		PROCEDURE Terminate;
 		BEGIN {EXCLUSIVE}
@@ -60,16 +62,16 @@ TYPE
 		PROCEDURE Process;
 		VAR process : Objects.Process; cycles : Objects.CpuCyclesArray; temp : ProcessTimeArray; i : LONGINT;
 		BEGIN
-		
-			(*todo: stop gc*)
+			NormalGC := Heaps.GC;
+			Heaps.GC := Nothing; (*disable gc*)
 			ProcessInfo.GetProcesses(processes, nofProcesses);
-			TRACE(nofProcesses);
+			(*TRACE(nofProcesses);*)
 			FOR i := 0 TO nofProcesses - 1 DO
 				process := processes[i];
 
 				Objects.GetCpuCycles(process, cycles, FALSE); 
 				times[i] := cycles[0];
-				TRACE(process,me,cycles[0],process.mode,Objects.Running);
+				(*TRACE(process,me,cycles[0],process.mode,Objects.Running);*)
 				IF (process # me) & (cycles[0] # 0)  & (process.mode = Objects.Running) (* (process.mode # Objects.AwaitingEvent) & (process.mode # Objects.AwaitingCond)  & (process.mode < Objects.Suspended) & (process.mode >= Objects.Ready)  (*RanMeanwhile(process, times[i]) *) *) THEN
 					HandleProcess(process);
 				END;
@@ -80,7 +82,7 @@ TYPE
 			ProcessInfo.Copy(processes, oldProcesses); 
 			oldNofProcesses := nofProcesses;
 			ProcessInfo.Clear(processes);
-			(*todo: reenable gc*)
+			Heaps.GC := NormalGC; (*re-enable gc*)
 		END Process;
 
 	BEGIN {ACTIVE, PRIORITY(Objects.Realtime)}
@@ -104,6 +106,11 @@ VAR
 	callback : Callback;
 	state : LONGINT;
 
+PROCEDURE Nothing; (*no-op garbage collector*)
+BEGIN
+END Nothing;
+
+
 PROCEDURE HandleProcess(process : Objects.Process);
 (*VAR context : Kernel32.Context; handle : Kernel32.HANDLE; res : Kernel32.BOOL;*) 
 
@@ -118,6 +125,7 @@ BEGIN
 	(*from check at callsite it's guaranteed that the process is running (mode=Objects.Running) *)
 	
 	(*todo: validate thread ID*)
+	TRACE('suspending thread',threadId);
 	Unix.ThrSuspend(threadId);
 	(*because thread suspending is under a mutex in Unix.Mod, this call is guaranteed to have finished with the handler when it returns.*)
 	context:=process.context;
@@ -127,13 +135,15 @@ BEGIN
 		bp:=context.r_bp;
 		IF bp<=stackBottom THEN
 			callback(1, process, context.r_pc,bp,sp,  stackBottom  );
-		ELSE
+		ELSE	
 				Unix.ThrResume(threadId);
-				ASSERT(bp<=stackBottom);
+				TRACE('bp smaller than stack bottom found',threadId);
 		END;
-	END;
+	END;				
+	TRACE('resuming thread',threadId);
 	Unix.ThrResume(threadId);
-	
+	TRACE('successful resume',threadId);
+
 (*	handle := process.handle;
 	IF (handle # Kernel32.NULL) & (handle # Kernel32.InvalidHandleValue) THEN
 		res := Kernel32.SuspendThread(handle);