123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- /*--------- threads support ------------------------- g.f. -----*/
- /*--------- lower half of the Oberon Threads module */
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <limits.h>
- #include <signal.h>
- #include <semaphore.h>
- #include <errno.h>
- #include <bits/local_lim.h>
- #include "Threads.h"
- extern int suid_root;
- extern int debug;
- extern void SetSigaltstack();
- static o_thr_t mainthread = 0;
- static struct sched_param oldparam;
- static int oldpolicy;
- #define T_SIGSUSPEND SIGUSR1
- #define T_SIGRESUME SIGUSR2
- static struct sigaction sasuspend, saresume;
- static pthread_mutex_t suspend_mutex;
- static int suspend_done;
- static int resume_done;
- void
- o_thrSleep(int ms) {
- struct timespec sltime, rem;
- sltime.tv_sec = ms/1000;
- sltime.tv_nsec = 1000000*(ms%1000);
- while (nanosleep( &sltime, &rem ) < 0 && errno == EINTR)
- sltime = rem;
- }
- o_mtx_t
- o_mtxInit(int dummy) {
- o_mtx_t mtx;
- mtx = (o_mtx_t)malloc( sizeof(pthread_mutex_t) );
- pthread_mutex_init( mtx, NULL );
- return mtx;
- }
- void
- o_mtxDestroy(o_mtx_t mtx) {
-
- (void)pthread_mutex_destroy( mtx );
- free( mtx );
- }
- void
- o_mtxLock(o_mtx_t mtx) {
-
- (void)pthread_mutex_lock( mtx );
- }
- void
- o_mtxUnlock(o_mtx_t mtx) {
-
- (void)pthread_mutex_unlock( mtx );
- }
- o_con_t
- o_conInit(int dymmy) {
- o_con_t c;
- c = (o_con_t)malloc( sizeof(pthread_cond_t) );
- pthread_cond_init( c, NULL );
- return c;
- }
- void
- o_conDestroy(o_con_t c) {
- pthread_cond_destroy( c );
- free( c );
- }
- void
- o_conWait( o_con_t c, o_mtx_t m ) {
- pthread_cond_wait( c, m );
- }
- void
- o_conSignal( o_con_t c ) {
- pthread_cond_signal( c );
- }
- static void *
- starter(void *p) {
- o_thr_t me = pthread_self();
- oberon_proc proc = (oberon_proc)p;
- sigset_t old, new;
- struct sched_param param;
- SetSigaltstack();
- sigfillset( &new );
- sigdelset( &new, SIGILL );
- sigdelset( &new, SIGTRAP );
- sigdelset( &new, SIGFPE );
- sigdelset( &new, SIGBUS );
- sigdelset( &new, SIGSEGV );
- sigdelset( &new, SIGTERM );
- sigdelset( &new, T_SIGSUSPEND );
- //sigdelset( &new, T_SIGRESUME );
- pthread_sigmask( SIG_SETMASK, &new, &old );
- pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
- pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
- param.sched_priority = 0;
- pthread_setschedparam( me, SCHED_OTHER, ¶m );
- proc();
- pthread_exit( NULL );
- return NULL;
- }
- o_thr_t
- o_thrStart( oberon_proc p, int len ) {
-
- o_thr_t id;
- pthread_attr_t attr;
-
- if (len < PTHREAD_STACK_MIN) len = PTHREAD_STACK_MIN;
- pthread_attr_init( &attr );
- pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
- pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
- pthread_attr_setstacksize( &attr, len );
- if (pthread_create( &id, &attr, starter, p ) != 0) return 0;
- return id;
- }
- o_thr_t
- o_thrThis(int dummy) {
- return pthread_self();
- }
- void
- o_thrYield(int dummy) {
- o_thrSleep( 1 );
- }
- void
- o_thrExit(int dummy) {
-
- pthread_exit( 0 );
- }
- void
- o_thrSuspend(o_thr_t thr) {
- pthread_mutex_lock( &suspend_mutex );
- suspend_done = 0;
- pthread_kill( thr, T_SIGSUSPEND );
- while (suspend_done != 1) o_thrSleep( 1 );
- pthread_mutex_unlock( &suspend_mutex );
- }
- static void
- suspend_handler(int sig) {
- sigset_t block;
- sigfillset( &block );
- sigdelset( &block, T_SIGRESUME );
- suspend_done = 1;
- sigsuspend( &block ); /* await T_SIGRESUME */
- resume_done = 1;
- }
- static void
- resume_handler(int sig) {
- }
- void
- o_thrResume(o_thr_t thr) {
- int n;
- pthread_mutex_lock( &suspend_mutex );
- resume_done = 0; n = 1;
- pthread_kill( thr, T_SIGRESUME );
- while (resume_done != 1 && n < 50) { o_thrSleep( 1 ); n++; }
- pthread_mutex_unlock( &suspend_mutex );
- }
- void
- o_thrSetprio(o_thr_t thr, int prio) {
- struct sched_param param;
- int policy;
- pthread_getschedparam( thr, &policy, ¶m );
- param.sched_priority = prio;
- if (pthread_setschedparam( thr, SCHED_OTHER, ¶m ) != 0)
- perror("pthread_setschedparam");
- }
- int
- o_thrGetprio(o_thr_t thr) {
- struct sched_param param;
- int policy;
- pthread_getschedparam( thr, &policy, ¶m );
- return ( param.sched_priority );
- }
- void
- o_thrKill(o_thr_t thr, int sig) {
- pthread_kill( thr, sig );
- /* if (thr != mainthread) {
- pthread_detach( thr );
- if (thr == pthread_self())
- pthread_exit( 0 );
- else {
- pthread_cancel( thr );
- }
- } */
- }
- int
- o_thrInitialize( int *low, int* high ) {
- struct sched_param param;
-
- pthread_mutex_init( &suspend_mutex, NULL );
- mainthread = pthread_self();
- *high = sched_get_priority_max(SCHED_OTHER);
- *low = sched_get_priority_min(SCHED_OTHER);
- param.sched_priority = *high;
- pthread_setschedparam( mainthread, SCHED_OTHER, ¶m );
- sigemptyset( &sasuspend.sa_mask );
- sigaddset( &sasuspend.sa_mask, T_SIGRESUME );
- sasuspend.sa_flags = 0;
- sasuspend.sa_handler = suspend_handler;
- sigaction( T_SIGSUSPEND, &sasuspend, NULL );
- sigemptyset( &saresume.sa_mask );
- saresume.sa_flags = 0;
- saresume.sa_handler = resume_handler;
- sigaction( T_SIGRESUME, &saresume, NULL );
-
- return 1;
- }
|