Beispiel #1
0
// add to list of thread data
int __AddThreadData( TID tid, thread_data *tdata )
{
    int             retn = 1;
    thread_data_list *tdl;

    _AccessTDList();
    tdl = lib_calloc( 1, sizeof( *tdl ) );
    if( tdl != NULL ) 
    {
        /*
        //  Thin doesn't need to call __initthread
        */
#if !defined(_THIN_LIB)
        if( __initthread( tdata ) ) 
        {
            lib_free( tdl );
            retn = 0;
        } 
        else 
#endif
        {
            tdl->data = tdata;
            tdl->tid = tid;
            tdl->allocated_entry = tdata->__allocated;
            tdl->next = __thread_data_list;
            __thread_data_list = tdl;
        }
    } 
    else 
    {
        retn = 0;
    }
    _ReleaseTDList();
    return( retn );
}
Beispiel #2
0
extern int *__threadid( void )
{
    void *netid;
    int   id;

    netid = GetThreadID();
    id = gettid( netid );
    if( netid != NULL && id == 0 ) { // handle stray threads
        id = gettid( NULL );
        if( id != 0 ) {
            void *ptr;
            __ThreadIDs[ id ] = netid;
            ptr = lib_calloc( 1, __ThreadDataSize );
            if( ptr == NULL ) {
                __fatal_runtime_error(
                    "Unable to allocate thread-specific data", 1 );
            }
            __ThreadData[ id ].data = ptr;
            __ThreadData[ id ].allocated_entry = 1;
            __ThreadData[ id ].data->__allocated = 1;
            __ThreadData[ id ].data->__randnext = 1;
            __ThreadData[ id ].data->__data_size = __ThreadDataSize;
            if( __initthread( ptr ) ) {
                lib_free( ptr );
                __fatal_runtime_error(
                    "Unable to initialize thread-specific data", 1 );
            }
        }
    }
    CurrThrdID = id;
    return( &CurrThrdID );
}
Beispiel #3
0
int __OS2AddThread( TID tid, thread_data *tdata )
/***********************************************/
{
    tdata = __AllocInitThreadData( tdata );
    if( tdata == NULL ) return( 0 );
    if( tid <= __MaxThreads ) {
        if( __initthread( tdata ) ) {
            __FreeInitThreadData( tdata );
            return( 0 );
        } else {
            __ThreadData[tid].data = tdata;
            __ThreadData[tid].allocated_entry = tdata->__allocated;
        }
    } else {
        if( !__AddThreadData( tid, tdata ) ) {
            // unable to setup storage
            __FreeInitThreadData( tdata );
            return( 0 );
        }
    }
    return( 1 );
}
Beispiel #4
0
// lookup thread data
thread_data *__GetThreadData( void )
{
    thread_data *tdata = NULL;
    #ifdef __OS2__
        TID             tid;
        tid = GetCurrentThreadId();
        if( tid <= __MaxThreads ) {
            tdata = __AllocInitThreadData( tdata );
            if( tdata != NULL ) {
                if( __initthread( tdata ) ) {
                    __FreeInitThreadData( tdata );
                    tdata = NULL;
                } else {
                    __ThreadData[tid].data = tdata;
                    __ThreadData[tid].allocated_entry = tdata->__allocated;
                }
            }
        } else {
            thread_data_list *tdl;
            thread_data_list **pprev;

            _AccessTDList();
            tdata = NULL;
            pprev = &__thread_data_list;
            for( tdl = *pprev; tdl != NULL ; tdl = tdl->next ) {
                if( tdl->tid == tid ) {
                    tdata = tdl->data;
                    break;
                }
                pprev = &(tdl->next);
            }
            if( tdata == NULL ) {
                tdata = __AllocInitThreadData( tdata );
                if( tdata != NULL ) {
                    if( !__AddThreadData( tid, tdata ) ) {
                        __FreeInitThreadData( tdata );
                        tdata = NULL;
                    }
                }
            } else if( *pprev ) {
                // promote to front
                *pprev = tdl->next;
                tdl->next = __thread_data_list;
                __thread_data_list = tdl;
                // check for need to resize thread data
                if( tdata->__resize ) {
                    tdata = __ReallocThreadData();
                }
            }
            _ReleaseTDList();
        }
    #elif defined(__NT__)
        if( __NTAddThread( tdata ) ) 
        {
            tdata = (thread_data *)TlsGetValue( __TlsIndex );
        }
    #elif defined(_NETWARE_LIBC)
        if( __LibCAddThread( tdata ) )
        {
            if(0 != NXKeyGetValue(__NXSlotID, (void **) &tdata))
                tdata = NULL;
        }
    #elif defined(__RDOS__)
        if( __RdosAddThread( tdata ) ) 
        {
            tdata = (thread_data *)__tls_get_value( __TlsIndex );
        }
    #endif
    if( tdata == NULL ) {
        __fatal_runtime_error( "Thread has no thread-specific data", 1 );
    }
    return( tdata );
}
Beispiel #5
0
void __InitMultipleThread( void )
/*******************************/
{
    if( __GetThreadPtr != __MultipleThread ) {
  #if defined( _NETWARE_CLIB )
        {
        /* __ThreadData[ 0 ] is used whenever GetThreadID() returns a pointer
           not in our __ThreadIDs list - ie. whenever it returns NULL, a
           pointer to a thread we didn't create, or an invalid pointer */
            void *ptr;
            ptr = lib_calloc( 1, __ThreadDataSize );
            if( ptr == NULL ) {
                __fatal_runtime_error(
                    "Unable to allocate thread-specific data", 1 );
            }
            __ThreadData[ 0 ].data = ptr;
            __ThreadData[ 0 ].allocated_entry = 1;
            __ThreadData[ 0 ].data->__allocated = 1;
            __ThreadData[ 0 ].data->__randnext = 1;
            __ThreadData[ 0 ].data->__data_size = __ThreadDataSize;
            if( __initthread( ptr ) ) {
                lib_free( ptr );
                __fatal_runtime_error(
                    "Unable to initialize thread-specific data", 1 );
            }
            ptr = lib_calloc( 1, __ThreadDataSize );
            if( ptr == NULL ) {
                __fatal_runtime_error(
                    "Unable to allocate thread-specific data", 1 );
            }
            __FirstThreadData = ptr;
            __FirstThreadData->__allocated = 1;
            __FirstThreadData->__randnext = 1;
            __FirstThreadData->__data_size = __ThreadDataSize;
            __ThreadData[ 1 ].data = __FirstThreadData;
            __ThreadData[ 1 ].allocated_entry = __FirstThreadData->__allocated;
            __ThreadIDs[ 1 ] = GetThreadID();
            if( __initthread( ptr ) ) {
                lib_free( ptr );
                __fatal_runtime_error(
                    "Unable to initialize thread-specific data", 1 );
            }
        }
  #elif defined( _NETWARE_LIBC )
        InitSemaphore.semaphore     = 0;    /* sema4 is mutex in this case */
        InitSemaphore.initialized   = 1;
        //_ThreadExitRtn = &__ThreadExit;   - might need this at some point??
        // Note: __AddThreadData uses the InitSemaphore, _AccessTDList & _ReleaseTDList

        __FirstThreadData->thread_id = GetCurrentThreadId();

        __AddThreadData( __FirstThreadData->thread_id, __FirstThreadData );
        if(0 != NXKeySetValue(__NXSlotID, __FirstThreadData)) {
            __fatal_runtime_error(
                "Unable to initialize thread-specific data", 1 );
        }
  #elif defined( __NT__ )
        InitSemaphore.semaphore = __NTGetCriticalSection();
        InitSemaphore.initialized = 1;
        _ThreadExitRtn = &__ThreadExit;
        // Note: __AddThreadData uses the InitSemaphore, _AccessTDList & _ReleaseTDList
        __AddThreadData( __FirstThreadData->thread_id, __FirstThreadData );
        TlsSetValue( __TlsIndex, __FirstThreadData );
  #elif defined( __QNX__ )
        __qsem_init( &InitSemaphore.semaphore, 1, 1 );
        InitSemaphore.initialized = 1;
        // first thread data already in magic memory
  #elif defined( __LINUX__ )
        // TODO: Init semaphores for Linux
  #elif defined( __RDOS__ )
        InitSemaphore.semaphore = RdosCreateSection();
        InitSemaphore.initialized = 1;
        __AddThreadData( __FirstThreadData->thread_id, __FirstThreadData );
        __tls_set_value( __TlsIndex, __FirstThreadData );
  #elif defined( __RDOSDEV__ )
        RdosInitKernelSection( &InitSemaphore.semaphore );
        InitSemaphore.initialized = 1;
  #elif defined( __OS2__ )
        DosCreateMutexSem( NULL, &InitSemaphore.semaphore, 0, FALSE );
        InitSemaphore.initialized = 1;
        __ThreadData[1].data = __FirstThreadData;
        __ThreadData[1].allocated_entry = __FirstThreadData->__allocated;
  #else
    #error Multiple thread support is not defined for this platform
  #endif

  #if !defined( _M_I86 )
    // Set these up after we have created the InitSemaphore
    #if !defined (_THIN_LIB)
        _AccessFileH      = &__AccessFileH;
        _ReleaseFileH     = &__ReleaseFileH;
        _AccessIOB        = &__AccessIOB;
        _ReleaseIOB       = &__ReleaseIOB;
    #endif
        _AccessTDList     = &__AccessTDList;
        _ReleaseTDList    = &__ReleaseTDList;
        __AccessSema4     = &__AccessSemaphore;
        __ReleaseSema4    = &__ReleaseSemaphore;
        __CloseSema4      = &__CloseSemaphore;
    #if !defined( __NETWARE__ )
        _AccessNHeap  = &__AccessNHeap;
        _AccessFHeap  = &__AccessFHeap;
        _ReleaseNHeap = &__ReleaseNHeap;
        _ReleaseFHeap = &__ReleaseFHeap;
    #endif
    #if defined( __NT__ )
        _AccessFList  = &__AccessFList;
        _ReleaseFList = &__ReleaseFList;
    #endif
  #endif
        __GetThreadPtr  = __MultipleThread;
    }
}