~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Python/thread_beos.h

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}