1 #include <process.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <time.h>
5
6 #include <windows.h>
7
8 #define POW10_3 1000
9 #define POW10_6 1000000
10
11 extern int __cdecl getntptimeofday(struct timespec *tp, struct timezone *tz);
12
timespec_diff_as_ms(struct timespec * __old,struct timespec * __new)13 __int64 timespec_diff_as_ms(struct timespec *__old, struct timespec *__new)
14 {
15 return (__new->tv_sec - __old->tv_sec) * POW10_3
16 + (__new->tv_nsec - __old->tv_nsec) / POW10_6;
17 }
18
start_address(void * dummy)19 unsigned __stdcall start_address(void *dummy)
20 {
21 int counter = 0;
22 struct timespec request = { 1, 0 }, remain;
23
24 while (counter < 5) {
25 int rc = nanosleep(&request, &remain);
26 if (rc != 0) {
27 printf("nanosleep interrupted, remain %d.%09d sec.\n",
28 (int) remain.tv_sec, (int) remain.tv_nsec);
29 } else {
30 printf("nanosleep succeeded.\n");
31 }
32
33 counter ++;
34 }
35
36 return 0;
37 }
38
usr_apc(ULONG_PTR dwParam)39 void WINAPI usr_apc(ULONG_PTR dwParam)
40 {
41 long *index = (long *) dwParam;
42 printf("running apc %ld\n", *index);
43 }
44
test_apc()45 void test_apc()
46 {
47 long i, rc, data[5];
48 HANDLE thread;
49
50 thread = (HANDLE) _beginthreadex(NULL, 0, start_address, NULL, 0, NULL);
51 if (thread == NULL) {
52 exit(1);
53 }
54
55 for (i = 0; i < 5; i++) {
56 data[i] = i;
57 Sleep(250 + rand() % 250);
58 rc = QueueUserAPC(usr_apc, thread, (ULONG_PTR) & data[i]);
59 if (rc == 0) {
60 printf("QueueUserAPC failed: %ld\n", GetLastError());
61 exit(1);
62 }
63 }
64
65 rc = WaitForSingleObject(thread, INFINITE);
66 if (rc != WAIT_OBJECT_0) {
67 printf("WaitForSingleObject failed with %ld: %ld\n", rc, GetLastError());
68 exit(1);
69 }
70 }
71
main(int argc,char * argv[])72 int main(int argc, char *argv[])
73 {
74 int rc;
75 struct timespec tp, tp2, request = { 1, 0 }, remain;
76
77 getntptimeofday(&tp, NULL);
78 rc = nanosleep(&request, &remain);
79 getntptimeofday(&tp2, NULL);
80
81 if (rc != 0) {
82 printf("remain: %d.%09d\n", (int) remain.tv_sec, (int) remain.tv_nsec);
83 }
84
85 printf("%d.%09d\n", (int) tp.tv_sec, (int) tp.tv_nsec);
86 printf("%d.%09d\n", (int) tp2.tv_sec, (int) tp2.tv_nsec);
87 printf("sleep %d ms\n\n", (int) timespec_diff_as_ms(&tp, &tp2));
88
89 test_apc();
90
91 return 0;
92 }
93