diff options
-rw-r--r-- | uisimulator/x11/thread.c | 89 |
1 files changed, 56 insertions, 33 deletions
diff --git a/uisimulator/x11/thread.c b/uisimulator/x11/thread.c index 25adf6a3c0..6f109a3425 100644 --- a/uisimulator/x11/thread.c +++ b/uisimulator/x11/thread.c | |||
@@ -21,11 +21,31 @@ | |||
21 | #include <pthread.h> | 21 | #include <pthread.h> |
22 | 22 | ||
23 | #include "kernel.h" | 23 | #include "kernel.h" |
24 | #include <poll.h> | 24 | #include <sys/time.h> |
25 | 25 | ||
26 | long current_tick = 0; | 26 | long current_tick = 0; |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * This is not a target thread, so it does not fall under the 1 thread at a | ||
30 | * time thing. | ||
31 | */ | ||
32 | static void update_tick_thread() | ||
33 | { | ||
34 | struct timeval start, now, delay; | ||
35 | |||
36 | gettimeofday(&start, NULL); | ||
37 | while (1) | ||
38 | { | ||
39 | delay.tv_sec = 0; | ||
40 | delay.tv_usec = (1000000/HZ/4); /* check 4 times per target tick */ | ||
41 | select(0, NULL, NULL, NULL, &delay); /* portable sub-second sleep */ | ||
42 | gettimeofday(&now, NULL); | ||
43 | current_tick = (now.tv_sec - start.tv_sec) * HZ | ||
44 | + (now.tv_usec - start.tv_usec) * HZ / 1000000; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | /* | ||
29 | * We emulate the target threads by using pthreads. We have a mutex that only | 49 | * We emulate the target threads by using pthreads. We have a mutex that only |
30 | * allows one thread at a time to execute. It forces each thread to yield() | 50 | * allows one thread at a time to execute. It forces each thread to yield() |
31 | * for the other(s) to run. | 51 | * for the other(s) to run. |
@@ -35,11 +55,14 @@ pthread_mutex_t mp; | |||
35 | 55 | ||
36 | void init_threads(void) | 56 | void init_threads(void) |
37 | { | 57 | { |
38 | pthread_mutex_init(&mp, NULL); | 58 | pthread_t tick_tid; |
39 | /* get mutex to only allow one thread running at a time */ | 59 | |
40 | pthread_mutex_lock(&mp); | 60 | pthread_mutex_init(&mp, NULL); |
61 | /* get mutex to only allow one thread running at a time */ | ||
62 | pthread_mutex_lock(&mp); | ||
41 | 63 | ||
42 | current_tick = time(NULL); /* give it a boost from start! */ | 64 | pthread_create(&tick_tid, NULL, (void *(*)(void *)) update_tick_thread, |
65 | NULL); | ||
43 | } | 66 | } |
44 | /* | 67 | /* |
45 | int pthread_create(pthread_t *new_thread_ID, | 68 | int pthread_create(pthread_t *new_thread_ID, |
@@ -49,49 +72,49 @@ void init_threads(void) | |||
49 | 72 | ||
50 | void yield(void) | 73 | void yield(void) |
51 | { | 74 | { |
52 | current_tick+=3; | 75 | pthread_mutex_unlock(&mp); /* return */ |
53 | pthread_mutex_unlock(&mp); /* return */ | 76 | pthread_mutex_lock(&mp); /* get it again */ |
54 | pthread_mutex_lock(&mp); /* get it again */ | ||
55 | } | 77 | } |
56 | 78 | ||
57 | void newfunc(void (*func)(void)) | 79 | void newfunc(void (*func)(void)) |
58 | { | 80 | { |
59 | yield(); | 81 | pthread_mutex_lock(&mp); |
60 | func(); | 82 | func(); |
83 | pthread_mutex_unlock(&mp); | ||
61 | } | 84 | } |
62 | 85 | ||
63 | 86 | ||
64 | int create_thread(void* fp, void* sp, int stk_size) | 87 | int create_thread(void* fp, void* sp, int stk_size) |
65 | { | 88 | { |
66 | pthread_t tid; | 89 | pthread_t tid; |
67 | int i; | 90 | int i; |
68 | int error; | 91 | int error; |
69 | 92 | ||
70 | /* we really don't care about these arguments */ | 93 | /* we really don't care about these arguments */ |
71 | (void)sp; | 94 | (void)sp; |
72 | (void)stk_size; | 95 | (void)stk_size; |
73 | error = pthread_create(&tid, | 96 | error = pthread_create(&tid, |
74 | NULL, /* default attributes please */ | 97 | NULL, /* default attributes please */ |
75 | (void *(*)(void *)) newfunc, /* function to start */ | 98 | (void *(*)(void *)) newfunc, /* function to start */ |
76 | fp /* start argument */); | 99 | fp /* start argument */); |
77 | if(0 != error) | 100 | if(0 != error) |
78 | fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error); | 101 | fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error); |
79 | else | 102 | else |
80 | fprintf(stderr, "Thread %ld is running\n", (long)tid); | 103 | fprintf(stderr, "Thread %ld is running\n", (long)tid); |
81 | 104 | ||
82 | yield(); | 105 | yield(); |
83 | 106 | ||
84 | return error; | 107 | return error; |
85 | } | 108 | } |
86 | 109 | ||
87 | /* ticks is HZ per second */ | ||
88 | void sim_sleep(int ticks) | 110 | void sim_sleep(int ticks) |
89 | { | 111 | { |
90 | current_tick+=5; | 112 | struct timeval delay; |
91 | pthread_mutex_unlock(&mp); /* return */ | ||
92 | /* portable subsecond "sleep" */ | ||
93 | poll((void *)0, 0, ticks * 1000/HZ); | ||
94 | 113 | ||
114 | pthread_mutex_unlock(&mp); /* return */ | ||
115 | delay.tv_sec = ticks / HZ; | ||
116 | delay.tv_usec = (ticks - HZ * delay.tv_sec) * (1000000/HZ); | ||
117 | select(0, NULL, NULL, NULL, &delay); /* portable subsecond sleep */ | ||
95 | pthread_mutex_lock(&mp); /* get it again */ | 118 | pthread_mutex_lock(&mp); /* get it again */ |
96 | } | 119 | } |
97 | 120 | ||