blob: 15e286aebe7acc67311f10771c1da33281a6a6d3 [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 */
Guido van Rossum65d5b571998-12-21 19:32:43 +000022static void PyThread__init_thread _P0()
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000023{
24}
25
26/*
27 * Thread support.
28 */
29struct func_arg {
30 void (*func) _P((void *));
31 void *arg;
32};
33
34static void *new_func _P1(funcarg, void *funcarg)
35{
36 void (*func) _P((void *));
37 void *arg;
38
39 func = ((struct func_arg *) funcarg)->func;
40 arg = ((struct func_arg *) funcarg)->arg;
41 free(funcarg);
42 (*func)(arg);
43 return 0;
44}
45
46
Guido van Rossum65d5b571998-12-21 19:32:43 +000047int PyThread_start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000048{
49 struct func_arg *funcarg;
50 int success = 0; /* init not needed when SOLARIS_THREADS and */
51 /* C_THREADS implemented properly */
52
Guido van Rossum65d5b571998-12-21 19:32:43 +000053 dprintf(("PyThread_start_new_thread called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000054 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +000055 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000056 funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
57 funcarg->func = func;
58 funcarg->arg = arg;
Guido van Rossum495894e1999-04-13 14:32:12 +000059 if (thr_create(0, 0, new_func, funcarg,
60 THR_DETACHED | THR_NEW_LWP, 0)) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000061 perror("thr_create");
62 free((void *) funcarg);
63 success = -1;
64 }
65 return success < 0 ? 0 : 1;
66}
67
Guido van Rossum65d5b571998-12-21 19:32:43 +000068long PyThread_get_thread_ident _P0()
Guido van Rossume944da81994-05-23 12:43:41 +000069{
70 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +000071 PyThread_init_thread();
Guido van Rossume944da81994-05-23 12:43:41 +000072 return thr_self();
73}
74
Guido van Rossum65d5b571998-12-21 19:32:43 +000075static void do_PyThread_exit_thread _P1(no_cleanup, int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000076{
Guido van Rossum65d5b571998-12-21 19:32:43 +000077 dprintf(("PyThread_exit_thread called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000078 if (!initialized)
79 if (no_cleanup)
80 _exit(0);
81 else
82 exit(0);
83 thr_exit(0);
84}
85
Guido van Rossum65d5b571998-12-21 19:32:43 +000086void PyThread_exit_thread _P0()
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000087{
Guido van Rossum65d5b571998-12-21 19:32:43 +000088 do_PyThread_exit_thread(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000089}
90
Guido van Rossum65d5b571998-12-21 19:32:43 +000091void PyThread__exit_thread _P0()
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000092{
Guido van Rossum65d5b571998-12-21 19:32:43 +000093 do_PyThread_exit_thread(1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000094}
95
96#ifndef NO_EXIT_PROG
Guido van Rossum65d5b571998-12-21 19:32:43 +000097static void do_PyThread_exit_prog _P2(status, int status, no_cleanup, int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000098{
Guido van Rossum65d5b571998-12-21 19:32:43 +000099 dprintf(("PyThread_exit_prog(%d) called\n", status));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000100 if (!initialized)
101 if (no_cleanup)
102 _exit(status);
103 else
104 exit(status);
105 if (no_cleanup)
106 _exit(status);
107 else
108 exit(status);
109}
110
Guido van Rossum65d5b571998-12-21 19:32:43 +0000111void PyThread_exit_prog _P1(status, int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000112{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000113 do_PyThread_exit_prog(status, 0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000114}
115
Guido van Rossum65d5b571998-12-21 19:32:43 +0000116void PyThread__exit_prog _P1(status, 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 */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000125PyThread_type_lock PyThread_allocate_lock _P0()
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000126{
127 mutex_t *lock;
128
Guido van Rossum65d5b571998-12-21 19:32:43 +0000129 dprintf(("PyThread_allocate_lock called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000130 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000131 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000132
133 lock = (mutex_t *) malloc(sizeof(mutex_t));
134 if (mutex_init(lock, USYNC_THREAD, 0)) {
135 perror("mutex_init");
136 free((void *) lock);
137 lock = 0;
138 }
Fred Drakea44d3532000-06-30 15:01:00 +0000139 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
Guido van Rossum65d5b571998-12-21 19:32:43 +0000140 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000141}
142
Guido van Rossum65d5b571998-12-21 19:32:43 +0000143void PyThread_free_lock _P1(lock, PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000144{
Fred Drakea44d3532000-06-30 15:01:00 +0000145 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000146 mutex_destroy((mutex_t *) lock);
147 free((void *) lock);
148}
149
Guido van Rossum65d5b571998-12-21 19:32:43 +0000150int PyThread_acquire_lock _P2(lock, PyThread_type_lock lock, waitflag, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000151{
152 int success;
153
Fred Drakea44d3532000-06-30 15:01:00 +0000154 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000155 if (waitflag)
156 success = mutex_lock((mutex_t *) lock);
157 else
158 success = mutex_trylock((mutex_t *) lock);
159 if (success < 0)
160 perror(waitflag ? "mutex_lock" : "mutex_trylock");
161 else
162 success = !success; /* solaris does it the other way round */
Fred Drakea44d3532000-06-30 15:01:00 +0000163 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000164 return success;
165}
166
Guido van Rossum65d5b571998-12-21 19:32:43 +0000167void PyThread_release_lock _P1(lock, PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000168{
Fred Drakea44d3532000-06-30 15:01:00 +0000169 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000170 if (mutex_unlock((mutex_t *) lock))
171 perror("mutex_unlock");
172}
173
174/*
175 * Semaphore support.
176 */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000177PyThread_type_sema PyThread_allocate_sema _P1(value, int value)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000178{
179 sema_t *sema;
Guido van Rossum65d5b571998-12-21 19:32:43 +0000180 dprintf(("PyThread_allocate_sema called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000181 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000182 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000183
184 sema = (sema_t *) malloc(sizeof(sema_t));
185 if (sema_init(sema, value, USYNC_THREAD, 0)) {
186 perror("sema_init");
187 free((void *) sema);
188 sema = 0;
189 }
Fred Drakea44d3532000-06-30 15:01:00 +0000190 dprintf(("PyThread_allocate_sema() -> %p\n", sema));
Guido van Rossum65d5b571998-12-21 19:32:43 +0000191 return (PyThread_type_sema) sema;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000192}
193
Guido van Rossum65d5b571998-12-21 19:32:43 +0000194void PyThread_free_sema _P1(sema, PyThread_type_sema sema)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000195{
Fred Drakea44d3532000-06-30 15:01:00 +0000196 dprintf(("PyThread_free_sema(%p) called\n", sema));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000197 if (sema_destroy((sema_t *) sema))
198 perror("sema_destroy");
199 free((void *) sema);
200}
201
Guido van Rossum65d5b571998-12-21 19:32:43 +0000202int PyThread_down_sema _P2(sema, PyThread_type_sema sema, waitflag, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000203{
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000204 int success;
205
Fred Drakea44d3532000-06-30 15:01:00 +0000206 dprintf(("PyThread_down_sema(%p) called\n", sema));
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000207 if (waitflag)
208 success = sema_wait((sema_t *) sema);
209 else
210 success = sema_trywait((sema_t *) sema);
211 if (success < 0) {
212 if (errno == EBUSY)
213 success = 0;
214 else
215 perror("sema_wait");
216 }
217 else
218 success = !success;
Fred Drakea44d3532000-06-30 15:01:00 +0000219 dprintf(("PyThread_down_sema(%p) return %d\n", sema, success));
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000220 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000221}
222
Guido van Rossum65d5b571998-12-21 19:32:43 +0000223void PyThread_up_sema _P1(sema, PyThread_type_sema sema)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000224{
Fred Drakea44d3532000-06-30 15:01:00 +0000225 dprintf(("PyThread_up_sema(%p)\n", sema));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000226 if (sema_post((sema_t *) sema))
227 perror("sema_post");
228}