Ver código fonte

Added basic support for cooperative high precision timer

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@8161 8c9fc860-2736-0410-a75d-ab315db34111
negelef 7 anos atrás
pai
commit
d3ea0d3f6b
2 arquivos alterados com 39 adições e 1 exclusões
  1. 13 1
      source/Linux.AMD64.Unix.Mod
  2. 26 0
      source/Unix.Timer.Mod

+ 13 - 1
source/Linux.AMD64.Unix.Mod

@@ -132,6 +132,12 @@ CONST
 	SA_NODEFER		= 0x40000000;
 	SA_RESETHAND	= 0x80000000;
 
+	CLOCK_MONOTONIC* = 1;
+	CLOCK_MONOTONIC_RAW* = 4;
+	CLOCK_PROCESS_CPUTIME_ID* = 2;
+	CLOCK_REALTIME* = 0;
+	CLOCK_THREAD_CPUTIME_ID* = 3;
+
 	PTHREAD_CANCEL_ENABLE 	= 0;
 	PTHREAD_CANCEL_DISABLE	= 1;
 
@@ -312,6 +318,10 @@ TYPE
 				interval*, value*: Timeval
 			END;
 
+	Timespec* = RECORD
+		tv_sec*: LONGWORD;
+		tv_nsec*: LONGWORD;
+	END;
 
 CONST
 	FdSetLen* = 16;
@@ -501,7 +511,8 @@ VAR
 	alarm-		: PROCEDURE {C} ( ms: LONGINT ): LONGINT;
 	setitimer-		: PROCEDURE {C} ( which: LONGINT;  VAR value, ovalue: Itimerval ): LONGINT;
 	getitimer-		: PROCEDURE {C} ( which: LONGINT;  VAR value: Itimerval ): LONGINT;
-	clock_gettime-	: PROCEDURE{C}	(clk_id: LONGINT; tp: tvPtr): LONGINT;
+	clock_gettime-	: PROCEDURE {C} (clk_id: WORD; tp: ADDRESS): WORD;
+	clock_getres-	: PROCEDURE {C} (clk_id: WORD; res: ADDRESS): WORD;
 
 	gettimeofday-	: PROCEDURE {C} ( VAR tv: Timeval;  VAR tz: Timezone ): LONGINT;
 	mktime-			: PROCEDURE {C} ( VAR tm: Tm ): LONGINT;
@@ -1143,6 +1154,7 @@ VAR
 		Dlsym( libc, "setitimer",	ADDRESSOF( setitimer ) );
 		Dlsym( libc, "getitimer",	ADDRESSOF( getitimer ) );
 		Dlsym( libc, "clock_gettime", ADDRESSOF(clock_gettime) );
+		Dlsym( libc, "clock_getres", ADDRESSOF(clock_getres) );
 
 		Dlsym( libc, "gettimeofday", ADDRESSOF( gettimeofday ) );
 		Dlsym( libc, "mktime",		ADDRESSOF( mktime ) );

+ 26 - 0
source/Unix.Timer.Mod

@@ -0,0 +1,26 @@
+(* Runtime support for high precision timer *)
+(* Copyright (C) Florian Negele *)
+
+MODULE Timer;
+
+IMPORT Unix;
+
+CONST Clock = Unix.CLOCK_MONOTONIC;
+
+TYPE Counter* = LONGWORD;
+
+PROCEDURE GetCounter- (): Counter;
+VAR timespec: Unix.Timespec; result: Counter;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	ASSERT (Unix.clock_gettime (Clock, ADDRESS OF timespec) = 0);
+	result := timespec.tv_sec; result := result * 1000000; INC (result, timespec.tv_nsec DIV 1000); RETURN result;
+END GetCounter;
+
+PROCEDURE GetFrequency- (): Counter;
+VAR timespec: Unix.Timespec;
+BEGIN {UNCOOPERATIVE, UNCHECKED}
+	IF Unix.clock_getres (Clock, ADDRESS OF timespec) # 0 THEN RETURN 0 END;
+	ASSERT ((timespec.tv_sec = 0) & (timespec.tv_nsec = 1)); RETURN 1000000;
+END GetFrequency;
+
+END Timer.