예제 #1
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 );
}
예제 #2
0
static CRITICAL_SECTION *__NTGetCriticalSection( void )
{
    CRITICAL_SECTION *ptr;

    if( critsect_next < MAX_CRITICAL_SECTION ) {
        ptr = &(critsect_cache[critsect_next]);
        critsect_next++;
    } else {
        ptr = lib_calloc( 1, sizeof( *ptr ) );
        if( ptr == NULL ) {
            __fatal_runtime_error(
                "Unable to allocate semaphore data", 1 );
        }
        critsect_vector = lib_realloc( critsect_vector,
                (critsect_vectornext+1)*sizeof(CRITICAL_SECTION*));
        if( critsect_vector == NULL ) {
            __fatal_runtime_error(
                "Unable to allocate semaphore data", 1 );
        }
        critsect_vector[critsect_vectornext] = ptr;
        critsect_vectornext++;
    }
    InitializeCriticalSection( ptr );
    return( ptr );
}
예제 #3
0
void __InitFiles( void )
{
    __stream_link               *link;
    FILE                        *fp;

    fp = _RWD_iob;

    stderr->_flag &= ~(_IONBF | _IOLBF | _IOFBF);
    stderr->_flag |= _IONBF;
    for( fp = _RWD_iob; fp->_flag != 0; ++fp )
    {
        link = lib_malloc( sizeof( __stream_link ) );
        if( link == NULL )
        {
            __fatal_runtime_error(
                "Not enough memory to allocate file structures\r\n", 1 );
        }
        link->stream = fp;
        link->next = _RWD_ostream;
        _RWD_ostream = link;
        fp->_link = link;
        fp->_link->_base = NULL;
        fp->_link->_tmpfchar = 0;
        fp->_link->_orientation = _NOT_ORIENTED;
    }
    _RWD_cstream = NULL;
}
예제 #4
0
void _WCI86FAR __default_sigfpe_handler( int fpe_sig )
{
    char    msg[] = "Floating point exception (00)";

    msg[sizeof( msg ) - 4] += _bin_to_ascii_offs( fpe_sig >> 4 );
    msg[sizeof( msg ) - 3] += _bin_to_ascii_offs( fpe_sig );
    __fatal_runtime_error( msg, EXIT_FAILURE );
}
예제 #5
0
_WCRTLINK void _WCFAR *__chkstack( void _WCFAR *ptr )
/***************************************************/
{
    if( FP_SEG( ptr ) != FP_SEG( &Routine ) ) {
        __fatal_runtime_error( "thread stack not in DGROUP", 1 );
        // never return
    }
    return( ptr );
}
예제 #6
0
static void init( void )
/**********************/
{
    __lfn_rm_tb_selector = __alloc_dos_tb( TOTAL_RM_TB_SIZE_PARA, 
                                      (unsigned short *)&__lfn_rm_tb_segment );
    if( __lfn_rm_tb_selector == 0 ) {
        __fatal_runtime_error( "Unable to allocate LFN real mode transfer buffer", -1 );
    }
    *(long *)&__lfn_rm_tb_linear = TinyDPMIBase( __lfn_rm_tb_selector );
}
예제 #7
0
void __InitFiles( void )
{
#ifdef _M_I86
    __stream_link _WCI86NEAR    *ptr;
#endif
    __stream_link               *link;
    FILE                        *fp;

    fp = _RWD_iob;
#if defined( __RDOS__ ) || defined( __RDOSDEV__ )
    stdout->_flag &= ~(_IONBF | _IOLBF | _IOFBF);
    stderr->_flag &= ~(_IONBF | _IOLBF | _IOFBF);
#else
#if defined( __NETWARE__ )
    stdout->_flag &= ~(_IONBF | _IOLBF | _IOFBF);
    stdout->_flag |= _IONBF;
#endif
    stderr->_flag &= ~(_IONBF | _IOLBF | _IOFBF);
    stderr->_flag |= _IONBF;
#endif
    for( fp = _RWD_iob; fp->_flag != 0; ++fp ) {
#ifdef _M_I86
        ptr = lib_nmalloc( sizeof( __stream_link ) );
        if( ptr != NULL ) {
            link = ptr;
        } else {
#endif
            link = lib_malloc( sizeof( __stream_link ) );
            if( link == NULL ) {
                __fatal_runtime_error( "Not enough memory to allocate file structures", 1 );
                // never return
            }
#ifdef _M_I86
        }
#endif
        link->stream = fp;
        link->next = _RWD_ostream;
        _RWD_ostream = link;
        fp->_link = link;
        fp->_link->_base = NULL;
        fp->_link->_tmpfchar = 0;
        fp->_link->_orientation = _NOT_ORIENTED;
    }
    _RWD_cstream = NULL;
}
예제 #8
0
_WCRTLINK void __CloseSemaphore( semaphore_object *obj )
{
#if defined( __RUNTIME_CHECKS__ ) && defined( _M_IX86 )
    // 0 is ok
    // 1 is ok  // JBS I don't think so. I would mean a critical section is active.
                // JBS For every lock, there should be an unlock.
//    if( obj->count >= 2 ) {
//        __fatal_runtime_error( "Semaphore locked too many times", 1 );
//    }
    if( obj->count >= 1 ) {
        __fatal_runtime_error( "Semaphore not unlocked", 1 );
    }
#endif
#if !defined( __NT__ )
  #if defined( _M_I86 )
    if( obj->count > 0 ) {
        DosSemClear( &obj->semaphore );
    }
  #else
    if( obj->initialized != 0 ) {
    #if defined( __NETWARE__ )
        obj->semaphore = 0;
    #elif defined( __QNX__ )
        __qsem_destroy( &obj->semaphore );
    #elif defined( __LINUX__ )
        // TODO: Close the semaphore for Linux!
    #elif defined( __RDOS__ )
        RdosDeleteSection( obj->semaphore );
        obj->semaphore = 0;
    #elif defined( __RDOSDEV__ )
    #else
        DosCloseMutexSem( obj->semaphore );
    #endif
    }
  #endif
    obj->initialized = 0;
    obj->owner = 0;
    obj->count = 0;
#endif
}
예제 #9
0
_WCRTLINK void __ReleaseSemaphore( semaphore_object *obj )
{
    TID tid;

    tid = GetCurrentThreadId();
#if defined( _NETWARE_CLIB )
    if( tid == 0 )
        return;
#endif
    if( obj->count > 0 ) {
        if( obj->owner != tid ) {
            __fatal_runtime_error( "Semaphore unlocked by wrong owner", 1 );
        }
        if( --obj->count == 0 ) {
            obj->owner = 0;
#if defined( _M_I86 )
            DosSemClear( &obj->semaphore );
#else
  #if defined( __NETWARE__ )
            obj->semaphore = 0;
  #elif defined( __NT__ )
            LeaveCriticalSection( obj->semaphore );
  #elif defined( __QNX__ )
            __qsem_post( &obj->semaphore );
  #elif defined( __LINUX__ )
            // TODO: Relase semaphore under Linux!
  #elif defined( __RDOS__ )
            RdosLeaveSection( obj->semaphore );
  #elif defined( __RDOSDEV__ )
            RdosLeaveKernelSection( &obj->semaphore );
  #else
            DosReleaseMutexSem( obj->semaphore );
  #endif
#endif
        }
    }
}
예제 #10
0
// realloc thread data
thread_data *__ReallocThreadData( void )
{
    TID tid;
    thread_data *tdata;

    _AccessTDList();
    tid = GetCurrentThreadId();
    #ifdef __OS2__
        if( tid <= __MaxThreads ) {
            thread_data_vector *tdv;
            tdv = &(__ThreadData[tid]);
            if( tdv->allocated_entry ) 
            {
                #if defined (_NETWARE_LIBC)
                /*
                //  we don't want to lose __FirstThreadData as our global
                //  destructors will try and access it as they are called
                //  from a different thread.
                */
                if(__IsFirstThreadData(tdv->data))
                {
                    tdata = lib_realloc( tdv->data, __ThreadDataSize );
                    __RegisterFirstThreadData(tdata);
                }
                else
                #endif
                    tdata = lib_realloc( tdv->data, __ThreadDataSize );
                if( tdata == NULL ) {
                    __fatal_runtime_error( "Unable to resize thread-specific data", 1 );
                }
                tdv->data = tdata;
            } 
            else 
            {
                tdata = lib_calloc( 1, __ThreadDataSize );
                if( tdata == NULL ) {
                    __fatal_runtime_error( "Unable to resize thread-specific data", 1 );
                }
                memcpy( tdata, tdv->data, tdv->data->__data_size );
                tdv->allocated_entry = 1;
                tdv->data = tdata;
            }
        } else
    #endif
    {
        thread_data_list *tdl;

        for( tdl = __thread_data_list ; tdl != NULL ; tdl = tdl->next ) {
            if( tdl->tid == tid ) {
                break;
            }
        }
        if( tdl == NULL ) {
            __fatal_runtime_error( "Thread has no thread-specific data", 1 );
        }
        if( tdl->allocated_entry ) 
        {
            #if defined(_NETWARE_LIBC)
            if(tdata = lib_malloc( __ThreadDataSize ))
            {
                memcpy(tdata, tdl->data, min(__ThreadDataSize, tdl->data->__data_size));
                lib_free(tdl->data);
            }
            #else
            tdata = lib_realloc( tdl->data, __ThreadDataSize );
            #endif
            if( tdata == NULL ) 
            {
                __fatal_runtime_error( "Unable to resize thread-specific data", 1 );
            }
            tdl->data = tdata;
        } 
        else 
        {
            tdata = lib_calloc( 1, __ThreadDataSize );
            if( tdata == NULL ) 
            {
                __fatal_runtime_error( "Unable to resize thread-specific data", 1 );
            }
            memcpy( tdata, tdl->data, tdl->data->__data_size );
            tdl->allocated_entry = 1;
            tdl->data = tdata;
        }
    }
    tdata->__allocated = 1;
    tdata->__data_size = __ThreadDataSize;
    tdata->__resize = 0;
    #if defined(__NT__)
        TlsSetValue( __TlsIndex, tdata );
    #endif
    #if defined(_NETWARE_LIBC)
        if(0 != NXKeySetValue(__NXSlotID, tdata))
        {
            lib_free(tdata);
            tdata = NULL;
        }
    #endif
    _ReleaseTDList();
    return( tdata );
}
예제 #11
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 );
}
예제 #12
0
static void _no_support_loaded( void )
{
    __fatal_runtime_error( "Floating-point support not loaded", 1 );
}
예제 #13
0
int _OS2Main( char far *stklow, char far * stktop,
               unsigned envseg, unsigned cmdoff )
/*************************************************/
{
    cmdoff = cmdoff;    /* supress warnings */
    envseg = envseg;
    stktop = stktop;

    /* set up global variables */
#if defined(__SW_BD)
    _STACKTOP = 0;
    _curbrk = _dynend = (unsigned)&end;
    stklow = NULL;
#else
    _STACKTOP = FP_OFF( stktop );
    _curbrk = _dynend = _STACKTOP;
#endif
    DosGetHugeShift( (PUSHORT)&_HShift );
    DosGetMachineMode( (PBYTE)&_osmode );
    {
    unsigned short      version;

    DosGetVersion( (PUSHORT)&version );
    _osmajor = version >> 8;
    _osminor = version & 0xff;
    }

#if defined(__SW_BD)
    _LpPgmName = "";
    _LpCmdLine = "";
#else
    /* copy progname and arguments to bottom of stack */
    {
    char                far *src;
    char                far *pgmp;

    src = MK_FP( envseg, cmdoff );
    _LpPgmName = stklow;
    /* back up from the ao: pointer to the eo: pointer (see OS/2 2.0 docs)*/
    for( pgmp = src - 1; *--pgmp != '\0'; );
    ++pgmp;
    while( *stklow++ = *pgmp++ );
    while( *src ) ++src;
    ++src;
    _LpCmdLine = stklow;
    while( *stklow++ = *src++ );
    }
#endif

#if defined(__SW_BM)
    {
        SEL             globalseg;
        SEL             localseg;

        DosGetInfoSeg( &globalseg, &localseg );
        _threadid = MK_FP( localseg, offsetof( LINFOSEG, tidCurrent ) );
        if( __InitThreadProcessing() == NULL )
            __fatal_runtime_error( "Not enough memory", 1 );
        #if defined(__SW_BD)
        {
            unsigned    i;
            unsigned    j;
            j = __MaxThreads;
            for( i = 1; i <= j; i++ ) {
                __SetupThreadProcessing( i );
            }
        }
        #else
            __SetupThreadProcessing( 1 );
        #endif
        _STACKLOW = (unsigned)stklow;
    }
#else
    _nothread = getpid();
    _threadid = &_nothread;
    _STACKLOW = (unsigned)stklow; /* set bottom of stack */
#endif
//  {   /* removed JBS 99/11/10 */
//      // make sure the iomode array is of the proper length
//      // this needs to be done before the InitRtns
//      extern  void    __grow_iomode(int);

//      if( _osmode == OS2_MODE ) {
//          __grow_iomode( 100 );
//      }
//  }
    __InitRtns( 255 );
#ifdef __SW_BD
    {
        int status;
        status = setjmp( JmpBuff );
        if( status == 0 ) return( _CMain() );
        return( RetCode );
    }
#else
    return( _CMain() );
#endif
}
예제 #14
0
static void _no_support_loaded() {
    __fatal_runtime_error( "C++ floating-point support not loaded\r\n", 1 );
}
예제 #15
0
void _Not_Enough_Memory()
{
    __fatal_runtime_error( "Not enough memory", 1 );
}
예제 #16
0
static void _no_support_loaded( void )
{
    __fatal_runtime_error( "C++ floating-point support not loaded", 1 );
    // never return
}
예제 #17
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;
    }
}
예제 #18
0
_WCRTLINK void __AccessSemaphore( semaphore_object *obj )
{
    TID tid;

    tid = GetCurrentThreadId();
#if defined( _NETWARE_CLIB )
    if( tid == 0 )
        return;
#endif
    if( obj->owner != tid ) {
#if defined( _M_I86 )
        DosSemRequest( &obj->semaphore, -1L );
#else
  #if !defined( __NETWARE__ )
        if( obj->initialized == 0 ) {
    #if defined( __RUNTIME_CHECKS__ ) && defined( _M_IX86 )
            if( obj == &InitSemaphore ) {
                __fatal_runtime_error( "Bad semaphore lock", 1 );
            }
    #endif
            __AccessSemaphore( &InitSemaphore );
            if( obj->initialized == 0 ) {
    #if defined( __NT__ )
                obj->semaphore = __NTGetCriticalSection();
    #elif defined( __QNX__ )
                __qsem_init( &obj->semaphore, 1, 1 );
    #elif defined( __LINUX__ )
                // TODO: Access semaphore under Linux!
    #elif defined( __RDOS__ )
                obj->semaphore = RdosCreateSection();
    #elif defined( __RDOSDEV__ )
                RdosInitKernelSection(&obj->semaphore);
    #else
                DosCreateMutexSem( NULL, &obj->semaphore, 0, FALSE );
    #endif
                obj->initialized = 1;
            }
            __ReleaseSemaphore( &InitSemaphore );
        }
  #endif
  #if defined( __NETWARE__ )
        while( obj->semaphore != 0 ) {
    #if defined (_NETWARE_CLIB)
            ThreadSwitch();
    #else
            NXThreadYield();
    #endif
        }

        obj->semaphore = 1;
        obj->initialized = 1;
  #elif defined( __NT__ )
        EnterCriticalSection( obj->semaphore );
  #elif defined( __QNX__ )
        __qsem_wait( &obj->semaphore );
  #elif defined( __LINUX__ )
        // TODO: Wait for semaphore under Linux!
  #elif defined( __RDOS__ )
        RdosEnterSection( obj->semaphore );
  #elif defined( __RDOSDEV__ )
        RdosEnterKernelSection( &obj->semaphore );
  #else
        DosRequestMutexSem( obj->semaphore, SEM_INDEFINITE_WAIT );
  #endif
#endif
        obj->owner = tid;
    }
    obj->count++;
}