2 #include <support/SupportDefs.h>
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/).
9 typedef struct benaphore
{
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
);
20 static status_t
benaphore_create( const char *name
, benaphore_t
*ben
)
24 ben
->_sem
= create_sem( 0, name
);
26 if( ben
->_sem
< B_NO_ERROR
) {
36 static status_t
benaphore_destroy( benaphore_t
*ben
)
38 if( ben
->_sem
>= B_NO_ERROR
) {
39 status_t retval
= benaphore_timedlock( ben
, 0 );
41 if( retval
== EOK
|| retval
== EWOULDBLOCK
) {
42 status_t del_retval
= delete_sem( ben
->_sem
);
51 static status_t
benaphore_lock( benaphore_t
*ben
)
53 int32 prev
= atomic_add( &(ben
->_atom
), 1 );
56 return acquire_sem( ben
->_sem
);
62 static status_t
benaphore_timedlock( benaphore_t
*ben
, bigtime_t micros
)
64 int32 prev
= atomic_add( &(ben
->_atom
), 1 );
67 status_t retval
= acquire_sem_etc( ben
->_sem
, 1, B_TIMEOUT
, micros
);
70 case B_WOULD_BLOCK
: /* Fall through... */
86 static status_t
benaphore_unlock( benaphore_t
*ben
)
88 int32 prev
= atomic_add( &(ben
->_atom
), -1 );
91 return release_sem( ben
->_sem
);
97 /* ----------------------------------------------------------------------
100 static void PyThread__init_thread( void )
106 /* ----------------------------------------------------------------------
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.
113 static int32 thread_count
= 0;
115 long PyThread_start_new_thread( void (*func
)(void *), void *arg
)
117 status_t success
= 0;
119 char name
[B_OS_NAME_LENGTH
];
122 dprintf(("PyThread_start_new_thread called\n"));
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
);
129 tid
= spawn_thread( (thread_func
)func
, name
,
130 B_NORMAL_PRIORITY
, arg
);
131 if( tid
> B_NO_ERROR
) {
132 success
= resume_thread( tid
);
135 return ( success
== B_NO_ERROR
? tid
: -1 );
138 long PyThread_get_thread_ident( void )
140 /* Presumed to return the current thread's ID... */
142 tid
= find_thread( NULL
);
144 return ( tid
!= B_NAME_NOT_FOUND
? tid
: -1 );
147 void PyThread_exit_thread( void )
151 dprintf(("PyThread_exit_thread called\n"));
153 /* Thread-safe way to read a variable without a mutex: */
154 threads
= atomic_add( &thread_count
, 0 );
157 /* No threads around, so exit main(). */
160 /* Oh, we're a thread, let's try to exit gracefully... */
161 exit_thread( B_NO_ERROR
);
165 /* ----------------------------------------------------------------------
169 static int32 lock_count
= 0;
171 PyThread_type_lock
PyThread_allocate_lock( void )
175 char name
[B_OS_NAME_LENGTH
];
178 dprintf(("PyThread_allocate_lock called\n"));
180 lock
= (benaphore_t
*)malloc( sizeof( benaphore_t
) );
182 /* TODO: that's bad, raise MemoryError */
183 return (PyThread_type_lock
)NULL
;
186 this_lock
= atomic_add( &lock_count
, 1 );
187 PyOS_snprintf(name
, sizeof(name
), "python lock (%d)", this_lock
);
189 retval
= benaphore_create( name
, lock
);
190 if( retval
!= EOK
) {
191 /* TODO: that's bad, raise an exception */
192 return (PyThread_type_lock
)NULL
;
195 dprintf(("PyThread_allocate_lock() -> %p\n", lock
));
196 return (PyThread_type_lock
) lock
;
199 void PyThread_free_lock( PyThread_type_lock lock
)
203 dprintf(("PyThread_free_lock(%p) called\n", lock
));
205 retval
= benaphore_destroy( (benaphore_t
*)lock
);
206 if( retval
!= EOK
) {
207 /* TODO: that's bad, raise an exception */
212 int PyThread_acquire_lock( PyThread_type_lock lock
, int waitflag
)
217 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock
, waitflag
));
220 retval
= benaphore_lock( (benaphore_t
*)lock
);
222 retval
= benaphore_timedlock( (benaphore_t
*)lock
, 0 );
225 if( retval
== EOK
) {
230 /* TODO: that's bad, raise an exception */
233 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock
, waitflag
, success
));
237 void PyThread_release_lock( PyThread_type_lock lock
)
241 dprintf(("PyThread_release_lock(%p) called\n", lock
));
243 retval
= benaphore_unlock( (benaphore_t
*)lock
);
244 if( retval
!= EOK
) {
245 /* TODO: that's bad, raise an exception */