Просмотр исходного кода

object tracker -> show stack works now

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7480 8c9fc860-2736-0410-a75d-ab315db34111
eth.guenter 7 лет назад
Родитель
Сommit
6378ee91e8
3 измененных файлов с 102 добавлено и 111 удалено
  1. 27 57
      source/Generic.Unix.I386.Machine.Mod
  2. 33 43
      source/Generic.Unix.Objects.Mod
  3. 42 11
      source/WMProcessInfo.Mod

+ 27 - 57
source/Generic.Unix.I386.Machine.Mod

@@ -52,14 +52,9 @@ TYPE
 		beginBlockAdr-, endBlockAdr-: ADDRESS
 	END;
 	
-	(** processor state, ordering of record fields is predefined! *)
-		(*!(not used in UnixAos, for interface compatibility only)*)
-	State* = RECORD					(* offsets used in FieldInterrupt, FieldIRQ and Objects.RestoreState *)
-		EDI*, ESI*, ERR*, ESP0*, EBX*, EDX*, ECX*, EAX*: LONGINT;	(** ESP0 = ADR(s.INT) *)
-		INT*, BP*, PC*, CS*: LONGINT;	(* BP and ERR are exchanged by glue code, for procedure link *)
-		FLAGS*: SET;
-		SP*, SS*: LONGINT;			(** only valid if (VMBit IN s.EFLAGS) OR (CS MOD 4 < s.CS MOD 4) *)
-		ES*, DS*, FS*, GS*: LONGINT;	(** only valid if (VMBit IN s.FLAGS) *)
+	(** processor state *)
+	State* = RECORD	
+		PC*, BP*, SP*: ADDRESS
 	END;
 	
 	
@@ -88,8 +83,6 @@ VAR
 	
 	standaloneAppl-: BOOLEAN;
 	
-	firstMemBlock: MemoryBlockDesc;		(* pseudo heap *)
-	
 	gcThreshold-: SIZE;
 	memBlockHead-{UNTRACED}, memBlockTail-{UNTRACED}: MemoryBlock; (* head and tail of sorted list of memory blocks *)
 	
@@ -101,16 +94,8 @@ VAR
 
 	timer0	: HUGEINT;
 
-
-	(** This procedure should be called in all spin loops as a hint to the processor (e.g. Pentium 4). *)
-	PROCEDURE -SpinHint*;
-	CODE {SYSTEM.i386}
-		XOR	ECX, ECX	;  just in case some processor interprets REP this way
-		REP	NOP	;  PAUSE instruction (* NOP on pre-P4 processors, Spin Loop Hint on P4 and after *)
-	END SpinHint;
-
 	(** Return current processor ID (0 to MaxNum-1). *)
-	PROCEDURE {REALTIME} ID* (): LONGINT;
+	PROCEDURE  ID* (): LONGINT;
 	BEGIN
 		RETURN 0
 	END ID;
@@ -262,24 +247,10 @@ VAR
 
 	(** Get first memory block and first free address, the first free address is identical to memBlockHead.endBlockAdr *)
 	PROCEDURE GetStaticHeap*(VAR beginBlockAdr, endBlockAdr, freeBlockAdr: ADDRESS);
-	VAR memBlockAdr: ADDRESS;
 	BEGIN
 		InitHeap(memBlockHead,beginBlockAdr, endBlockAdr);
 		memBlockTail := memBlockHead;
 
-		(*
-		SYSTEM.GET(bootHeapAdr + EndBlockOfs, freeBlockAdr);
-		ASSERT(freeBlockAdr MOD StaticBlockSize = 0);
-		memBlockAdr := bootHeapAdr + HeaderSize + MemoryBlockOfs;
-
-
-		memBlockHead := SYSTEM.VAL(MemoryBlock, memBlockAdr); (* this block will never be freed since there is a global reference (initBlock in Heaps.Mod) to it *)
-		memBlockHead.startAdr := bootHeapAdr;
-		memBlockHead.size := bootHeapSize;
-		ASSERT(memBlockHead.beginBlockAdr MOD StaticBlockSize = 0);
-		ASSERT((memBlockHead.endBlockAdr - memBlockHead.beginBlockAdr) MOD StaticBlockSize = 0);
-		memBlockTail := memBlockHead;
-		*)
 		beginBlockAdr := memBlockHead.beginBlockAdr;
 		endBlockAdr := memBlockHead.endBlockAdr;
 		freeBlockAdr := beginBlockAdr;
@@ -313,7 +284,7 @@ VAR
 	
 
 	(** Fill "size" bytes at "destAdr" with "filler". "size" must be multiple of 4. *)
-	PROCEDURE {REALTIME} Fill32* (destAdr: ADDRESS; size: SIZE; filler: LONGINT);
+	PROCEDURE  Fill32* (destAdr: ADDRESS; size: SIZE; filler: LONGINT);
 	CODE {SYSTEM.i386}
 		MOV EDI, [EBP+destAdr]
 		MOV ECX, [EBP+size]
@@ -328,7 +299,6 @@ VAR
 		REP STOSD
 	END Fill32;
 
-
 PROCEDURE  Portin8*(port: LONGINT; VAR val: CHAR);
 END Portin8;
 
@@ -395,7 +365,7 @@ CODE {SYSTEM.i386}
 END AtomicTestSet;
 
 (* Atomic compare-and-swap. Set x = new if x = old and return old value of x *)
-PROCEDURE {REALTIME} -AtomicCAS* (VAR x: LONGINT; old, new: LONGINT): LONGINT;
+PROCEDURE  -AtomicCAS* (VAR x: LONGINT; old, new: LONGINT): LONGINT;
 CODE {SYSTEM.i386}
 	POP EBX		; new
 	POP EAX		; old
@@ -405,81 +375,81 @@ END AtomicCAS;
 
 
 (* Return current instruction pointer *)
-PROCEDURE {REALTIME} CurrentPC* (): ADDRESS;
+PROCEDURE  CurrentPC* (): ADDRESS;
 CODE {SYSTEM.i386}
 	MOV EAX, [EBP+4]
 END CurrentPC;
 
 (* Return current frame pointer *)
-PROCEDURE {REALTIME} -CurrentBP* (): ADDRESS;
+PROCEDURE  -CurrentBP* (): ADDRESS;
 CODE {SYSTEM.i386}
 	MOV EAX, EBP
 END CurrentBP;
 
 (* Set current frame pointer *)
-PROCEDURE {REALTIME} -SetBP* (bp: ADDRESS);
+PROCEDURE  -SetBP* (bp: ADDRESS);
 CODE {SYSTEM.i386}
 	POP EBP
 END SetBP;
 
 (* Return current stack pointer *)
-PROCEDURE {REALTIME} -CurrentSP* (): ADDRESS;
+PROCEDURE  -CurrentSP* (): ADDRESS;
 CODE {SYSTEM.i386}
 	MOV EAX, ESP
 END CurrentSP;
 
 (* Set current stack pointer *)
-PROCEDURE {REALTIME} -SetSP* (sp: ADDRESS);
+PROCEDURE  -SetSP* (sp: ADDRESS);
 CODE {SYSTEM.i386}
 	POP ESP
 END SetSP;
 
-PROCEDURE {REALTIME} -GetEAX*(): LONGINT;
+PROCEDURE  -GetEAX*(): LONGINT;
 CODE{SYSTEM.i386}
 END GetEAX;
 
-PROCEDURE {REALTIME} -GetECX*(): LONGINT;
+PROCEDURE  -GetECX*(): LONGINT;
 CODE{SYSTEM.i386}
 	MOV EAX,ECX	
 END GetECX;
 
-PROCEDURE {REALTIME} -GetESI*(): LONGINT;
+PROCEDURE  -GetESI*(): LONGINT;
 CODE{SYSTEM.i386}
 	MOV EAX,ESI	
 END GetESI;
 
-PROCEDURE {REALTIME} -GetEDI*(): LONGINT;
+PROCEDURE  -GetEDI*(): LONGINT;
 CODE{SYSTEM.i386}
 	MOV EAX,EDI	
 END GetEDI;
 
 
-PROCEDURE {REALTIME} -SetEAX*(n: LONGINT);
+PROCEDURE  -SetEAX*(n: LONGINT);
 CODE{SYSTEM.i386}	
 	POP EAX
 END SetEAX;
 
-PROCEDURE {REALTIME} -SetEBX*(n: LONGINT);
+PROCEDURE  -SetEBX*(n: LONGINT);
 CODE{SYSTEM.i386}
 	POP EBX
 END SetEBX;
 
-PROCEDURE {REALTIME} -SetECX*(n: LONGINT);
+PROCEDURE  -SetECX*(n: LONGINT);
 CODE{SYSTEM.i386}
 	POP ECX
 END SetECX;
 
-PROCEDURE {REALTIME} -SetEDX*(n: LONGINT);
+PROCEDURE  -SetEDX*(n: LONGINT);
 CODE{SYSTEM.i386}
 	POP EDX
 END SetEDX;
 
-PROCEDURE {REALTIME} -SetESI*(n: LONGINT);
+PROCEDURE  -SetESI*(n: LONGINT);
 CODE{SYSTEM.i386}
 	POP ESI
 END SetESI;
 
-PROCEDURE {REALTIME} -SetEDI*(n: LONGINT);
+PROCEDURE  -SetEDI*(n: LONGINT);
 CODE{SYSTEM.i386}
 	POP EDI
 END SetEDI;
@@ -557,9 +527,9 @@ END GetTimer;
 
 	(* function returning the number of processors that are available to Aos *)
 	PROCEDURE NumberOfProcessors*( ): LONGINT;
-		VAR res: LONGINT;
+	VAR res: LONGINT;
 	BEGIN
-		res:=Unix.getnprocs();
+		res := Unix.getnprocs();
 		RETURN res;
 	END NumberOfProcessors;
 
@@ -695,7 +665,7 @@ END GetTimer;
 
 	(* Initialize locks. *)
 	PROCEDURE InitLocks;  
-	VAR i: LONGINT;  a: ADDRESS;
+	VAR i: LONGINT; 
 	BEGIN 
 		i := 0;  
 		WHILE i < MaxLocks DO  mtx[i] := Unix.NewMtx( );  INC( i )  END;   
@@ -743,8 +713,8 @@ END GetTimer;
 		TypeDescOffset = -AddressSize; (* see Heaps.Mod *)
 		HeapBlockOffset = - 2 * AddressSize; (* see Heaps.Mod *)
 		DataAdrOffset = AddressSize; (* offset of dataAdr field in Heaps.HeapBlockDesc *)
-	VAR memDescSize, memBlkSize, alignOffset: SIZE; adr, memHeaderAdr, memBlockAdr, memBlockHeadAdr: ADDRESS;
-		memBlock {UNTRACED}: MemoryBlock; i: LONGINT; ch: CHAR; h: HUGEINT; size: LONGINT;
+	VAR memDescSize, memBlkSize, alignOffset: SIZE; adr, memHeaderAdr, memBlockAdr: ADDRESS;
+		memBlock {UNTRACED}: MemoryBlock; size: LONGINT;
 		initVal: LONGINT;
 	BEGIN
 
@@ -885,7 +855,7 @@ END GetTimer;
 	
 	
 	PROCEDURE InitLog;
-	VAR name, cmd: ARRAY 32 OF CHAR;  pid, i: LONGINT; 
+	VAR name: ARRAY 32 OF CHAR;  pid, i: LONGINT; 
 	BEGIN
 		name := "AOS.xxxxx.Log";
 		pid := Unix.getpid();  i := 8;

+ 33 - 43
source/Generic.Unix.Objects.Mod

@@ -165,7 +165,6 @@ TYPE
 					n.finalizer(n.objStrong)	(* may acquire locks *)
 				END;
 			END;
-		(*	Machine.ReleaseGC( )	*)
 		END
 	END FinalizerCaller;
 	
@@ -191,7 +190,7 @@ TYPE
 		continue		: Unix.Condition_t;	(* gets signaled when condition yields true *)
 		waitingOn-	: ProtectedObject;
 		procID-		: LONGINT;				(*! processor ID where running, not used in UnixAos *)
-		state-			: Machine.State;		(*! only PC, SP and BP are updated in UnixAos *)
+		state-			: Machine.State;	
 		context-		: Unix.McontextDesc;
 		state0	: ARRAY 2048 OF CHAR;		(* thread state at body start, used for restart after trap *)
 					
@@ -202,24 +201,19 @@ TYPE
 			IF mode # Terminated THEN
 				
 				IF SELF = CurrentProcess() THEN
-					context.r_sp := Machine.CurrentSP( );
-					context.r_bp := Machine.CurrentBP( );
+					state.SP := Machine.CurrentSP( );
+					state.BP := Machine.CurrentBP( );
 				END;
-				sp := context.r_sp; bp := context.r_bp; 
+				sp := state.SP; bp := state.BP; 
 			
 				IF Heaps.GCType = Heaps.HeuristicStackInspectionGC THEN	
-					Heaps.Candidate( context.r_di );  Heaps.Candidate( context.r_si );
-					Heaps.Candidate( context.r_bx ); Heaps.Candidate( context.r_dx );
-					Heaps.Candidate( context.r_cx ); Heaps.Candidate( context.r_ax);
 					IF (stackBottom # 0) & (sp # 0) & (sp <= stackBottom) THEN
 						Heaps.RegisterCandidates( sp, stackBottom - sp );
 					END;
 				ELSIF Heaps.GCType = Heaps.MetaDataForStackGC THEN
 					IF bp < stackBottom THEN
 						WHILE (bp # Heaps.NilVal) & (bp > 1024) & (bp < stackBottom) DO (* do not test for bp >= sp: could be wrong temporarily! *)
-							TRACE( bp );
 							S.GET( bp, n );
-							TRACE( n );
 							IF ODD( n ) THEN (* procedure descriptor at bp *)
 								IF n > 1024 THEN
 									desc := S.VAL( Modules.ProcedureDescPointer, n-1 );
@@ -240,7 +234,6 @@ TYPE
 							ELSE (* classical stack frame *)
 								bp := n; 
 							END;
-							TRACE( bp );
 						END;
 						ASSERT( (bp = stackBottom) OR (bp < 1024) , 12345 );
 					END; 
@@ -282,13 +275,6 @@ TYPE
 			priority := GetPriority( )	
 		END SetPriority;
 		
-		PROCEDURE UpdateState;
-		BEGIN
-			state.PC := context.r_pc;
-			state.BP := context.r_bp;
-			state.SP := context.r_sp
-		END UpdateState;
-				
 				
 		PROCEDURE & Initialize( obj: ProtectedObject;  bodyProc: Body;  prio: LONGINT; fl: SET; stacksize: LONGINT);
 		BEGIN
@@ -330,10 +316,9 @@ TYPE
 			IF value THEN
 				Machine.Acquire( Machine.Objects );	
 				Machine.Acquire( Machine.Heaps );
-				cur.context.r_sp := Machine.CurrentSP();
-				cur.context.r_bp := Machine.CurrentBP();
-				cur.context.r_pc := ADDRESSOF( GCLoop );
-				cur.UpdateState;
+				cur.state.SP := Machine.CurrentSP();
+				cur.state.BP := Machine.CurrentBP();
+				cur.state.PC := ADDRESSOF( GCLoop );
 					
 				SuspendActivities;
 				Heaps.CollectGarbage( Modules.root );
@@ -415,10 +400,9 @@ TYPE
 		ASSERT( exclusive );   (* shared not implemented yet *)
 		S.GET( S.VAL( ADDRESS, obj ) + Heaps.HeapBlockOffset, hdr );
 		p := CurrentProcess();
-		p.context.r_sp := Machine.CurrentSP( );
-		p.context.r_bp := Machine.CurrentBP( );
-		p.context.r_pc := Machine.CurrentPC( );
-		p.UpdateState;
+		p.state.SP := Machine.CurrentSP( );
+		p.state.BP := Machine.CurrentBP( );
+		p.state.PC := Machine.CurrentPC( );
 		p.mode := AwaitingLock;
 
 		(*! we might want to replace the lock mutex by a lock free construct *)
@@ -450,10 +434,9 @@ TYPE
 		hdr.lockedBy := c;
 		IF c # NIL THEN  Unix.CondSignal( c.continue )  ELSE  Unix.CondSignal( lock.enter )  END;
 
-		p.context.r_sp := Machine.CurrentSP( );
-		p.context.r_bp := Machine.CurrentBP( );
-		p.context.r_pc := Machine.CurrentPC( );
-		p.UpdateState;
+		p.state.SP := Machine.CurrentSP( );
+		p.state.BP := Machine.CurrentBP( );
+		p.state.PC := Machine.CurrentPC( );
 		Unix.CondWait( p.continue, lock.mtx );   
 		
 		p.mode := Running;  hdr.lockedBy := p;  p.waitingOn := NIL
@@ -742,23 +725,30 @@ TYPE
 	BEGIN
 		(*	use CurrentProcess0 here instead of CurrentProcess in order to
 			avoid a possible deadlock *)
-		t := CurrentProcess0();
+		t := CurrentProcess0( );
 		Unix.CopyContext( ctxt.mc, t.context );
-		t.UpdateState
+		t.state.PC := t.context.r_pc;
+		t.state.BP := t.context.r_bp;
+		t.state.SP := t.context.r_sp
 	END GetContext;
 	
 	(* called by WMProcessInfo to obtain the current state of a running process *)
 	PROCEDURE UpdateProcessState*( p: Process );	
 	BEGIN 
-		(*  update p.stat.{PC,BP,SP}  *)
-		IF p.threadId # Unix.ThrThis() THEN
-			timerStopped := TRUE;
-			Unix.ThrSleep( 2 );
-			IF p.mode = Running THEN	(* still  running *)
-				Unix.ThrSuspend( p.threadId, TRUE );
-				Unix.ThrResume( p.threadId );
-			END;
-			timerStopped := FALSE
+		IF p.threadId = Unix.ThrThis( ) THEN
+			p.state.PC := Machine.CurrentPC( );
+			p.state.BP := Machine.CurrentBP( );
+			p.state.SP := Machine.CurrentSP( )	
+		ELSE
+			IF p.mode = Running THEN
+				timerStopped := TRUE;
+				Unix.ThrSleep( 3 );
+				IF p.mode = Running THEN	(* still running *)
+					Unix.ThrSuspend( p.threadId, TRUE );
+					Unix.ThrResume( p.threadId );
+				END;
+				timerStopped := FALSE
+			END			
 		END	
 	END UpdateProcessState;
 	
@@ -821,7 +811,7 @@ TYPE
 			bp := Machine.CurrentBP();
 			S.GET( bp, n );
 			IF ODD( n ) THEN S.GET( bp + SIZEOF( ADDRESS ), bp )  ELSE  bp := n  END;
-			cur.context.r_bp := bp;
+			cur.state.BP := bp;
 		END;
 	END LeaveA2;
 
@@ -831,7 +821,7 @@ TYPE
 		IF clock = NIL THEN  RETURN  END;
 		cur := CurrentProcess();
 		IF cur # NIL THEN 
-			cur.context.r_bp := 0;
+			cur.state.BP := 0;
 		END;	
 	END ReenterA2;
 	

+ 42 - 11
source/WMProcessInfo.Mod

@@ -211,7 +211,9 @@ TYPE
 			mod : Modules.Module;
 			str : ARRAY 256 OF CHAR;
 			t0, t1 : HUGEINT;
-			pc : ADDRESS;
+			
+			pc, relpc : ADDRESS;
+			mode: LONGINT;
 
 			PROCEDURE SetText(line, cell : LONGINT; CONST str : ARRAY OF CHAR);
 			VAR s : Strings.String;
@@ -222,7 +224,25 @@ TYPE
 				grid.model.SetTextAlign(cell, line + 1, GetAlign(cell));
 				grid.model.SetCellText(cell, line + 1, s)
 			END SetText;
-
+			
+			PROCEDURE GetValues( p: Objects.Process );
+			VAR bp: ADDRESS; 
+			BEGIN
+				Objects.UpdateProcessState( p );	
+				mode := p.mode;
+				pc := p.state.PC;
+				bp := p.state.BP;
+				mod := Modules.ThisModuleByAdr( pc );
+				WHILE (mod = NIL) & (bp # 0) DO
+					bp := CheckBP( p, bp );
+					IF bp # 0 THEN
+						SYSTEM.GET( bp + SIZEOF(ADDRESS), pc );	(* return addr from stack *)
+						mod := Modules.ThisModuleByAdr( pc );
+						SYSTEM.GET( bp, bp );	(* follow dynamic link *)
+					END
+				END
+			END GetValues;
+			
 		BEGIN
 			t1 := Machine.GetTimer() - lastProcTime;
 			lastProcTime := Machine.GetTimer();
@@ -231,8 +251,9 @@ TYPE
 			grid.model.SetNofRows(nofProcesses + 1);
 
 			FOR i := 0 TO nofProcesses - 1 DO
-				ASSERT(processes[i] # NIL);
-
+				ASSERT(processes[i] # NIL);				
+				GetValues( processes[i] );
+				
 				(* PID Process ID - 0 *)
 				Strings.IntToStr(processes[i].id, str); SetText(i, 0, str);
 
@@ -249,26 +270,24 @@ TYPE
 				Strings.IntToStr(processes[i].priority, str); SetText(i, 3, str);
 
 				(* mode - 4 *)
-				sw.Reset; ProcessInfo.WriteMode(processes[i].mode, sw); sw.Get(str); SetText(i, 4, str);
+				sw.Reset; ProcessInfo.WriteMode( mode, sw ); sw.Get(str); SetText(i, 4, str);
 
 				(* PC - 5 *)
-				IF (mod # NIL) & (mod.code # NIL) THEN DEC(pc, ADDRESSOF(mod.code[0])) END;
-				Strings.IntToStr(SYSTEM.VAL (LONGINT, pc), str); SetText(i, 5, str);
+				relpc := pc;
+				IF (mod # NIL) & (mod.code # NIL) THEN DEC(relpc, ADDRESSOF(mod.code[0])) END;
+				Strings.IntToStr(SYSTEM.VAL (LONGINT, relpc), str); SetText(i, 5, str);
 
 				(* active object type - 6 *)
 				sw.Reset; ProcessInfo.WriteActiveObject(processes[i], sw); sw.Get(str);
 				SetText(i, 6, str);
 
 				(* Module - 7 *)
-				pc := processes[i].state.PC;
-				mod := Modules.ThisModuleByAdr(pc);
 				IF mod # NIL THEN SetText(i, 7, mod.name)
 				ELSE  str := "Unknown"; SetText(i, 7, str);
 				END;
 
 				(* Procedure - 8 - Module name (prefix) and "pc=xyz" (suffix) suppressed *)
-				sw.Reset; Reflection.WriteProc(sw, processes[i].state.PC);
-				sw.Get(str);
+				sw.Reset;  Reflection.WriteProc( sw, pc );  sw.Get(str);
 				IF (str # "NIL") & (mod#NIL) THEN
 					posP := 0;
 					REPEAT INC(posP) UNTIL  (posP=LEN(str)) OR (str[posP]=0X)  OR (str[posP] = ".");	(* Skip prefix *)
@@ -555,6 +574,18 @@ BEGIN
 	END
 END GetAlign;
 
+PROCEDURE CheckBP( p: Objects.Process; bp: ADDRESS ): ADDRESS;
+VAR n: ADDRESS;
+BEGIN
+	IF (bp < p.stackBottom) & (bp > p.stackBottom - 256*1024) THEN
+		SYSTEM.GET(bp, n);
+		IF ODD(n) THEN INC(bp, SIZEOF(ADDRESS)) END;
+		RETURN bp
+	ELSE
+		RETURN 0
+	END;
+END CheckBP;
+
 PROCEDURE OpenCpuLoadWindow(pid : LONGINT);
 VAR commandString, msg : ARRAY 128 OF CHAR; nbr : ARRAY 16 OF CHAR; res : LONGINT;
 BEGIN