History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Python/thread_beos.h (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Python/thread_beos.h+287−0
@@ -0,0 +1,287 @@
1+#include <kernel/OS.h>
2+#include <support/SupportDefs.h>
3+#include <errno.h>
4+
5+/* ----------------------------------------------------------------------
6+ * Fast locking mechanism described by Benoit Schillings (benoit@be.com)
7+ * in the Be Developer's Newsletter, Issue #26 (http://www.be.com/).
8+ */
9+typedef struct benaphore {
10+ sem_id _sem;
11+ int32 _atom;
12+} benaphore_t;
13+
14+static status_t benaphore_create( const char *name, benaphore_t *ben );
15+static status_t benaphore_destroy( benaphore_t *ben );
16+static status_t benaphore_lock( benaphore_t *ben );
17+static status_t benaphore_timedlock( benaphore_t *ben, bigtime_t micros );
18+static status_t benaphore_unlock( benaphore_t *ben );
19+
20+static status_t benaphore_create( const char *name, benaphore_t *ben )
21+{
22+ if( ben != NULL ) {
23+ ben->_atom = 0;
24+ ben->_sem = create_sem( 0, name );
25+
26+ if( ben->_sem < B_NO_ERROR ) {
27+ return B_BAD_SEM_ID;
28+ }
29+ } else {
30+ return EFAULT;
31+ }
32+
33+ return EOK;
34+}
35+
36+static status_t benaphore_destroy( benaphore_t *ben )
37+{
38+ if( ben->_sem >= B_NO_ERROR ) {
39+ status_t retval = benaphore_timedlock( ben, 0 );
40+
41+ if( retval == EOK || retval == EWOULDBLOCK ) {
42+ status_t del_retval = delete_sem( ben->_sem );
43+
44+ return del_retval;
45+ }
46+ }
47+
48+ return B_BAD_SEM_ID;
49+}
50+
51+static status_t benaphore_lock( benaphore_t *ben )
52+{
53+ int32 prev = atomic_add( &(ben->_atom), 1 );
54+
55+ if( prev > 0 ) {
56+ return acquire_sem( ben->_sem );
57+ }
58+
59+ return EOK;
60+}
61+
62+static status_t benaphore_timedlock( benaphore_t *ben, bigtime_t micros )
63+{
64+ int32 prev = atomic_add( &(ben->_atom), 1 );
65+
66+ if( prev > 0 ) {
67+ status_t retval = acquire_sem_etc( ben->_sem, 1, B_TIMEOUT, micros );
68+
69+ switch( retval ) {
70+ case B_WOULD_BLOCK: /* Fall through... */
71+ case B_TIMED_OUT:
72+ return EWOULDBLOCK;
73+ break;
74+ case B_OK:
75+ return EOK;
76+ break;
77+ default:
78+ return retval;
79+ break;
80+ }
81+ }
82+
83+ return EOK;
84+}
85+
86+static status_t benaphore_unlock( benaphore_t *ben )
87+{
88+ int32 prev = atomic_add( &(ben->_atom), -1 );
89+
90+ if( prev > 1 ) {
91+ return release_sem( ben->_sem );
92+ }
93+
94+ return EOK;
95+}
96+
97+/* ----------------------------------------------------------------------
98+ * Initialization.
99+ */
100+static void PyThread__init_thread( void )
101+{
102+ /* Do nothing. */
103+ return;
104+}
105+
106+/* ----------------------------------------------------------------------
107+ * Thread support.
108+ *
109+ * Only ANSI C, renamed functions here; you can't use K&R on BeOS,
110+ * and there's no legacy thread module to support.
111+ */
112+
113+static int32 thread_count = 0;
114+
115+long PyThread_start_new_thread( void (*func)(void *), void *arg )
116+{
117+ status_t success = 0;
118+ thread_id tid;
119+ char name[B_OS_NAME_LENGTH];
120+ int32 this_thread;
121+
122+ dprintf(("PyThread_start_new_thread called\n"));
123+
124+ /* We are so very thread-safe... */
125+ this_thread = atomic_add( &thread_count, 1 );
126+ PyOS_snprintf(name, sizeof(name),
127+ "python thread (%d)", this_thread );
128+
129+ tid = spawn_thread( (thread_func)func, name,
130+ B_NORMAL_PRIORITY, arg );
131+ if( tid > B_NO_ERROR ) {
132+ success = resume_thread( tid );
133+ }
134+
135+ return ( success == B_NO_ERROR ? tid : -1 );
136+}
137+
138+long PyThread_get_thread_ident( void )
139+{
140+ /* Presumed to return the current thread's ID... */
141+ thread_id tid;
142+ tid = find_thread( NULL );
143+
144+ return ( tid != B_NAME_NOT_FOUND ? tid : -1 );
145+}
146+
147+static void do_PyThread_exit_thread( int no_cleanup )
148+{
149+ int32 threads;
150+
151+ dprintf(("PyThread_exit_thread called\n"));
152+
153+ /* Thread-safe way to read a variable without a mutex: */
154+ threads = atomic_add( &thread_count, 0 );
155+
156+ if( threads == 0 ) {
157+ /* No threads around, so exit main(). */
158+ if( no_cleanup ) {
159+ _exit(0);
160+ } else {
161+ exit(0);
162+ }
163+ } else {
164+ /* Oh, we're a thread, let's try to exit gracefully... */
165+ exit_thread( B_NO_ERROR );
166+ }
167+}
168+
169+void PyThread_exit_thread( void )
170+{
171+ do_PyThread_exit_thread(0);
172+}
173+
174+void PyThread__exit_thread( void )
175+{
176+ do_PyThread_exit_thread(1);
177+}
178+
179+#ifndef NO_EXIT_PROG
180+static void do_PyThread_exit_prog( int status, int no_cleanup )
181+{
182+ dprintf(("PyThread_exit_prog(%d) called\n", status));
183+
184+ /* No need to do anything, the threads get torn down if main() exits. */
185+
186+ if (no_cleanup) {
187+ _exit(status);
188+ } else {
189+ exit(status);
190+ }
191+}
192+
193+void PyThread_exit_prog( int status )
194+{
195+ do_PyThread_exit_prog(status, 0);
196+}
197+
198+void PyThread__exit_prog( int status )
199+{
200+ do_PyThread_exit_prog(status, 1);
201+}
202+#endif /* NO_EXIT_PROG */
203+
204+/* ----------------------------------------------------------------------
205+ * Lock support.
206+ */
207+
208+static int32 lock_count = 0;
209+
210+PyThread_type_lock PyThread_allocate_lock( void )
211+{
212+ benaphore_t *lock;
213+ status_t retval;
214+ char name[B_OS_NAME_LENGTH];
215+ int32 this_lock;
216+
217+ dprintf(("PyThread_allocate_lock called\n"));
218+
219+ lock = (benaphore_t *)malloc( sizeof( benaphore_t ) );
220+ if( lock == NULL ) {
221+ /* TODO: that's bad, raise MemoryError */
222+ return (PyThread_type_lock)NULL;
223+ }
224+
225+ this_lock = atomic_add( &lock_count, 1 );
226+ PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);
227+
228+ retval = benaphore_create( name, lock );
229+ if( retval != EOK ) {
230+ /* TODO: that's bad, raise an exception */
231+ return (PyThread_type_lock)NULL;
232+ }
233+
234+ dprintf(("PyThread_allocate_lock() -> %p\n", lock));
235+ return (PyThread_type_lock) lock;
236+}
237+
238+void PyThread_free_lock( PyThread_type_lock lock )
239+{
240+ status_t retval;
241+
242+ dprintf(("PyThread_free_lock(%p) called\n", lock));
243+
244+ retval = benaphore_destroy( (benaphore_t *)lock );
245+ if( retval != EOK ) {
246+ /* TODO: that's bad, raise an exception */
247+ return;
248+ }
249+}
250+
251+int PyThread_acquire_lock( PyThread_type_lock lock, int waitflag )
252+{
253+ int success;
254+ status_t retval;
255+
256+ dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
257+
258+ if( waitflag ) {
259+ retval = benaphore_lock( (benaphore_t *)lock );
260+ } else {
261+ retval = benaphore_timedlock( (benaphore_t *)lock, 0 );
262+ }
263+
264+ if( retval == EOK ) {
265+ success = 1;
266+ } else {
267+ success = 0;
268+
269+ /* TODO: that's bad, raise an exception */
270+ }
271+
272+ dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
273+ return success;
274+}
275+
276+void PyThread_release_lock( PyThread_type_lock lock )
277+{
278+ status_t retval;
279+
280+ dprintf(("PyThread_release_lock(%p) called\n", lock));
281+
282+ retval = benaphore_unlock( (benaphore_t *)lock );
283+ if( retval != EOK ) {
284+ /* TODO: that's bad, raise an exception */
285+ return;
286+ }
287+}