summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--uisimulator/x11/thread.c89
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
26long current_tick = 0; 26long 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 */
32static 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
36void init_threads(void) 56void 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
50void yield(void) 73void 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
57void newfunc(void (*func)(void)) 79void 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
64int create_thread(void* fp, void* sp, int stk_size) 87int 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 */
88void sim_sleep(int ticks) 110void 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