/**********************************************************************/ /* Howard Eng 2/94 */ /* Unixpros, Inc. */ /* */ /* This module defines the "pthread_" wrappers into the "Ada" threads.*/ /* The model for thread cancellation is as follows: */ /* */ /* - all of the pthread calls are contained within TRY/CATCH */ /* blocks. The TRY block contains the corresponding Ada */ /* pthread implementation. */ /* - if the pthread call is a cancellation point, then the Cancel*/ /* exception is raised from within the call. */ /* - if there are cleanup handlers, then they are executed since */ /* the handlers catch and absorb the Cancel exception. */ /* - Other exceptions can be raised from within the Ada code */ /* and must be caught in the wrappers. For example, pthread_ */ /* create() catches STORAGE_ERROR exceptions if there is */ /* insufficient memory. */ /* */ /**********************************************************************/ #include #include #include #include #include #include extern int ada_thd_is_handle_valid( pthread_t *, int * ); #include #define ada_thd_set_errno cma__set_errno pthread_attr_t pthread_attr_default; pthread_mutexattr_t pthread_mutexattr_default; pthread_condattr_t pthread_condattr_default; /**********************************************************************/ /* Returns the current task's TCB. This is used as a unique ID for */ /* the thread. */ /**********************************************************************/ char *ada_thd_get_task_tcb_ptr () { extern char **alsytac_curr_tcb_ptr; return ( *alsytac_curr_tcb_ptr ); } /**********************************************************************/ /* Initialize "ada_pthreads" */ /**********************************************************************/ void ada_thd_init_ada_threads ( max_ada_excs ) int max_ada_excs; { int i; init___ada_exceptions( max_ada_excs ); cma_init(); } int pthread_attr_create ( pthread_attr_t *attr ) { int status = 0; extern void ada_pthread_attr_create( pthread_attr_t * ); attr->field1 = (cma_t_address) attr; TRY ada_pthread_attr_create( attr ); CATCH ( ___ada_exceptions___[ ADA_NO_MEMORY_E ] ) status = -1; errno = ada_thd_set_errno( ENOMEM ); #ifndef NDEBUG fprintf( stderr, "No Memory: %s %d\n", __FILE__, __LINE__ ); #endif CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) status = -1; errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_attr_setsched ( pthread_attr_t *attr, int sched ) { int status = -1; extern int ada_pthread_attr_setsched( pthread_attr_t *, int ); TRY status = ada_pthread_attr_setsched( attr, sched ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_EOPNOTSUPP_E ] ) errno = ada_thd_set_errno( EOPNOTSUPP ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } void pthread_unlock_global_np () { extern pthread_mutex_t __ada__g_global_lock__; pthread_mutex_unlock( &__ada__g_global_lock__ ); } void pthread_lock_global_np () { extern pthread_mutex_t __ada__g_global_lock__; pthread_mutex_lock( &__ada__g_global_lock__ ); } int pthread_attr_setprio ( pthread_attr_t *attr, int priority ) { int status = -1; extern int ada_pthread_attr_setprio( pthread_attr_t *, int ); TRY status = ada_pthread_attr_setprio( attr, priority ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_EOPNOTSUPP_E ] ) errno = ada_thd_set_errno( EOPNOTSUPP ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_attr_delete ( pthread_attr_t *attr ) { int status = -1; extern int ada_pthread_attr_delete( pthread_attr_t *); TRY status = ada_pthread_attr_delete( attr ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return (status ); } int pthread_attr_setstacksize ( pthread_attr_t *attr, long stacksize ) { int size = 0; extern int ada_pthread_attr_setstacksize( pthread_attr_t *, long ); TRY size = ada_pthread_attr_setstacksize( attr, stacksize ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_EOPNOTSUPP_E ] ) errno = ada_thd_set_errno( EOPNOTSUPP ); CATCH_ALL RERAISE; ENDTRY; return size; } int pthread_mutex_destroy ( pthread_mutex_t *mutex ) { int status = -1; extern int ada_pthread_mutex_destroy( pthread_mutex_t *); TRY status = ada_pthread_mutex_destroy( mutex ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_EBUSY_E ] ) errno = ada_thd_set_errno( EBUSY ); CATCH ( ___ada_exceptions___[ ADA_EDEADLK_E ] ) errno = ada_thd_set_errno( EDEADLK ); CATCH ( ___ada_exceptions___[ ADA_USE_ERROR_E ] ) errno = ada_thd_set_errno( EINVAL ); fprintf( stderr, "Can't Destroy Mutex Not Owned\n" ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_mutex_trylock ( pthread_mutex_t *mutex ) { int status = -1; extern int ada_pthread_mutex_trylock( pthread_mutex_t *); TRY status = ada_pthread_mutex_trylock( mutex ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_EBUSY_E ] ) errno = ada_thd_set_errno( EBUSY ); CATCH ( ___ada_exceptions___[ ADA_EDEADLK_E ] ) errno = ada_thd_set_errno( EDEADLK ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_mutex_lock ( pthread_mutex_t *mutex ) { int status = -1; extern int ada_pthread_mutex_lock( pthread_mutex_t *); TRY status = ada_pthread_mutex_lock( mutex ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_EBUSY_E ] ) errno = ada_thd_set_errno( EBUSY ); CATCH ( ___ada_exceptions___[ ADA_EDEADLK_E ] ) errno = ada_thd_set_errno( EDEADLK ); CATCH ( ___ada_exceptions___[ ADA_USE_ERROR_E ] ) fprintf( stderr, "Use Error during lock\n" ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_mutex_unlock ( pthread_mutex_t *mutex ) { int status = -1; extern int ada_pthread_mutex_unlock( pthread_mutex_t *); TRY status = ada_pthread_mutex_unlock( mutex ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_EBUSY_E ] ) errno = ada_thd_set_errno( EBUSY ); CATCH ( ___ada_exceptions___[ ADA_EDEADLK_E ] ) errno = ada_thd_set_errno( EDEADLK ); CATCH ( ___ada_exceptions___[ ADA_USE_ERROR_E ] ) errno = ada_thd_set_errno( EINVAL ); fprintf( stderr, "Can't unlock Mutex Not owned\n" ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } extern int ada_thd_is_key_valid( pthread_key_t ); /**********************************************************************/ /* Associates "value" with the thread's "key". If the key is not */ /* known in the current application context, then errno is set to */ /* EINVAL. If the key is not known to the current thread, then it */ /* is added to the thread. Otherwise, the thread specific value is */ /* saved. */ /**********************************************************************/ int pthread_setspecific ( pthread_key_t key, pthread_addr_t value ) { int out = 0; extern void ada_pthread_setspecfic( pthread_key_t, pthread_addr_t ); extern void ada_pthread_keycreate( pthread_key_t , pthread_destructor_t ); if ( !ada_ptd_check_master_key_list( key ) ) errno = ada_thd_set_errno( EINVAL ); else if( ada_thd_is_key_valid( key ) ) { ada_pthread_setspecific( key, value ); } else { pthread_destructor_t destructor; destructor = ada_thd_get_master_key_destructor( key ); TRY { ada_pthread_keycreate( key, destructor ); ada_pthread_setspecific( key, value ); } CATCH ( ___ada_exceptions___[ ADA_NO_MEMORY_E ] ) errno = ada_thd_set_errno( EAGAIN ); out = -1; #ifndef NDEBUG fprintf( stderr, "No Memory: %s %d\n", __FILE__, __LINE__ ); #endif CATCH ( ___ada_exceptions___[ ADA_NO_RESOURCES_E ] ) errno = ada_thd_set_errno( ENOMEM ); out = -1; CATCH_ALL RERAISE; ENDTRY; } return out; } /**********************************************************************/ /* Returns the value associated with "key". If the key is not known */ /* to the application, then errno is set to EINVAL. If the key is */ /* not known to the thread, then "value" is set to NULL and the key */ /* is added to the thread. Otherwise, the key value is returned. */ /**********************************************************************/ int pthread_getspecific ( pthread_key_t key, pthread_addr_t *value ) { int out = 0; extern pthread_addr_t ada_pthread_getspecific( pthread_key_t *); extern void ada_pthread_keycreate( pthread_key_t, pthread_destructor_t ); if ( !ada_ptd_check_master_key_list( key ) ) { errno = ada_thd_set_errno( EINVAL ); out = -1; } else if( ada_thd_is_key_valid( key ) ) { *value = ada_pthread_getspecific( key ); } else { pthread_destructor_t destructor; *value = (pthread_destructor_t *) NULL; destructor = ada_thd_get_master_key_destructor( key ); TRY ada_pthread_keycreate( key, destructor ); CATCH ( ___ada_exceptions___[ ADA_NO_MEMORY_E ] ) errno = ada_thd_set_errno( ENOMEM ); out = -1; #ifndef NDEBUG fprintf( stderr, "No Memory: %s %d\n", __FILE__, __LINE__ ); #endif CATCH_ALL RERAISE; ENDTRY; } return out; } /**********************************************************************/ /* Creates a new thread key for the current application context. */ /* "destructor" is also registered for the key if it is present. */ /**********************************************************************/ int pthread_keycreate ( pthread_key_t *key, pthread_destructor_t destructor ) { int status = 0; extern void ada_thd_create_master_key( pthread_key_t *, pthread_destructor_t ); TRY ada_thd_create_master_key( key, destructor ); CATCH ( ___ada_exceptions___[ ADA_NO_MEMORY_E ] ) status = -1; errno = ada_thd_set_errno( ENOMEM ); #ifndef NDEBUG fprintf( stderr, "No Memory: %s %d\n", __FILE__, __LINE__ ); #endif CATCH_ALL RERAISE; ENDTRY; return ( status ); } /**********************************************************************/ /* Executes "init_routine" once. */ /**********************************************************************/ int pthread_once ( 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 ); } int pthread_setcancel ( int state ) { int ret; extern int ada_pthread_setcancel( int ); (cma__get_self_tcb() )->alert.g_enable = state == CANCEL_ON; ret = ada_pthread_setcancel( state == CANCEL_ON ? 1 : 0 ); return ( ret ? CANCEL_ON : CANCEL_OFF ); } void pthread_testcancel () { extern void ada_pthread_testcancel( void ); #ifndef NDEBUG fprintf( stderr, "--- pthread_testcancel() ---\n" ); #endif ada_pthread_testcancel(); } int pthread_setasynccancel ( int state ) { int ret; cma__t_int_tcb *tcb; extern int ada_pthread_setasynccancel( int ); ( (tcb = cma__get_self_tcb()) )->alert.a_enable = state == CANCEL_ON; ret = ada_pthread_setasynccancel( state == CANCEL_ON ? 1 : 0 ); return ( ret ? CANCEL_ON : CANCEL_OFF ); } /**********************************************************************/ /* Tries to join the current thread with the specified thread. The */ /* exit status of the target thread is returned through "status". An */ /* initial check is made to determine if the target thread is valid. */ /* If it is then a join is performed. The exit status of the target */ /* thread is returned only if "status" is valid. */ /**********************************************************************/ int pthread_join ( pthread_t thread, pthread_addr_t *status ) { pthread_addr_t exit_value = (pthread_addr_t) 0; int ret_status = 0; int exists = 0; extern pthread_addr_t ada_pthread_join( pthread_t *, int * ); if( !ada_thd_is_handle_valid( &thread, &exists ) ) { errno = ada_thd_set_errno( exists ? ESRCH : EINVAL ); } else { TRY exit_value = ada_pthread_join( &thread, &ret_status ); CATCH ( ___ada_exceptions___[ ADA_PTHREAD_CANCEL_E ] ) RERAISE; CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) ret_status = -1; errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_EDEADLK_E ] ) ret_status = -1; errno = ada_thd_set_errno( EDEADLK ); CATCH_ALL fprintf( stderr, "Unknown Exception: %s %d\n", __FILE__, __LINE__ ); ENDTRY; } if( status != (pthread_addr_t *) NULL && status != (pthread_addr_t *) 0) *status = exit_value; return ( ret_status ); } /**********************************************************************/ /* Forces the current task to yield by causing it to delay for 1 sec. */ /**********************************************************************/ void pthread_yield () { extern void ada_pthread_yield(); ada_pthread_yield(); } /**********************************************************************/ /**********************************************************************/ void pthread_exit ( pthread_addr_t status ) { extern void ada_pthread_exit( pthread_addr_t ); ada_pthread_exit( status ); } /**********************************************************************/ /* Retrieves the a pointer to the task's task record. */ /**********************************************************************/ pthread_t pthread_self () { pthread_t thread; extern char *ada_pthread_self( void ); thread.field1 = (cma_t_address *) ada_pthread_self(); return ( thread ); } /**********************************************************************/ /* Wrapper for "pthread_delay_np()". Resolution for delay is seconds.*/ /**********************************************************************/ int pthread_delay_np ( struct timespec *interval ) { extern void ada_pthread_delay_np( struct timespec * ); TRY ada_pthread_delay_np( interval ); CATCH ( ___ada_exceptions___[ ADA_PTHREAD_CANCEL_E ] ) RERAISE; ENDTRY; return ( 0 ); } /**********************************************************************/ /* Wrapper function for "pthread_create()". The function calls */ /* "ada_pthread_create()" which creates the "thread" using the Ada */ /* run-time. */ /**********************************************************************/ int pthread_create ( pthread_t *thread, pthread_attr_t attr, pthread_startroutine_t start_routine, pthread_addr_t arg ) { int status = 0; extern void ada_pthread_create( pthread_t *, pthread_attr_t *, pthread_startroutine_t, pthread_addr_t ); thread->field1 = (cma_t_address) thread; if ( !memcpy( attr, pthread_attr_default, sizeof( attr ) ) ) attr.field1 = -1; TRY ada_pthread_create( thread, &attr, start_routine, arg ); CATCH ( ___ada_exceptions___[ ADA_NO_MEMORY_E ] ) status = -1; errno = ada_thd_set_errno( ENOMEM ); #ifndef NDEBUG fprintf( stderr, "No Memory: %s %d\n", __FILE__, __LINE__ ); #endif ENDTRY; return ( status ); } /**********************************************************************/ /* Marks a thread for "detaching". When the thread is cancelled, then*/ /* all memory will be freed. */ /**********************************************************************/ int pthread_detach ( pthread_t *thread ) { int status = -1; int exists = 1; extern int ada_pthread_detach( pthread_t * ); if( !ada_thd_is_handle_valid( thread, &exists ) ) { errno = ada_thd_set_errno( exists ? ESRCH : EINVAL ); } else { TRY status = ada_pthread_detach( thread ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); ENDTRY; } return ( status ); } #ifdef pthread_equal #undef pthread_equal #endif /**********************************************************************/ /* Determines if two threads are equal. */ /**********************************************************************/ int pthread_equal ( pthread_t thread1, pthread_t thread2 ) { int status = -1; extern int ada_pthread_equal( pthread_t *, pthread_t * ); TRY status = ada_pthread_equal( &thread1, &thread2 ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); ENDTRY; return ( status ); } /**********************************************************************/ /* Cancels "thread". In order for the thread to be cancelled, it must*/ /* currently be running. Otherwise, an error is returned. */ /**********************************************************************/ int pthread_cancel ( pthread_t thread ) { int status = -1; int exists = 2; extern int ada_pthread_cancel( pthread_t * ); #ifndef NDEBUG fprintf( stderr, "--- pthread_cancel() --- \n" ); #endif if( !ada_thd_is_handle_valid( &thread, &exists ) ) { errno = ada_thd_set_errno( exists ? ESRCH : EINVAL ); } else { TRY status = ada_pthread_cancel( &thread ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_USE_ERROR_E ] ) fprintf( stderr, "General Cancel Failure\n" ); CATCH_ALL RERAISE; ENDTRY; } return ( status ); } /**********************************************************************/ /* Executes the thread entry function passed in from Ada. An exit */ /* out of the thread is performed when execution returns or if when */ /* the cancel exception is propagated out of the TRY block. */ /**********************************************************************/ pthread_addr_t ada_thd_enter_thread_routine ( func, arg ) pthread_addr_t (*func)(); char *arg; { pthread_addr_t exit_status = (pthread_addr_t) -1; extern pthread_addr_t ada_get_exit_status(); TRY exit_status = func( arg ); CATCH ( ___ada_exceptions___[ ADA_PTHREAD_CANCEL_E ] ) ; CATCH ( ___ada_exceptions___[ ADA_EXIT_THREAD_E ] ) exit_status = ada_get_exit_status(); CATCH ( ___ada_exceptions___[ ADA_USE_ERROR_E ] ) fprintf( stderr, "Caught Use Error Exception: %s %d\n", __FILE__, __LINE__ ); CATCH_ALL fprintf( stderr, "Unknown Exception: %s %d\n", __FILE__, __LINE__ ); ENDTRY; return ( exit_status ); } int pthread_mutex_init ( pthread_mutex_t *mutex, pthread_mutexattr_t attr ) { int status = 0; extern void ada_pthread_mutex_init( pthread_mutex_t *, pthread_mutexattr_t * ); mutex->field1 = (cma_t_address) mutex; if ( !memcpy( attr, pthread_mutexattr_default, sizeof( attr ) ) ) attr.field1 = -1; TRY ada_pthread_mutex_init( mutex, &attr ); CATCH ( ___ada_exceptions___[ ADA_NO_MEMORY_E ] ) status = -1; errno = ada_thd_set_errno( ENOMEM ); #ifndef NDEBUG fprintf( stderr, "No Memory: %s %d\n", __FILE__, __LINE__ ); #endif CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_cond_init ( pthread_cond_t *cond, pthread_condattr_t attr ) { int status = 0; extern void ada_pthread_cond_init( pthread_cond_t *, pthread_condattr_t *); cond->field1 = (cma_t_address) cond; if ( !memcpy( attr, pthread_condattr_default, sizeof( attr ) ) ) attr.field1 = -1; TRY ada_pthread_cond_init( cond, &attr ); CATCH ( ___ada_exceptions___[ ADA_NO_MEMORY_E ] ) status = -1; errno = ada_thd_set_errno( ENOMEM ); #ifndef NDEBUG fprintf( stderr, "No Memory: %s %d\n", __FILE__, __LINE__ ); #endif CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_cond_wait ( pthread_cond_t *cond, pthread_mutex_t *mutex ) { int status = -1; extern int ada_pthread_cond_wait( pthread_cond_t *, pthread_mutex_t * ); TRY status = ada_pthread_cond_wait( cond, mutex ); CATCH ( ___ada_exceptions___[ ADA_PTHREAD_CANCEL_E ] ) RERAISE; CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL fprintf( stderr, "Unknown Exception: %s %d\n", __FILE__, __LINE__ ); ENDTRY; return ( status ); } int pthread_cond_timedwait ( pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime ) { int status = -1; extern int ada_pthread_cond_timedwait( pthread_cond_t *, pthread_mutex_t *, struct timespec * ); TRY status = ada_pthread_cond_timedwait( cond, mutex, abstime ); CATCH ( ___ada_exceptions___[ ADA_PTHREAD_CANCEL_E ] ) RERAISE; CATCH ( ___ada_exceptions___[ ADA_TIMED_OUT_E ] ) errno = ada_thd_set_errno( EAGAIN ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL fprintf( stderr, "Unknown Exception: %s %d\n", __FILE__, __LINE__ ); ENDTRY; return ( status ); } int pthread_cond_signal ( pthread_cond_t *cond ) { int status = -1; extern int ada_pthread_cond_signal( pthread_cond_t * ); TRY status = ada_pthread_cond_signal( cond ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_cond_broadcast ( pthread_cond_t *cond ) { int status = -1; extern int ada_pthread_cond_broadcast( pthread_cond_t * ); TRY status = ada_pthread_cond_broadcast( cond ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_cond_destroy ( pthread_cond_t *cond ) { int status = -1; extern int ada_pthread_cond_destroy( pthread_cond_t *); TRY status = ada_pthread_cond_destroy( cond ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_EBUSY_E ] ) errno = ada_thd_set_errno( EBUSY ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_attr_getinheritsched ( pthread_attr_t attr ) { int status = -1; extern int ada_pthread_attr_getinheritsched( pthread_attr_t * ); TRY status = ada_pthread_attr_getinheritsched( &attr ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_attr_getprio ( pthread_attr_t attr ) { int status = -1; extern int ada_pthread_attr_getprio( pthread_attr_t * ); TRY status = ada_pthread_attr_getprio( &attr ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_attr_getsched ( pthread_attr_t attr ) { int status = -1; extern int ada_pthread_attr_getsched( pthread_attr_t * ); TRY status = ada_pthread_attr_getsched( &attr ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } long pthread_attr_getstacksize ( pthread_attr_t attr ) { int status = -1; extern int ada_pthread_attr_getstacksize( pthread_attr_t * ); TRY status = ada_pthread_attr_getstacksize( &attr ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_attr_setinheritsched ( pthread_attr_t *attr, int i ) { int status = -1; extern int ada_pthread_attr_setinheritsched( pthread_attr_t *, int ); TRY status = ada_pthread_attr_setinheritsched( attr, i ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH ( ___ada_exceptions___[ ADA_EOPNOTSUPP_E ] ) errno = ada_thd_set_errno( EOPNOTSUPP ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_getprio ( pthread_t thread ) { int status = -1; int exists; extern int ada_pthread_getprio( pthread_t * ); if( !ada_thd_is_handle_valid( &thread, &exists ) ) errno = ada_thd_set_errno( exists ? ESRCH : EINVAL ); else { TRY status = ada_pthread_getprio( &thread ); CATCH ( ___ada_exceptions___[ ADA_EOPNOTSUPP_E ] ) errno = ada_thd_set_errno( EOPNOTSUPP ); CATCH_ALL RERAISE; ENDTRY; } return ( status ); } int pthread_getscheduler ( pthread_t thread ) { int status = -1; int exists; extern int ada_pthread_getscheduler( pthread_t * ); if( !ada_thd_is_handle_valid( &thread, &exists ) ) errno = ada_thd_set_errno( exists ? ESRCH : EINVAL ); else { TRY status = ada_pthread_getscheduler( &thread ); CATCH ( ___ada_exceptions___[ ADA_EOPNOTSUPP_E ] ) errno = ada_thd_set_errno( EOPNOTSUPP ); CATCH_ALL RERAISE; ENDTRY; } return ( status ); } int pthread_setprio ( pthread_t thread, int priority ) { int status = -1; int exists; extern int ada_pthread_setprio( pthread_t *, int ); if( !ada_thd_is_handle_valid( &thread, &exists ) ) errno = ada_thd_set_errno( exists ? ESRCH : EINVAL ); else { TRY status = ada_pthread_setprio( &thread, priority ); CATCH ( ___ada_exceptions___[ ADA_EOPNOTSUPP_E ] ) errno = ada_thd_set_errno( EOPNOTSUPP ); CATCH_ALL RERAISE; ENDTRY; } return ( status ); } int pthread_setscheduler ( pthread_t thread, int scheduler, int priority ) { int status = -1; int exists; extern int ada_pthread_setscheduler( pthread_t *, int, int ); if( !ada_thd_is_handle_valid( &thread, &exists ) ) { errno = ada_thd_set_errno( exists ? ESRCH : EINVAL ); } else { TRY status = ada_pthread_setscheduler( &thread, scheduler, priority ); CATCH ( ___ada_exceptions___[ ADA_EOPNOTSUPP_E ] ) errno = ada_thd_set_errno( EOPNOTSUPP ); CATCH_ALL RERAISE; ENDTRY; } return ( status ); } int pthread_condattr_create ( pthread_condattr_t *attr ) { int status = -1; extern int ada_pthread_condattr_create( pthread_condattr_t *attr ); attr->field1 = (cma_t_address) attr; TRY status = ada_pthread_condattr_create( attr ); CATCH ( ___ada_exceptions___[ ADA_NO_MEMORY_E ] ) errno = ada_thd_set_errno( ENOMEM ); #ifndef NDEBUG fprintf( stderr, "No Memory: %s %d\n", __FILE__, __LINE__ ); #endif CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_condattr_delete ( pthread_condattr_t *attr ) { int status = -1; int ada_pthread_condattr_delete( pthread_condattr_t *attr ); TRY status = ada_pthread_condattr_delete( attr ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_mutexattr_create ( pthread_mutexattr_t *attr ) { int status = 0; extern int ada_pthread_mutexattr_create( pthread_mutexattr_t *attr ); attr->field1 = (cma_t_address) attr; TRY status = ada_pthread_mutexattr_create( attr ); CATCH ( ___ada_exceptions___[ ADA_NO_MEMORY_E ] ) status = -1; errno = ada_thd_set_errno( ENOMEM ); #ifndef NDEBUG fprintf( stderr, "No Memory: %s %d\n", __FILE__, __LINE__ ); #endif CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) status = -1; errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_mutexattr_delete ( pthread_mutexattr_t *attr ) { int status = -1; int ada_pthread_mutexattr_delete( pthread_mutexattr_t *attr ); TRY status = ada_pthread_mutexattr_delete( attr ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return ( status ); } int pthread_mutexattr_getkind_np ( pthread_mutexattr_t mutex ) { fprintf( stderr, "**** pthread_mutexattr_getkind_np() ****\n" ); return ( -1 ); } int pthread_mutexattr_setkind_np ( pthread_mutexattr_t *mutex, int k ) { int status = -1; extern ada_pthread_mutexattr_setkind_np( pthread_mutexattr_t *mutex, int ); TRY status = ada_pthread_mutexattr_setkind_np( mutex, k ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return status; } int pthread_mutexattr_disablechecks_np ( pthread_mutexattr_t *mutex ) { int status = -1; extern ada_pthread_mutexattr_disablechecks_np( pthread_mutexattr_t *mutex ); TRY status = ada_pthread_mutexattr_disablechecks_np( mutex ); CATCH ( ___ada_exceptions___[ ADA_INVALID_OBJ_E ] ) errno = ada_thd_set_errno( EINVAL ); CATCH_ALL RERAISE; ENDTRY; return status; } int pthread_get_expiration_np ( struct timespec *delta, struct timespec *abstime ) { struct timeval tmptime; struct timezone zone; struct timespec current_time; if (delta->tv_nsec >= (1000 * 1000000) || delta->tv_nsec < 0) { errno = ada_thd_set_errno( EINVAL ); return -1; } gettimeofday( &tmptime, &zone ); current_time.tv_sec = tmptime.tv_sec; current_time.tv_nsec = tmptime.tv_usec * 1000; abstime->tv_nsec = delta->tv_nsec + (current_time.tv_nsec); abstime->tv_sec = delta->tv_sec + current_time.tv_sec; if (abstime->tv_nsec >= (1000 * 1000000)) { /* check for carry */ abstime->tv_nsec -= (1000 * 1000000); abstime->tv_sec += 1; } return 0; }