summaryrefslogtreecommitdiff
path: root/uisimulator/sdl/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'uisimulator/sdl/thread.c')
-rw-r--r--uisimulator/sdl/thread.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/uisimulator/sdl/thread.c b/uisimulator/sdl/thread.c
new file mode 100644
index 0000000000..6d9139c35d
--- /dev/null
+++ b/uisimulator/sdl/thread.c
@@ -0,0 +1,148 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Daniel Stenberg
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "autoconf.h"
21
22#include <stdio.h>
23#include <pthread.h>
24
25#include "kernel.h"
26#include <sys/time.h>
27
28#ifdef ROCKBOX_HAS_SIMSOUND
29#include "sound.h"
30#endif
31
32long current_tick = 0;
33extern void sim_tick_tasks(void);
34
35static void msleep(int msec)
36{
37 struct timeval delay;
38
39 delay.tv_sec = msec / 1000;
40 delay.tv_usec = (msec % 1000) * 1000;
41 select(0, NULL, NULL, NULL, &delay); /* portable sub-second sleep */
42}
43
44/*
45 * This is not a target thread, so it does not fall under the 1 thread at a
46 * time thing.
47 */
48static void update_tick_thread()
49{
50 struct timeval start, now;
51 long new_tick;
52
53 gettimeofday(&start, NULL);
54 while (1)
55 {
56 msleep(5); /* check twice per simulated target tick */
57 gettimeofday(&now, NULL);
58 new_tick = (now.tv_sec - start.tv_sec) * HZ
59 + (now.tv_usec - start.tv_usec) / (1000000/HZ);
60 if (new_tick > current_tick)
61 {
62 sim_tick_tasks();
63 current_tick = new_tick;
64 }
65 }
66}
67
68/*
69 * We emulate the target threads by using pthreads. We have a mutex that only
70 * allows one thread at a time to execute. It forces each thread to yield()
71 * for the other(s) to run.
72 */
73
74pthread_mutex_t mp;
75
76void init_threads(void)
77{
78 pthread_t tick_tid;
79
80 pthread_mutex_init(&mp, NULL);
81 /* get mutex to only allow one thread running at a time */
82 pthread_mutex_lock(&mp);
83
84 /* start a tick thread */
85 pthread_create(&tick_tid, NULL, (void *(*)(void *)) update_tick_thread,
86 NULL);
87
88#ifdef ROCKBOX_HAS_SIMSOUND /* start thread that plays PCM data */
89 {
90 pthread_t sound_tid;
91 pthread_create(&sound_tid, NULL,
92 (void *(*)(void *)) sound_playback_thread,
93 NULL);
94 }
95#endif
96
97}
98/*
99 int pthread_create(pthread_t *new_thread_ID,
100 const pthread_attr_t *attr,
101 void * (*start_func)(void *), void *arg);
102*/
103
104void yield(void)
105{
106 pthread_mutex_unlock(&mp); /* return */
107 msleep(1); /* prevent busy loop */
108 pthread_mutex_lock(&mp); /* get it again */
109}
110
111void newfunc(void (*func)(void))
112{
113 pthread_mutex_lock(&mp);
114 func();
115 pthread_mutex_unlock(&mp);
116}
117
118
119int create_thread(void (*fp)(void), void* sp, int stk_size)
120{
121 pthread_t tid;
122 int i;
123 int error;
124
125 /* we really don't care about these arguments */
126 (void)sp;
127 (void)stk_size;
128 error = pthread_create(&tid,
129 NULL, /* default attributes please */
130 (void *(*)(void *)) newfunc, /* function to start */
131 fp /* start argument */);
132 if(0 != error)
133 fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
134 else
135 fprintf(stderr, "Thread %ld is running\n", (long)tid);
136
137 yield();
138
139 return error;
140}
141
142void sim_sleep(int ticks)
143{
144 pthread_mutex_unlock(&mp); /* return */
145 msleep((1000/HZ) * ticks);
146 pthread_mutex_lock(&mp); /* get it again */
147}
148