/**********************************************************************/ /* Howard Eng 4/94 */ /* Unixpros, Inc. */ /* */ /* This module defines "standard" CMA and other exceptions used by the*/ /* Ada "threads" package. It also defines wrappers for the "pthread" */ /* exception returning calls (i.e., "ptdexc_") */ /**********************************************************************/ #include #include #include EXCEPTION ___ada_exceptions___[ ADA_MAX_EXCEPTIONS ]; EXCEPTION cma_e_alerted; EXCEPTION cma_e_assertion; EXCEPTION cma_e_badparam; EXCEPTION cma_e_bugcheck; EXCEPTION cma_e_exit_thread; EXCEPTION cma_e_existence; EXCEPTION cma_e_in_use; EXCEPTION cma_e_use_error; EXCEPTION cma_e_wrongmutex; EXCEPTION cma_e_stackovf; EXCEPTION cma_e_nostackmem; EXCEPTION cma_e_notcmastack; EXCEPTION cma_e_unimp; EXCEPTION cma_e_inialrpro; EXCEPTION cma_e_defer_q_full; EXCEPTION cma_e_signal_q_full; EXCEPTION cma_e_alert_nesting; EXCEPTION exc_e_uninitexc; EXCEPTION exc_e_illaddr; EXCEPTION exc_e_exquota; EXCEPTION exc_e_insfmem; EXCEPTION exc_e_nopriv; EXCEPTION exc_e_illinstr; EXCEPTION exc_e_resaddr; EXCEPTION exc_e_privinst; EXCEPTION exc_e_resoper; EXCEPTION exc_e_SIGTRAP; EXCEPTION exc_e_SIGIOT; EXCEPTION exc_e_SIGEMT; EXCEPTION exc_e_aritherr; EXCEPTION exc_e_SIGPIPE; EXCEPTION exc_e_SIGSYS; EXCEPTION exc_e_excpu; EXCEPTION exc_e_exfilsiz; EXCEPTION exc_e_intovf; EXCEPTION exc_e_intdiv; EXCEPTION exc_e_fltovf; EXCEPTION exc_e_fltdiv; EXCEPTION exc_e_fltund; EXCEPTION exc_e_decovf; EXCEPTION exc_e_subrng; void init___ada_exceptions ( int max_ada_excs ) { int i; if ( max_ada_excs != (int) ADA_MAX_EXCEPTIONS ) { fprintf( stderr, "Mismatch in Exceptions\n" ); exit( 1 ); } EXCEPTION_INIT( cma_e_alerted ); EXCEPTION_INIT( cma_e_assertion ); EXCEPTION_INIT( cma_e_badparam ); EXCEPTION_INIT( cma_e_bugcheck ); EXCEPTION_INIT( cma_e_exit_thread ); EXCEPTION_INIT( cma_e_existence ); EXCEPTION_INIT( cma_e_in_use ); EXCEPTION_INIT( cma_e_use_error ); EXCEPTION_INIT( cma_e_wrongmutex ); EXCEPTION_INIT( cma_e_stackovf ); EXCEPTION_INIT( cma_e_nostackmem ); EXCEPTION_INIT( cma_e_notcmastack ); EXCEPTION_INIT( cma_e_unimp ); EXCEPTION_INIT( cma_e_inialrpro ); EXCEPTION_INIT( cma_e_defer_q_full ); EXCEPTION_INIT( cma_e_signal_q_full ); EXCEPTION_INIT( cma_e_alert_nesting ); EXCEPTION_INIT( exc_e_uninitexc ); EXCEPTION_INIT( cma_e_badparam ); EXCEPTION_INIT( cma_e_alerted ); EXCEPTION_INIT( exc_e_SIGPIPE ); EXCEPTION_INIT( exc_e_SIGSYS ); EXCEPTION_INIT( exc_e_SIGTRAP ); EXCEPTION_INIT( exc_e_SIGIOT ); EXCEPTION_INIT( exc_e_SIGEMT ); EXCEPTION_INIT( exc_e_illaddr ); EXCEPTION_INIT( exc_e_exquota ); EXCEPTION_INIT( exc_e_insfmem ); EXCEPTION_INIT( exc_e_nopriv ); EXCEPTION_INIT( exc_e_illinstr ); EXCEPTION_INIT( exc_e_resaddr ); EXCEPTION_INIT( exc_e_privinst ); EXCEPTION_INIT( exc_e_resoper ); EXCEPTION_INIT( exc_e_aritherr ); EXCEPTION_INIT( exc_e_excpu ); EXCEPTION_INIT( exc_e_exfilsiz ); EXCEPTION_INIT( exc_e_intovf ); EXCEPTION_INIT( exc_e_intdiv ); EXCEPTION_INIT( exc_e_fltovf ); EXCEPTION_INIT( exc_e_fltdiv ); EXCEPTION_INIT( exc_e_fltund ); EXCEPTION_INIT( exc_e_decovf ); EXCEPTION_INIT( exc_e_subrng ); for( i = 0; i < ADA_MAX_EXCEPTIONS; i++ ) { switch ( i ) { case ADA_EXIT_THREAD_E: ___ada_exceptions___[ i ] = cma_e_exit_thread; break; case ADA_USE_ERROR_E: ___ada_exceptions___[ i ] = cma_e_use_error; break; case ADA_PTHREAD_CANCEL_E : ___ada_exceptions___[ i ] = pthread_cancel_e; break; default : EXCEPTION_INIT( ___ada_exceptions___[ i ] ); break; } } } void ada_thd_raise_exception ( exc ) ada_pthread_exc_t exc; { #ifndef NDEBUG fprintf( stderr, "Raising Exception: %d\n", exc ); #endif if ( (int) exc < 0 || (int) exc > ADA_MAX_EXCEPTIONS ) { fprintf( stderr, "Invalid Exception: %d\n", (int) exc ); RAISE( cma_e_use_error ); } else RAISE( ___ada_exceptions___[ exc ] ); } int ptdexc_attr_create _CMA_PROTOTYPE_ (( pthread_attr_t *attr)) { pthread_attr_t attr1; int status; status = pthread_attr_create( &attr1 ); *attr = attr1; } /* * An attributes object can be deleted when it is no longer needed. */ int ptdexc_attr_delete _CMA_PROTOTYPE_ (( pthread_attr_t *attr)) { pthread_attr_t attr1; int status; status = pthread_attr_delete( &attr1 ); *attr = attr1; return ( status ); } int ptdexc_attr_setprio _CMA_PROTOTYPE_ (( pthread_attr_t *attr, int priority)) { pthread_attr_t attr1; int status; status = pthread_attr_setprio( &attr1, priority ); *attr = attr1; return ( status ); } int ptdexc_attr_getprio _CMA_PROTOTYPE_ (( pthread_attr_t attr)) { return ( pthread_attr_getprio( attr ) ); } int ptdexc_attr_setsched _CMA_PROTOTYPE_ (( pthread_attr_t *attr, int scheduler)) { return pthread_attr_setsched( attr, scheduler ); } int ptdexc_attr_getsched _CMA_PROTOTYPE_ (( pthread_attr_t attr)) { return pthread_attr_getsched( attr ); } /* * Set or obtain whether a thread will use the default scheduling attributes, * or inherit them from the creating thread. */ int ptdexc_attr_setinheritsched _CMA_PROTOTYPE_ (( pthread_attr_t *attr, int inherit)) { return pthread_attr_setinheritsched( attr, inherit ); } int ptdexc_attr_getinheritsched _CMA_PROTOTYPE_ (( pthread_attr_t attr)) { return ( pthread_attr_getinheritsched( attr ) ); } /* * Set or obtain the default stack size */ int ptdexc_attr_setstacksize _CMA_PROTOTYPE_ (( pthread_attr_t *attr, long stacksize)) { return ( pthread_attr_setstacksize( attr, stacksize ) ); } long ptdexc_attr_getstacksize _CMA_PROTOTYPE_ (( pthread_attr_t attr)) { return ( pthread_attr_getstacksize( attr ) ); } int ptdexc_create _CMA_PROTOTYPE_ (( pthread_t *thread, pthread_attr_t attr, pthread_startroutine_t start_routine, pthread_addr_t arg)) { pthread_t thd; int status; status = pthread_create( &thd, attr, start_routine, arg); *thread = thd; return status; } /* * A thread object may be "detached" to specify that the return value and * completion status will not be requested. */ int ptdexc_detach _CMA_PROTOTYPE_ (( pthread_t *thread)) { return ( pthread_detach( thread ) ); } /* * A thread may terminate it's own execution. */ void ptdexc_exit _CMA_PROTOTYPE_ (( pthread_addr_t status)) { pthread_exit( status ); } /* * A thread can await termination of another thread and retrieve the return * value of the thread. */ int ptdexc_join _CMA_PROTOTYPE_ (( pthread_t thread, pthread_addr_t *status)) { return ( pthread_join( thread, status ) ); } /* * Thread Scheduling Operations */ /* * The current user_assigned priority of a thread can be changed. */ int ptdexc_setprio _CMA_PROTOTYPE_ (( pthread_t thread, int priority)) { return ( pthread_setprio( thread, priority ) ); } /* * The current user_assigned scheduler algorithm of a thread can be changed. */ int ptdexc_setscheduler _CMA_PROTOTYPE_ (( pthread_t thread, int scheduler, int priority)) { return ( pthread_setscheduler( thread, scheduler, priority ) ); } /* * A thread may tell the scheduler that its processor can be made available. */ void ptdexc_yield _CMA_PROTOTYPE_ ((void)) { pthread_yield(); } /* * Thread Information Operations */ /* * A thread may obtain a copy of its own thread handle. */ pthread_t ptdexc_self _CMA_PROTOTYPE_ ((void)) { return ( pthread_self() ); } /* * The current user_assigned priority of a thread can be read. */ int ptdexc_getprio _CMA_PROTOTYPE_ (( pthread_t thread)) { return ( pthread_getprio( thread ) ); } /* * The current user_assigned scheduler algorithm of a thread can be read. */ int ptdexc_getscheduler _CMA_PROTOTYPE_ (( pthread_t thread)) { return ( pthread_getscheduler( thread ) ); } /* * Operations on Mutexes */ int ptdexc_mutexattr_create _CMA_PROTOTYPE_ (( pthread_mutexattr_t *attr)) { pthread_mutexattr_t attr1; int status; status = pthread_mutexattr_create( &attr1 ); *attr = attr1; return ( status ); } int ptdexc_mutexattr_delete _CMA_PROTOTYPE_ (( pthread_mutexattr_t *attr)) { return ( pthread_mutexattr_delete( attr ) ); } int ptdexc_mutexattr_setkind_np _CMA_PROTOTYPE_ (( pthread_mutexattr_t *attr, int kind)) { return pthread_mutexattr_setkind_np( attr, kind ); } int ptdexc_mutexattr_getkind_np _CMA_PROTOTYPE_ (( pthread_mutexattr_t attr)) { return pthread_mutexattr_getkind_np( attr ); } /* * The following routines create, delete, lock and unlock mutexes. */ int ptdexc_mutex_init _CMA_PROTOTYPE_ (( pthread_mutex_t *mutex, pthread_mutexattr_t attr)) { pthread_mutex_t mut; int status; status = pthread_mutex_init( &mut, attr ); *mutex = mut; return ( status ); } int ptdexc_mutex_destroy _CMA_PROTOTYPE_ (( pthread_mutex_t *mutex)) { return pthread_mutex_destroy( mutex ); } int ptdexc_mutex_lock _CMA_PROTOTYPE_ (( pthread_mutex_t *mutex)) { return ( pthread_mutex_lock( mutex ) ); } int ptdexc_mutex_trylock _CMA_PROTOTYPE_ (( pthread_mutex_t *mutex)) { return ( pthread_mutex_trylock( mutex ) ); } int ptdexc_mutex_unlock _CMA_PROTOTYPE_ (( pthread_mutex_t *mutex)) { return ( pthread_mutex_unlock( mutex ) ); } /* * Operations on condition variables */ int ptdexc_condattr_create _CMA_PROTOTYPE_ (( pthread_condattr_t *attr)) { pthread_condattr_t attr1; int status; status = pthread_condattr_create( &attr1 ); *attr = attr1; return( status ); } int ptdexc_condattr_delete _CMA_PROTOTYPE_ (( pthread_condattr_t *attr)) { return pthread_condattr_delete( attr ); } /* * A thread can create and delete condition variables. */ int ptdexc_cond_init _CMA_PROTOTYPE_ (( pthread_cond_t *cond, pthread_condattr_t attr)) { pthread_cond_t cnd; int status; status = pthread_cond_init( &cnd, attr ); *cond = cnd; return( status ); } int ptdexc_cond_destroy _CMA_PROTOTYPE_ (( pthread_cond_t *cond)) { return ( pthread_cond_destroy( cond ) ); } /* * A thread can signal to and broadcast on a condition variable. */ int ptdexc_cond_broadcast _CMA_PROTOTYPE_ (( pthread_cond_t *cond)) { return ( pthread_cond_broadcast( cond ) ); } int ptdexc_cond_signal _CMA_PROTOTYPE_ (( pthread_cond_t *cond)) { return ( pthread_cond_signal( cond ) ); } int ptdexc_cond_signal_int_np _CMA_PROTOTYPE_ (( pthread_cond_t *cond)) { return( pthread_cond_signal( cond ) ); } /* * A thread can wait for a condition variable to be signalled or broadcast. */ int ptdexc_cond_wait _CMA_PROTOTYPE_ (( pthread_cond_t *cond, pthread_mutex_t *mutex)) { return ( pthread_cond_wait( cond, mutex ) ); } /* * Operations for timed waiting */ /* * A thread can perform a timed wait on a condition variable. */ int ptdexc_cond_timedwait _CMA_PROTOTYPE_ (( pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime)) { return( pthread_cond_timedwait( cond, mutex, abstime ) ); } /* * Operations for client initialization. */ int ptdexc_once _CMA_PROTOTYPE_ (( pthread_once_t *once_block, pthread_initroutine_t init_routine)) { pthread_once_t init_block = pthread_once_init; pthread_lock_global_np(); if( !memcmp( once_block, &init_block, sizeof( init_block )) ) { init_routine(); once_block->field1 = init_block.field1 + 1; } pthread_unlock_global_np(); return ( 0 ); } /* * Operations for per-thread context */ int ptdexc_keycreate _CMA_PROTOTYPE_ (( pthread_key_t *key, pthread_destructor_t destructor)) { pthread_key_t k; int status; status = pthread_keycreate( &k, destructor ); *key = k; return( status ); } /* * A thread can set a per-thread context value identified by a key. */ int ptdexc_setspecific _CMA_PROTOTYPE_ (( pthread_key_t key, pthread_addr_t value)) { return ( pthread_setspecific( key, value ) ); } /* * A thread can retrieve a per-thread context value identified by a key. */ int ptdexc_getspecific _CMA_PROTOTYPE_ (( pthread_key_t key, pthread_addr_t *value)) { return ( pthread_getspecific( key, value ) ); } /* * Operations for alerts. */ /* * The current thread can request that a thread terminate it's execution. */ int ptdexc_cancel _CMA_PROTOTYPE_ (( pthread_t thread)) { return ( pthread_cancel( thread ) ); } /* * The current thread can poll for alert delivery. */ void ptdexc_testcancel _CMA_PROTOTYPE_ ((void)) { pthread_testcancel(); } /* * The current thread can enable or disable alert delivery (PTHREAD * "cancels"); it can control "general cancelability" (CMA "defer") or * just "asynchronous cancelability" (CMA "asynch disable"). */ int ptdexc_setasynccancel _CMA_PROTOTYPE_ (( int state)) { return( pthread_setasynccancel( state )); } int ptdexc_setcancel _CMA_PROTOTYPE_ (( int state)) { return ( pthread_setcancel( state ) ); } /* * Define nonportable extensions */ extern int ptdexc_get_expiration_np _CMA_PROTOTYPE_ (( struct timespec *delta, struct timespec *abstime)) { return( pthread_get_expiration_np( delta, abstime ) ); } extern int ptdexc_delay_np _CMA_PROTOTYPE_ (( struct timespec *interval)) { return pthread_delay_np( interval ); } extern void ptdexc_lock_global_np _CMA_PROTOTYPE_ ((void)) { pthread_lock_global_np(); } extern void ptdexc_unlock_global_np _CMA_PROTOTYPE_ ((void)) { pthread_unlock_global_np(); }