00001 #if PTHREAD
00002 #include "eus.h"
00003 #define ESUCCESS 0
00004
00005
00006
00007
00008
00009
00010 struct {
00011 int using;
00012 thread_t tid;
00013 } thread_table[MAXTHREAD];
00014
00015 unsigned int thr_self()
00016 {
00017 int i;
00018 thread_t tid;
00019
00020 tid = pthread_self();
00021 for( i = 0; i < MAXTHREAD && !pthread_equal(thread_table[i].tid,tid); i++ )
00022 ;
00023
00024 return( i );
00025 }
00026
00027 int thr_getprio( int tid, int *prio )
00028 {
00029 int policy,err;
00030 struct sched_param param;
00031 err = pthread_getschedparam( thread_table[tid].tid, &policy, ¶m );
00032 if (err == 0){
00033 *prio = param.sched_priority;
00034 return ESUCCESS;
00035 }else
00036 return errno;
00037 }
00038
00039 int thr_setprio(int tid, int prio)
00040 {
00041 int err;
00042 struct sched_param param;
00043 param.sched_priority = prio;
00044 err = pthread_setschedparam( thread_table[tid].tid, SCHED_RR, ¶m );
00045 if (err == 0)
00046 return ESUCCESS;
00047 else
00048 return errno;
00049 }
00050
00051 struct thr_arg {
00052 int tid;
00053 void (*func)();
00054 void *args;
00055 };
00056
00057 static void thr_cleanup( struct thr_arg *arg )
00058 {
00059 thread_table[arg->tid].using = 0;
00060
00061 free(arg);
00062 }
00063
00064 static int thr_create_lock=0;
00065
00066 static void thr_startup( struct thr_arg *arg )
00067 {
00068
00069
00070
00071 pthread_cleanup_push((void(*)(void *))thr_cleanup, arg );
00072 if( !thread_table[arg->tid].tid )
00073 thread_table[arg->tid].tid = pthread_self();
00074
00075
00076 #if !Linux && !Cygwin
00077 pthread_setcancel( CANCEL_ON );
00078 pthread_setasynccancel( CANCEL_ON );
00079 #endif
00080 while(thr_create_lock) usleep(1000);
00081 (arg->func)( arg->args );
00082
00083 pthread_cleanup_pop( 1 );
00084 }
00085
00086 int thr_create(void *base, size_t size, void (*func)(void *), void *args, long flags, int *tid )
00087
00088
00089
00090 {
00091 int i, stat;
00092 struct thr_arg *arg;
00093
00094 for( i = 0; i < MAXTHREAD && thread_table[i].using; i++ )
00095 ;
00096 if( i >= MAXTHREAD )
00097 return -1;
00098
00099 if( (arg = (struct thr_arg *)malloc( sizeof(struct thr_arg) )) == NULL )
00100 return -1;
00101
00102 arg->tid = i;
00103 arg->func = func;
00104 arg->args = args;
00105 thr_create_lock=1;
00106 stat = pthread_create( &thread_table[i].tid, NULL, (void*(*)(void *))thr_startup, arg );
00107 if( stat == 0 )
00108 thread_table[i].using = 1;
00109 *tid = i;
00110 thr_create_lock=0;
00111 return( stat );
00112 }
00113
00114 #if Linux
00115 #include <signal.h>
00116
00117
00118
00119
00120 pthread_mutex_t susp_the_mutex = PTHREAD_MUTEX_INITIALIZER;
00121 pthread_mutex_t susp_mut = PTHREAD_MUTEX_INITIALIZER;
00122 volatile int susp_sentinel = 0;
00123 pthread_once_t susp_once = PTHREAD_ONCE_INIT;
00124 pthread_t susp_null_pthread = {0};
00125 pthread_t susp_array[MAXTHREAD];
00126 int susp_bottom = MAXTHREAD;
00127 int susp_inited = 0;
00128
00129
00130
00131
00132
00133 void
00134 suspend_signal_handler (int sig)
00135 {
00136 sigset_t signal_set;
00137
00138
00139
00140
00141 sigfillset (&signal_set);
00142 sigdelset (&signal_set, SIGUSR2);
00143 susp_sentinel = 1;
00144 sigsuspend (&signal_set);
00145
00146
00147
00148
00149
00150 return;
00151 }
00152
00153
00154
00155
00156
00157
00158 void
00159 resume_signal_handler (int sig)
00160 {
00161 return;
00162 }
00163
00164
00165
00166
00167
00168 void
00169 suspend_init_routine (void)
00170 {
00171 int status;
00172 struct sigaction sigusr1, sigusr2;
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 sigusr1.sa_flags = 0;
00185 sigusr1.sa_handler = suspend_signal_handler;
00186
00187 sigemptyset (&sigusr1.sa_mask);
00188 sigusr2.sa_flags = 0;
00189 sigusr2.sa_handler = resume_signal_handler;
00190 sigusr2.sa_mask = sigusr1.sa_mask;
00191
00192 status = sigaction (SIGUSR1, &sigusr1, NULL);
00193 if (status == -1)
00194 {fprintf (stderr, "Installing suspend handler: %s\n", strerror(errno)); abort();}
00195
00196 status = sigaction (SIGUSR2, &sigusr2, NULL);
00197 if (status == -1)
00198 {fprintf (stderr, "Installing resume handler : %s\n", strerror(errno)); abort(); }
00199
00200 susp_inited = 1;
00201 return;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 int
00213
00214 pthread_suspend (pthread_t target_thread)
00215 {
00216 int status;
00217 int i = 0;
00218
00219
00220
00221
00222
00223 status = pthread_once (&susp_once, suspend_init_routine);
00224 if (status != 0)
00225 return status;
00226
00227
00228
00229
00230 status = pthread_mutex_lock (&susp_mut);
00231 if (status != 0)
00232 return status;
00233
00234
00235
00236
00237
00238
00239
00240 while (i < susp_bottom)
00241 if (susp_array[i++] == target_thread) {
00242 status = pthread_mutex_unlock (&susp_mut);
00243 return status;
00244 }
00245
00246
00247
00248
00249
00250
00251 i = 0;
00252 while (susp_array[i] != 0)
00253 i++;
00254
00255 if (i == susp_bottom) {
00256
00257
00258
00259 pthread_mutex_unlock (&susp_mut);
00260 return errno;
00261
00262
00263
00264 }
00265
00266
00267
00268
00269 susp_sentinel = 0;
00270 status = pthread_kill (target_thread, SIGUSR1);
00271 if (status != 0) {
00272 pthread_mutex_unlock (&susp_mut);
00273 return status;
00274 }
00275
00276
00277
00278
00279 while (susp_sentinel == 0)
00280 sched_yield ();
00281
00282 susp_array[i] = target_thread;
00283
00284 status = pthread_mutex_unlock (&susp_mut);
00285 return status;
00286 }
00287
00288
00289
00290
00291
00292
00293 int
00294
00295 pthread_continue (pthread_t target_thread)
00296 {
00297 int status;
00298 int i = 0;
00299
00300
00301
00302 status = pthread_mutex_lock (&susp_mut);
00303 if (status != 0)
00304 return status;
00305
00306
00307
00308
00309
00310 if (!susp_inited) {
00311 status = pthread_mutex_unlock (&susp_mut);
00312 return status;
00313 }
00314
00315
00316
00317
00318
00319
00320 while (susp_array[i] != target_thread && i < susp_bottom)
00321 i++;
00322
00323 if (i >= susp_bottom) {
00324 pthread_mutex_unlock (&susp_mut);
00325 return 0;
00326 }
00327
00328
00329
00330
00331
00332 status = pthread_kill (target_thread, SIGUSR2);
00333 if (status != 0) {
00334 pthread_mutex_unlock (&susp_mut);
00335 return status;
00336 }
00337
00338 susp_array[i] = 0;
00339 status = pthread_mutex_unlock (&susp_mut);
00340 return status;
00341 }
00342 #endif
00343 int thr_suspend( int tid ) {
00344 return pthread_suspend ( thread_table[tid].tid );
00345 }
00346
00347 int thr_continue( int tid ) {
00348 return pthread_continue ( thread_table[tid].tid );
00349 }
00350
00351
00352 int thr_kill( int tid, int sig )
00353
00354 {
00355 if( pthread_cancel( thread_table[tid].tid ) < 0 )
00356 return errno;
00357 else
00358 return ESUCCESS;
00359 }
00360
00361
00362 int rwlock_init(rwlock_t *rwlp, int type, void *arg)
00363 {
00364 pthread_mutex_init(&(rwlp->lock), NULL);
00365 pthread_cond_init(&(rwlp->r_cond), NULL);
00366 pthread_cond_init(&(rwlp->w_cond), NULL);
00367
00368 rwlp->readers = 0;
00369
00370 return 0;
00371 }
00372
00373 int rwlock_destroy( rwlock_t *rwlp )
00374 {
00375 pthread_mutex_destroy( &(rwlp->lock) );
00376 pthread_cond_destroy( &(rwlp->r_cond) );
00377 pthread_cond_destroy( &(rwlp->w_cond) );
00378
00379 return 0;
00380 }
00381
00382 int rw_rdlock( rwlock_t *rwlp )
00383 {
00384 pthread_mutex_lock( &(rwlp->lock) );
00385 while( rwlp->readers == -1 )
00386 pthread_cond_wait( &(rwlp->r_cond), &(rwlp->lock) );
00387 rwlp->readers++;
00388 pthread_mutex_unlock( &(rwlp->lock) );
00389
00390 return 0;
00391 }
00392
00393 int rw_wrlock( rwlock_t *rwlp )
00394 {
00395 pthread_mutex_lock( &(rwlp->lock) );
00396 while( rwlp->readers != 0 )
00397 pthread_cond_wait( &(rwlp->w_cond), &(rwlp->lock) );
00398 rwlp->readers=-1;
00399 pthread_mutex_unlock( &(rwlp->lock) );
00400
00401 return 0;
00402 }
00403
00404 int rw_unlock( rwlock_t *rwlp )
00405 {
00406 pthread_mutex_lock( &(rwlp->lock) );
00407 if( rwlp->readers == -1 )
00408 rwlp->readers = 0;
00409 else
00410 rwlp->readers--;
00411 pthread_cond_broadcast( &(rwlp->w_cond) );
00412 pthread_cond_broadcast( &(rwlp->r_cond) );
00413 pthread_mutex_unlock( &(rwlp->lock) );
00414
00415 return 0;
00416 }
00417
00418
00419 int sema_init(sema_t *sem, unsigned int c, int d, void *e)
00420
00421
00422
00423 {
00424 pthread_mutex_init(&(sem->lock), NULL);
00425 pthread_cond_init(&(sem->cond), NULL);
00426 sem->count = 0;
00427
00428 return 0;
00429 }
00430
00431 int sema_destroy(sema_t *sem)
00432 {
00433 pthread_mutex_destroy(&(sem->lock));
00434 pthread_cond_destroy(&(sem->cond));
00435
00436 return 0;
00437 }
00438
00439 int sema_wait(sema_t *sem)
00440 {
00441 pthread_mutex_lock(&(sem->lock));
00442 while (sem->count == 0){
00443 pthread_cond_wait(&(sem->cond), &(sem->lock));}
00444 sem->count--;
00445 pthread_mutex_unlock(&(sem->lock));
00446
00447 return 0;
00448 }
00449
00450 int sema_trywait(sema_t *sem)
00451 {
00452 int ret;
00453 pthread_mutex_lock(&(sem->lock));
00454 if (sem->count == 0)
00455 ret = EBUSY;
00456 else{
00457 sem->count--;
00458 ret = 0;
00459 }
00460 pthread_mutex_unlock(&(sem->lock));
00461 return (ret);
00462 }
00463
00464 int sema_post(sema_t *sem)
00465 {
00466 pthread_mutex_lock(&(sem->lock));
00467 sem->count++;
00468 pthread_cond_broadcast(&(sem->cond));
00469 pthread_mutex_unlock(&(sem->lock));
00470
00471 return 0;
00472 }
00473
00474
00475 void mthread_init( context *mainctx )
00476 {
00477 int i;
00478 pthread_t tid;
00479
00480 for( i = 0; i < MAXTHREAD; i++ )
00481 thread_table[i].using = 0;
00482
00483 thread_table[0].tid = pthread_self();
00484 thread_table[0].using = 1;
00485
00486 pthread_mutex_init(&mark_lock, NULL);
00487 pthread_mutex_init(&alloc_lock, NULL);
00488 pthread_mutex_init(&free_thread_lock, NULL);
00489 pthread_mutex_init(&qthread_lock, NULL);
00490 pthread_mutex_init(&qsort_lock, NULL);
00491
00492 sema_init(&free_thread_sem, 0, 0, 0);
00493 rwlock_init(&gc_lock, 0, 0);
00494 }
00495
00496
00497 #endif