blob: 66bdfa25a3445438032ee7a71d1444db68672319 [file] [log] [blame]
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00001
2#include <stdlib.h>
3#include <stdio.h>
4#include <unistd.h>
Guido van Rossumcf1474b1996-10-08 14:17:53 +00005#include <errno.h>
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00006#include </usr/include/thread.h>
Guido van Rossum6eea3261996-08-26 14:58:54 +00007#undef _POSIX_THREADS
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00008
9
10/*
11 * Initialization.
12 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000013static void PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000014{
15}
16
17/*
18 * Thread support.
19 */
20struct func_arg {
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000021 void (*func)(void *);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000022 void *arg;
23};
24
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000025static void *
26new_func(void *funcarg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000027{
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000028 void (*func)(void *);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000029 void *arg;
30
31 func = ((struct func_arg *) funcarg)->func;
32 arg = ((struct func_arg *) funcarg)->arg;
33 free(funcarg);
34 (*func)(arg);
35 return 0;
36}
37
38
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000039int
40PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000041{
42 struct func_arg *funcarg;
43 int success = 0; /* init not needed when SOLARIS_THREADS and */
44 /* C_THREADS implemented properly */
45
Guido van Rossum65d5b571998-12-21 19:32:43 +000046 dprintf(("PyThread_start_new_thread called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000047 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +000048 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000049 funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
50 funcarg->func = func;
51 funcarg->arg = arg;
Guido van Rossum495894e1999-04-13 14:32:12 +000052 if (thr_create(0, 0, new_func, funcarg,
53 THR_DETACHED | THR_NEW_LWP, 0)) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000054 perror("thr_create");
55 free((void *) funcarg);
56 success = -1;
57 }
58 return success < 0 ? 0 : 1;
59}
60
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000061long
62PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +000063{
64 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +000065 PyThread_init_thread();
Guido van Rossume944da81994-05-23 12:43:41 +000066 return thr_self();
67}
68
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000069static void
70do_PyThread_exit_thread(int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000071{
Guido van Rossum65d5b571998-12-21 19:32:43 +000072 dprintf(("PyThread_exit_thread called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000073 if (!initialized)
74 if (no_cleanup)
75 _exit(0);
76 else
77 exit(0);
78 thr_exit(0);
79}
80
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000081void
82PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000083{
Guido van Rossum65d5b571998-12-21 19:32:43 +000084 do_PyThread_exit_thread(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000085}
86
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000087void
88PyThread__exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000089{
Guido van Rossum65d5b571998-12-21 19:32:43 +000090 do_PyThread_exit_thread(1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000091}
92
93#ifndef NO_EXIT_PROG
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000094static void
95do_PyThread_exit_prog(int status, int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000096{
Guido van Rossum65d5b571998-12-21 19:32:43 +000097 dprintf(("PyThread_exit_prog(%d) called\n", status));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000098 if (!initialized)
99 if (no_cleanup)
100 _exit(status);
101 else
102 exit(status);
103 if (no_cleanup)
104 _exit(status);
105 else
106 exit(status);
107}
108
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000109void
110PyThread_exit_prog(int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000111{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000112 do_PyThread_exit_prog(status, 0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000113}
114
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000115void
116PyThread__exit_prog(int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000117{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000118 do_PyThread_exit_prog(status, 1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000119}
120#endif /* NO_EXIT_PROG */
121
122/*
123 * Lock support.
124 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000125PyThread_type_lock
126PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000127{
128 mutex_t *lock;
129
Guido van Rossum65d5b571998-12-21 19:32:43 +0000130 dprintf(("PyThread_allocate_lock called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000131 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000132 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000133
134 lock = (mutex_t *) malloc(sizeof(mutex_t));
135 if (mutex_init(lock, USYNC_THREAD, 0)) {
136 perror("mutex_init");
137 free((void *) lock);
138 lock = 0;
139 }
Fred Drakea44d3532000-06-30 15:01:00 +0000140 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
Guido van Rossum65d5b571998-12-21 19:32:43 +0000141 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000142}
143
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000144void
145PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000146{
Fred Drakea44d3532000-06-30 15:01:00 +0000147 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000148 mutex_destroy((mutex_t *) lock);
149 free((void *) lock);
150}
151
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000152int
153PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000154{
155 int success;
156
Fred Drakea44d3532000-06-30 15:01:00 +0000157 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000158 if (waitflag)
159 success = mutex_lock((mutex_t *) lock);
160 else
161 success = mutex_trylock((mutex_t *) lock);
162 if (success < 0)
163 perror(waitflag ? "mutex_lock" : "mutex_trylock");
164 else
165 success = !success; /* solaris does it the other way round */
Fred Drakea44d3532000-06-30 15:01:00 +0000166 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000167 return success;
168}
169
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000170void
171PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000172{
Fred Drakea44d3532000-06-30 15:01:00 +0000173 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000174 if (mutex_unlock((mutex_t *) lock))
175 perror("mutex_unlock");
176}
177
178/*
179 * Semaphore support.
180 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000181PyThread_type_sema
182PyThread_allocate_sema(int value)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000183{
184 sema_t *sema;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000185 dprintf(("PyThread_allocate_sema called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000186 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000187 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000188
189 sema = (sema_t *) malloc(sizeof(sema_t));
190 if (sema_init(sema, value, USYNC_THREAD, 0)) {
191 perror("sema_init");
192 free((void *) sema);
193 sema = 0;
194 }
Fred Drakea44d3532000-06-30 15:01:00 +0000195 dprintf(("PyThread_allocate_sema() -> %p\n", sema));
Guido van Rossum65d5b571998-12-21 19:32:43 +0000196 return (PyThread_type_sema) sema;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000197}
198
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000199void
200PyThread_free_sema(PyThread_type_sema sema)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000201{
Fred Drakea44d3532000-06-30 15:01:00 +0000202 dprintf(("PyThread_free_sema(%p) called\n", sema));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000203 if (sema_destroy((sema_t *) sema))
204 perror("sema_destroy");
205 free((void *) sema);
206}
207
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000208int
209PyThread_down_sema(PyThread_type_sema sema, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000210{
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000211 int success;
212
Fred Drakea44d3532000-06-30 15:01:00 +0000213 dprintf(("PyThread_down_sema(%p) called\n", sema));
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000214 if (waitflag)
215 success = sema_wait((sema_t *) sema);
216 else
217 success = sema_trywait((sema_t *) sema);
218 if (success < 0) {
219 if (errno == EBUSY)
220 success = 0;
221 else
222 perror("sema_wait");
223 }
224 else
225 success = !success;
Fred Drakea44d3532000-06-30 15:01:00 +0000226 dprintf(("PyThread_down_sema(%p) return %d\n", sema, success));
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000227 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000228}
229
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000230void
231PyThread_up_sema(PyThread_type_sema sema)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000232{
Fred Drakea44d3532000-06-30 15:01:00 +0000233 dprintf(("PyThread_up_sema(%p)\n", sema));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000234 if (sema_post((sema_t *) sema))
235 perror("sema_post");
236}