Annotation of sbbs/src/xpdev/threadwrap.c, revision 1.1.1.2

1.1       root        1: /* threadwrap.c */
                      2: 
                      3: /* Thread-related cross-platform development wrappers */
                      4: 
1.1.1.2 ! root        5: /* $Id: threadwrap.c,v 1.31 2011/09/09 08:06:15 rswindell Exp $ */
1.1       root        6: 
                      7: /****************************************************************************
                      8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                     10:  *                                                                                                                                                     *
1.1.1.2 ! root       11:  * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html         *
1.1       root       12:  *                                                                                                                                                     *
                     13:  * This library is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU Lesser General Public License          *
                     15:  * as published by the Free Software Foundation; either version 2                      *
                     16:  * of the License, or (at your option) any later version.                                      *
                     17:  * See the GNU Lesser General Public License for more details: lgpl.txt or     *
                     18:  * http://www.fsf.org/copyleft/lesser.html                                                                     *
                     19:  *                                                                                                                                                     *
                     20:  * Anonymous FTP access to the most recent released source is available at     *
                     21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     22:  *                                                                                                                                                     *
                     23:  * Anonymous CVS access to the development source and modification history     *
                     24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     26:  *     (just hit return, no password is necessary)                                                     *
                     27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     28:  *                                                                                                                                                     *
                     29:  * For Synchronet coding style and modification guidelines, see                                *
                     30:  * http://www.synchro.net/source.html                                                                          *
                     31:  *                                                                                                                                                     *
                     32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     33:  * format) via e-mail to [email protected]                                                                      *
                     34:  *                                                                                                                                                     *
                     35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     36:  ****************************************************************************/
                     37: 
                     38: #if defined(__unix__)
                     39:        #include <unistd.h>     /* _POSIX_THREADS */
                     40:        #include <sys/param.h>  /* BSD */
                     41: #endif
                     42: 
                     43: #if defined(_WIN32) && !defined(_WIN32_WINNT)
                     44:        #define _WIN32_WINNT 0x0400     /* Needed for TryEnterCriticalSection */
                     45: #endif
                     46: 
                     47: #include "threadwrap.h"        /* DLLCALL */
                     48: 
                     49: /****************************************************************************/
                     50: /* Wrapper for Win32 create/begin thread function                                                      */
                     51: /* Uses POSIX threads                                                                                                          */
                     52: /****************************************************************************/
                     53: #if defined(__unix__)
                     54: #if defined(_POSIX_THREADS)
                     55: ulong _beginthread(void( *start_address )( void * )
                     56:                ,unsigned stack_size, void *arglist)
                     57: {
                     58:        pthread_t       thread;
                     59:        pthread_attr_t attr;
                     60:        size_t          default_stack;
                     61: 
1.1.1.2 ! root       62:        (void)stack_size;
        !            63: 
1.1       root       64:        pthread_attr_init(&attr);     /* initialize attribute structure */
                     65: 
                     66:        /* set thread attributes to PTHREAD_CREATE_DETACHED which will ensure
                     67:           that thread resources are freed on exit() */
                     68:        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
                     69: 
                     70:        /* Default stack size in BSD is too small for JS stuff */
                     71:        /* Force to at least 256k */
                     72: #define XPDEV_MIN_THREAD_STACK_SIZE    (256*1024)
1.1.1.2 ! root       73:        if(stack_size==0 && pthread_attr_getstacksize(&attr, &default_stack)==0 
        !            74:                        && default_stack < XPDEV_MIN_THREAD_STACK_SIZE)
1.1       root       75:                stack_size=XPDEV_MIN_THREAD_STACK_SIZE;
                     76: 
                     77:        if(stack_size!=0)
                     78:                pthread_attr_setstacksize(&attr, stack_size);
                     79: 
                     80:        if(pthread_create(&thread
                     81: #if defined(__BORLANDC__) /* a (hopefully temporary) work-around */
1.1.1.2 ! root       82:                        ,NULL
1.1       root       83: #else
1.1.1.2 ! root       84:                        ,&attr  /* default attributes */
1.1       root       85: #endif
1.1.1.2 ! root       86:                        /* POSIX defines this arg as "void *(*start_address)" */
        !            87:                        ,(void * (*)(void *)) start_address
        !            88:                        ,arglist)==0) {
        !            89:                pthread_attr_destroy(&attr);
        !            90:                return((ulong) thread /* thread handle */);
        !            91:        }
1.1       root       92: 
1.1.1.2 ! root       93:        pthread_attr_destroy(&attr);
1.1       root       94:        return(-1);     /* error */
                     95: }
                     96: #else
                     97: 
                     98: #error "Need _beginthread implementation for non-POSIX thread library."
                     99: 
                    100: #endif
                    101: 
                    102: #endif /* __unix__ */
                    103: 
                    104: /****************************************************************************/
                    105: /* Wrappers for POSIX thread (pthread) mutexes                                                         */
                    106: /****************************************************************************/
1.1.1.2 ! root      107: pthread_mutex_t pthread_mutex_initializer_np(BOOL recursive)
1.1       root      108: {
                    109:        pthread_mutex_t mutex;
1.1.1.2 ! root      110: #if defined(_POSIX_THREADS)
        !           111:        pthread_mutexattr_t attr;
        !           112:        pthread_mutexattr_init(&attr);
        !           113:        if(recursive)
        !           114: #if defined(__linux__) && !defined(__USE_UNIX98)
        !           115:                pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE_NP);
        !           116: #else
        !           117:                pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
        !           118: #endif
        !           119:        pthread_mutex_init(&mutex, &attr);
        !           120: #else  /* Assumes recursive (e.g. Windows) */
        !           121:        (void)recursive;
1.1       root      122:        pthread_mutex_init(&mutex,NULL);
1.1.1.2 ! root      123: #endif
1.1       root      124:        return(mutex);
                    125: }
                    126: 
                    127: #if !defined(_POSIX_THREADS)
                    128: 
                    129: int pthread_mutex_init(pthread_mutex_t* mutex, void* attr)
                    130: {
1.1.1.2 ! root      131:        (void)attr;
1.1       root      132: #if defined(PTHREAD_MUTEX_AS_WIN32_MUTEX)
                    133:        return ((((*mutex)=CreateMutex(/* security */NULL, /* owned */FALSE, /* name */NULL))==NULL) ? -1 : 0);
                    134: #elif defined(_WIN32)  /* Win32 Critical Section */
                    135:        InitializeCriticalSection(mutex);
                    136:        return 0;       /* No error */
                    137: #elif defined(__OS2__)
                    138:        return DosCreateMutexSem(/* name */NULL, mutex, /* attr */0, /* owned */0);
                    139: #endif
                    140: }
                    141: 
                    142: int pthread_mutex_lock(pthread_mutex_t* mutex)
                    143: {
                    144: #if defined(PTHREAD_MUTEX_AS_WIN32_MUTEX)
                    145:        return (WaitForSingleObject(*mutex, INFINITE)==WAIT_OBJECT_0 ? 0 : EBUSY);
                    146: #elif defined(_WIN32)  /* Win32 Critical Section */
                    147:        EnterCriticalSection(mutex);
                    148:        return 0;       /* No error */
                    149: #elif defined(__OS2__)
                    150:        return DosRequestMutexSem(*mutex, -1 /* SEM_INDEFINITE_WAIT */);
                    151: #endif
                    152: }
                    153: 
                    154: int pthread_mutex_trylock(pthread_mutex_t* mutex)
                    155: {
                    156: #if defined(PTHREAD_MUTEX_AS_WIN32_MUTEX)
                    157:        return (WaitForSingleObject(*mutex, 0)==WAIT_OBJECT_0 ? 0 : EBUSY);
                    158: #elif defined(_WIN32)  /* Win32 Critical Section */
                    159:        /* TryEnterCriticalSection only available on NT4+ :-( */
                    160:        return (TryEnterCriticalSection(mutex) ? 0 : EBUSY);
                    161: #elif defined(__OS2__)
                    162:        return DosRequestMutexSem(*mutex, 0 /* SEM_IMMEDIATE_RETURN */);
                    163: #endif
                    164: }
                    165: 
                    166: int pthread_mutex_unlock(pthread_mutex_t* mutex)
                    167: {
                    168: #if defined(PTHREAD_MUTEX_AS_WIN32_MUTEX)
                    169:        return (ReleaseMutex(*mutex) ? 0 : GetLastError());
                    170: #elif defined(_WIN32)  /* Win32 Critical Section */
                    171:        LeaveCriticalSection(mutex);
                    172:        return 0;       /* No error */
                    173: #elif defined(__OS2__)
                    174:        return DosReleaseMutexSem(*mutex);
                    175: #endif
                    176: }
                    177: 
                    178: int pthread_mutex_destroy(pthread_mutex_t* mutex)
                    179: {
                    180: #if defined(PTHREAD_MUTEX_AS_WIN32_MUTEX)
                    181:        return (CloseHandle(*mutex) ? 0 : GetLastError());
                    182: #elif defined(_WIN32)  /* Win32 Critical Section */
                    183:        DeleteCriticalSection(mutex);
                    184:        return 0;       /* No error */
                    185: #elif defined(__OS2__)
                    186:        return DosCloseMutexSem(*mutex);
                    187: #endif
                    188: }
                    189: 
                    190: #endif /* POSIX thread mutexes */
1.1.1.2 ! root      191: 
        !           192: /************************************************************************/
        !           193: /* Protected (thread-safe) Integers (e.g. atomic/interlocked variables) */
        !           194: /************************************************************************/
        !           195: 
        !           196: int    protected_int32_init(protected_int32_t* prot, int32_t value)
        !           197: {
        !           198:        prot->value = value;
        !           199:        return pthread_mutex_init(&prot->mutex,NULL);
        !           200: }
        !           201: 
        !           202: int    protected_int64_init(protected_int64_t* prot, int64_t value)
        !           203: {
        !           204:        prot->value = value;
        !           205:        return pthread_mutex_init(&prot->mutex,NULL);
        !           206: }
        !           207: 
        !           208: int32_t protected_int32_adjust(protected_int32_t* i, int32_t adjustment)
        !           209: {
        !           210:        int32_t newval;
        !           211:        pthread_mutex_lock(&i->mutex);
        !           212:        newval = i->value += adjustment;
        !           213:        pthread_mutex_unlock(&i->mutex);
        !           214:        return newval;
        !           215: }
        !           216: 
        !           217: uint32_t protected_uint32_adjust(protected_uint32_t* i, int32_t adjustment)
        !           218: {
        !           219:        uint32_t newval;
        !           220:        pthread_mutex_lock(&i->mutex);
        !           221:        newval = i->value += adjustment;
        !           222:        pthread_mutex_unlock(&i->mutex);
        !           223:        return newval;
        !           224: }
        !           225: 
        !           226: int64_t protected_int64_adjust(protected_int64_t* i, int64_t adjustment)
        !           227: {
        !           228:        int64_t newval;
        !           229:        pthread_mutex_lock(&i->mutex);
        !           230:        newval = i->value += adjustment;
        !           231:        pthread_mutex_unlock(&i->mutex);
        !           232:        return newval;
        !           233: }
        !           234: 
        !           235: uint64_t protected_uint64_adjust(protected_uint64_t* i, int64_t adjustment)
        !           236: {
        !           237:        uint64_t newval;
        !           238:        pthread_mutex_lock(&i->mutex);
        !           239:        newval = i->value += adjustment;
        !           240:        pthread_mutex_unlock(&i->mutex);
        !           241:        return newval;
        !           242: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.