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