blob: 24ceef00323cca25632c060151dcee008acec190 [file] [log] [blame]
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00009******************************************************************/
10
11#include <stdlib.h>
12#include <stdio.h>
13#include <unistd.h>
Guido van Rossumcf1474b1996-10-08 14:17:53 +000014#include <errno.h>
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000015#include </usr/include/thread.h>
Guido van Rossum6eea3261996-08-26 14:58:54 +000016#undef _POSIX_THREADS
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000017
18
19/*
20 * Initialization.
21 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000022static void PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000023{
24}
25
26/*
27 * Thread support.
28 */
29struct func_arg {
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000030 void (*func)(void *);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000031 void *arg;
32};
33
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000034static void *
35new_func(void *funcarg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000036{
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000037 void (*func)(void *);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000038 void *arg;
39
40 func = ((struct func_arg *) funcarg)->func;
41 arg = ((struct func_arg *) funcarg)->arg;
42 free(funcarg);
43 (*func)(arg);
44 return 0;
45}
46
47
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000048int
49PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000050{
51 struct func_arg *funcarg;
52 int success = 0; /* init not needed when SOLARIS_THREADS and */
53 /* C_THREADS implemented properly */
54
Guido van Rossum65d5b571998-12-21 19:32:43 +000055 dprintf(("PyThread_start_new_thread called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000056 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +000057 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000058 funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
59 funcarg->func = func;
60 funcarg->arg = arg;
Guido van Rossum495894e1999-04-13 14:32:12 +000061 if (thr_create(0, 0, new_func, funcarg,
62 THR_DETACHED | THR_NEW_LWP, 0)) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000063 perror("thr_create");
64 free((void *) funcarg);
65 success = -1;
66 }
67 return success < 0 ? 0 : 1;
68}
69
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000070long
71PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +000072{
73 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +000074 PyThread_init_thread();
Guido van Rossume944da81994-05-23 12:43:41 +000075 return thr_self();
76}
77
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000078static void
79do_PyThread_exit_thread(int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000080{
Guido van Rossum65d5b571998-12-21 19:32:43 +000081 dprintf(("PyThread_exit_thread called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000082 if (!initialized)
83 if (no_cleanup)
84 _exit(0);
85 else
86 exit(0);
87 thr_exit(0);
88}
89
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000090void
91PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000092{
Guido van Rossum65d5b571998-12-21 19:32:43 +000093 do_PyThread_exit_thread(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000094}
95
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000096void
97PyThread__exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000098{
Guido van Rossum65d5b571998-12-21 19:32:43 +000099 do_PyThread_exit_thread(1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000100}
101
102#ifndef NO_EXIT_PROG
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000103static void
104do_PyThread_exit_prog(int status, int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000105{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000106 dprintf(("PyThread_exit_prog(%d) called\n", status));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000107 if (!initialized)
108 if (no_cleanup)
109 _exit(status);
110 else
111 exit(status);
112 if (no_cleanup)
113 _exit(status);
114 else
115 exit(status);
116}
117
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000118void
119PyThread_exit_prog(int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000120{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000121 do_PyThread_exit_prog(status, 0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000122}
123
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000124void
125PyThread__exit_prog(int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000126{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000127 do_PyThread_exit_prog(status, 1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000128}
129#endif /* NO_EXIT_PROG */
130
131/*
132 * Lock support.
133 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000134PyThread_type_lock
135PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000136{
137 mutex_t *lock;
138
Guido van Rossum65d5b571998-12-21 19:32:43 +0000139 dprintf(("PyThread_allocate_lock called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000140 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000141 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000142
143 lock = (mutex_t *) malloc(sizeof(mutex_t));
144 if (mutex_init(lock, USYNC_THREAD, 0)) {
145 perror("mutex_init");
146 free((void *) lock);
147 lock = 0;
148 }
Fred Drakea44d3532000-06-30 15:01:00 +0000149 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
Guido van Rossum65d5b571998-12-21 19:32:43 +0000150 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000151}
152
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000153void
154PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000155{
Fred Drakea44d3532000-06-30 15:01:00 +0000156 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000157 mutex_destroy((mutex_t *) lock);
158 free((void *) lock);
159}
160
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000161int
162PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000163{
164 int success;
165
Fred Drakea44d3532000-06-30 15:01:00 +0000166 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000167 if (waitflag)
168 success = mutex_lock((mutex_t *) lock);
169 else
170 success = mutex_trylock((mutex_t *) lock);
171 if (success < 0)
172 perror(waitflag ? "mutex_lock" : "mutex_trylock");
173 else
174 success = !success; /* solaris does it the other way round */
Fred Drakea44d3532000-06-30 15:01:00 +0000175 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000176 return success;
177}
178
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000179void
180PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000181{
Fred Drakea44d3532000-06-30 15:01:00 +0000182 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000183 if (mutex_unlock((mutex_t *) lock))
184 perror("mutex_unlock");
185}
186
187/*
188 * Semaphore support.
189 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000190PyThread_type_sema
191PyThread_allocate_sema(int value)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000192{
193 sema_t *sema;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000194 dprintf(("PyThread_allocate_sema called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000195 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000196 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000197
198 sema = (sema_t *) malloc(sizeof(sema_t));
199 if (sema_init(sema, value, USYNC_THREAD, 0)) {
200 perror("sema_init");
201 free((void *) sema);
202 sema = 0;
203 }
Fred Drakea44d3532000-06-30 15:01:00 +0000204 dprintf(("PyThread_allocate_sema() -> %p\n", sema));
Guido van Rossum65d5b571998-12-21 19:32:43 +0000205 return (PyThread_type_sema) sema;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000206}
207
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000208void
209PyThread_free_sema(PyThread_type_sema sema)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000210{
Fred Drakea44d3532000-06-30 15:01:00 +0000211 dprintf(("PyThread_free_sema(%p) called\n", sema));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000212 if (sema_destroy((sema_t *) sema))
213 perror("sema_destroy");
214 free((void *) sema);
215}
216
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000217int
218PyThread_down_sema(PyThread_type_sema sema, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000219{
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000220 int success;
221
Fred Drakea44d3532000-06-30 15:01:00 +0000222 dprintf(("PyThread_down_sema(%p) called\n", sema));
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000223 if (waitflag)
224 success = sema_wait((sema_t *) sema);
225 else
226 success = sema_trywait((sema_t *) sema);
227 if (success < 0) {
228 if (errno == EBUSY)
229 success = 0;
230 else
231 perror("sema_wait");
232 }
233 else
234 success = !success;
Fred Drakea44d3532000-06-30 15:01:00 +0000235 dprintf(("PyThread_down_sema(%p) return %d\n", sema, success));
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000236 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000237}
238
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000239void
240PyThread_up_sema(PyThread_type_sema sema)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000241{
Fred Drakea44d3532000-06-30 15:01:00 +0000242 dprintf(("PyThread_up_sema(%p)\n", sema));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000243 if (sema_post((sema_t *) sema))
244 perror("sema_post");
245}