1 /*	Public domain	*/
2 /*
3  * Time backend for the traditional gettimeofday() interface.
4  * Delay() is implemented using the "timeout" argument of select().
5  */
6 
7 #include <sys/types.h>
8 #include <sys/time.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <errno.h>
12 
13 #include <agar/core/core.h>
14 
15 static struct timeval t0;
16 
17 static void
GTOD_Init(void)18 GTOD_Init(void)
19 {
20 	gettimeofday(&t0, NULL);
21 }
22 
23 static Uint32
GTOD_GetTicks(void)24 GTOD_GetTicks(void)
25 {
26 	struct timeval t;
27 
28 	gettimeofday(&t, NULL);
29 	return (Uint32)(t.tv_sec - t0.tv_sec)*1000 +
30 	               (t.tv_usec - t0.tv_usec)/1000;
31 }
32 
33 static void
GTOD_Delay(Uint32 ticks)34 GTOD_Delay(Uint32 ticks)
35 {
36 	Uint32 t1, t, Telapsed, Tdelay = ticks;
37 	struct timeval tv;
38 	int rv;
39 
40 	t1 = GTOD_GetTicks();
41 	for (;;) {
42 		t = GTOD_GetTicks();
43 		Telapsed = (t - t1);
44 		t1 = t;
45 		if (Telapsed >= Tdelay) {
46 			break;
47 		}
48 		Tdelay -= Telapsed;
49 		tv.tv_sec = Tdelay/1000;
50 		tv.tv_usec = (Tdelay % 1000)*1000;
51 		if ((rv = select(0, NULL, NULL, NULL, &tv)) == -1 &&
52 		    errno == EINTR) {
53 			continue;
54 		}
55 		break;
56 	}
57 }
58 
59 const AG_TimeOps agTimeOps_gettimeofday = {
60 	"gettimeofday",
61 	GTOD_Init,
62 	NULL,
63 	GTOD_GetTicks,
64 	GTOD_Delay
65 };
66