Changeset 1575 for trunk/src


Ignore:
Timestamp:
Oct 10, 2004, 1:14:29 PM (21 years ago)
Author:
bird
Message:

Signal changes - enabled by NEW_SIGNALS.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/src/lib/process/thread_internals.c

    • Property cvs2svn:cvs-rev changed from 1.5 to 1.6
    r1574 r1575  
    3535#include <errno.h>
    3636#include <sys/smutex.h>
     37#include <sys/builtin.h>
     38#include <sys/fmutex.h>
    3739#include <emx/umalloc.h>
    3840#include <emx/syscalls.h>
    3941#include <InnoTekLIBC/thread.h>
    4042#include <InnoTekLIBC/backend.h>
     43#include <InnoTekLIBC/signals.h>
    4144#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_THREAD
    4245#include <InnoTekLIBC/logstrict.h>
     
    5154static int              gfPreAllocThrd;
    5255
     56/** Mutex for the thread database. */
     57static _fmutex          gmtxThrdDB;
     58/** Thread database. (Protected gmtxThrdDB.) */
     59static __LIBC_PTHREAD   gpThrdDB;
     60/** Number of threads in the thread database. (Protected gmtxThrdDB.) */
     61static unsigned         gcThrdDBEntries;
     62/** Zombie thread database. (Protected gmtxThrdDB.) */
     63static __LIBC_PTHREAD   gpThrdDBZombies;
     64/** Number of threads in the zombie thread database. (Protected gmtxThrdDB.) */
     65static unsigned         gcThrdDBZombies;
     66
    5367/** Head of the thread termination callback list. */
    5468static __LIBC_PTHREADTERMCBREGREC   gpTermHead;
     
    6377 * Initialize a thread structure.
    6478 *
    65  * @param   pThrd   Pointer to the thread structure which is to be initialized.
     79 * @param   pThrd       Pointer to the thread structure which is to be initialized.
     80 * @param   pParentThrd Pointer to the thread structure for the parent thread.
     81 *                      If NULL and thread id is 1 then inherit from parent process.
     82 *                      If NULL and thread is not null or no record of parent then
     83 *                      use defaults.
    6684 */
    67 static void threadInit(__LIBC_PTHREAD pThrd)
     85static void threadInit(__LIBC_PTHREAD pThrd, const __LIBC_PTHREAD pParentThrd)
    6886{
    6987    bzero(pThrd, sizeof(*pThrd));
    7088    pThrd->iRand = 1;
    71     __libc_Back_threadInit(pThrd);
     89    pThrd->cRefs = 1;
     90    /* ASSUMES sigemptyset() is equivalent with memsetting a sigset_t. */
     91    if (pParentThrd)
     92    {
     93        /*
     94         * Gain exclusive access to the signal stuff.
     95         */
     96        int rc = __libc_back_signalSemRequest();
     97
     98        /*
     99         * Copy signal stuff.
     100         */
     101        pThrd->SigSetBlocked    = pParentThrd->SigSetBlocked;
     102        if (pParentThrd->fSigSetBlockedOld)
     103        {
     104            pThrd->SigSetBlockedOld     = pParentThrd->SigSetBlockedOld;
     105            pThrd->fSigSetBlockedOld    = pParentThrd->fSigSetBlockedOld;
     106        }
     107
     108        /*
     109         * Release semaphore.
     110         */
     111        if (!rc)
     112            __libc_back_signalSemRelease();
     113    }
     114    else
     115    {
     116        /** @todo try find info from parent process. */
     117    }
     118
     119    __libc_Back_threadInit(pThrd, pParentThrd);
     120}
     121
     122
     123void __libc_threadUse(__LIBC_PTHREAD pThrd)
     124{
     125    LIBCLOG_ENTER("pThrd=%p\n", (void *)pThrd);
     126    int     rc;
     127
     128    /*
     129     * Check that pThrd isn't already in use and set gpTLS to point at pThrd.
     130     */
     131    assert(!pThrd->pNext && !pThrd->tid && !*__libc_gpTLS);
     132    *__libc_gpTLS = pThrd;
     133
     134    /*
     135     * Set the thread id of this thread.
     136     */
     137    pThrd->tid = _gettid();
     138
     139    /*
     140     * Insert this thread into the thread database.
     141     * Note that there might be a dead thread by the same id in the database.
     142     * This have to be removed of course.
     143     */
     144    /** @todo rewrite to use a read/write semaphore, not mutex. */
     145    if (gmtxThrdDB.fs == _FMS_UNINIT)
     146        _fmutex_create(&gmtxThrdDB, 0);
     147
     148    rc = _fmutex_request(&gmtxThrdDB, 0);
     149    if (!rc)
     150    {
     151        /* Remove any zombie threads. */
     152        __LIBC_PTHREAD pPrev = NULL;
     153        __LIBC_PTHREAD p = gpThrdDB;
     154        while (p)
     155        {
     156            if (p->tid == pThrd->tid)
     157            {
     158                /* remove it and place it in the zombie list */
     159                __LIBC_PTHREAD pNext = p->pNext;
     160                if (pPrev)
     161                    pPrev->pNext = pNext;
     162                else
     163                    gpThrdDB = pNext;
     164                gcThrdDBEntries--;
     165
     166                p->pNext = gpThrdDBZombies;
     167                gpThrdDBZombies = p;
     168                gcThrdDBZombies++;
     169                p = pNext;
     170                /* paranoid as always, we continue scanning the entire list. */
     171            }
     172            else
     173            {
     174                /* next */
     175                pPrev = p;
     176                p = p->pNext;
     177            }
     178        }
     179
     180        /* Insert it */
     181        pThrd->pNext = gpThrdDB;
     182        gpThrdDB = pThrd;
     183        gcThrdDBEntries++;
     184
     185        _fmutex_release(&gmtxThrdDB);
     186    }
     187
     188    LIBCLOG_RETURN_VOID();
    72189}
    73190
     
    81198        /*
    82199         * Setup a temporary thread block on the stack so _hmalloc()
    83          * can't end up calling us recursivly if something goes wrong
     200         * can't end up calling us recursivly if something goes wrong.
    84201         */
    85202        __LIBC_THREAD   Thrd;
    86         threadInit(&Thrd);
     203        threadInit(&Thrd, NULL);
    87204        *__libc_gpTLS   = &Thrd;
    88205
     
    92209        {
    93210            pThrd = _hmalloc(sizeof(__LIBC_THREAD));
    94             assert(pThrd); /* deep, deep, depp, shit. abort the process in a controlled manner... */
     211            assert(pThrd); /* deep, deep, deep, shit. abort the process in a controlled manner... */
    95212        }
    96213        *pThrd = Thrd;
    97214
    98         *__libc_gpTLS = pThrd;
    99         LIBCLOG_MSG("Created thread block %p\n", pThrd);
     215        __libc_threadUse(pThrd);
     216        LIBCLOG_MSG("Created thread block %p\n", (void*)pThrd);
    100217    }
    101218
     
    113230    __LIBC_PTHREAD pThrd = _hmalloc(sizeof(__LIBC_THREAD));
    114231    if (pThrd)
    115         threadInit(pThrd);
     232        threadInit(pThrd, __libc_threadCurrentNoAuto());
    116233    LIBCLOG_RETURN_P(pThrd);
    117234}
    118235
    119236
    120 void  __libc_threadFree(__LIBC_PTHREAD pThrd)
    121 {
    122     LIBCLOG_ENTER("pThrd=%p\n", (void *)pThrd);
    123     /*
    124      * Clean up members.
    125      */
    126     __libc_Back_threadCleanup(pThrd);
    127 
    128     /*
    129      * Release storage.
    130      */
    131     if (pThrd != &gPreAllocThrd)
    132         free(pThrd);
    133     else
    134         __lxchg(&gfPreAllocThrd, 0);
    135     LIBCLOG_RETURN_VOID();
    136 }
    137 
     237void __libc_threadDereference(__LIBC_PTHREAD pThrd)
     238{
     239    LIBCLOG_ENTER("pThrd=%p (tid=%d)\n", (void *)pThrd, pThrd->tid);
     240    /*
     241     * Take owner ship of the DB semaphore.
     242     */
     243    _fmutex_request(&gmtxThrdDB, 0);
     244    if (pThrd->cRefs)
     245        pThrd->cRefs--;
     246    if (pThrd->cRefs)
     247    {
     248#ifdef DEBUG_LOGGING
     249        unsigned cRefs = pThrd->cRefs;
     250#endif
     251        _fmutex_release(&gmtxThrdDB);
     252        LIBCLOG_RETURN_MSG_VOID("ret void. cRefs=%d\n", cRefs);
     253    }
     254    LIBCLOG_MSG("unlinking and disposing the thread.\n");
     255
     256    /*
     257     * Thread is dead, unlink it.
     258     */
     259    if (pThrd->tid)
     260    {
     261        if (pThrd == gpThrdDB)
     262        {
     263            gpThrdDB = pThrd->pNext;
     264            gcThrdDBEntries--;
     265        }
     266        else
     267        {
     268            __LIBC_PTHREAD p;
     269            for (p = gpThrdDB; p->pNext; p = p->pNext)
     270                if (p->pNext == pThrd)
     271                {
     272                    p->pNext = pThrd->pNext;
     273                    gcThrdDBEntries--;
     274                    p = NULL;
     275                    break;
     276                }
     277
     278            /* not found? search zombie DB. */
     279            if (p)
     280            {
     281                if (gpThrdDBZombies == pThrd)
     282                {
     283                    gpThrdDBZombies = pThrd->pNext;
     284                    gcThrdDBZombies--;
     285                }
     286                else
     287                {
     288                    for (p = gpThrdDBZombies; p->pNext; p = p->pNext)
     289                        if (p->pNext == pThrd)
     290                        {
     291                            p->pNext = pThrd->pNext;
     292                            gcThrdDBZombies--;
     293                            p = NULL;
     294                            break;
     295                        }
     296                }
     297            }
     298
     299            assert(p);                      /* it must be found! */
     300            if (p)
     301                pThrd = NULL;
     302        }
     303    }
     304
     305    _fmutex_release(&gmtxThrdDB);
     306
     307
     308    /*
     309     * Dispose of the thread
     310     */
     311    if (pThrd)
     312    {
     313        /*
     314         * Clean up members.
     315         */
     316        __libc_Back_threadCleanup(pThrd);
     317
     318        /*
     319         * Clear the TLS if it's for the current thread.
     320         */
     321        if (*__libc_gpTLS == pThrd)
     322            *__libc_gpTLS = NULL;
     323
     324        /*
     325         * Release storage.
     326         */
     327        if (pThrd != &gPreAllocThrd)
     328            free(pThrd);
     329        else
     330            __lxchg(&gfPreAllocThrd, 0);
     331    }
     332
     333    LIBCLOG_RETURN_MSG_VOID("ret (gcThrdDBEntires=%d gcThrdDBZombies=%d)\n", gcThrdDBEntries, gcThrdDBZombies);
     334}
     335
     336
     337__LIBC_PTHREAD __libc_threadLookup(unsigned tid)
     338{
     339    LIBCLOG_ENTER("tid=%d\n", tid);
     340    int             rc;
     341    __LIBC_PTHREAD  pThrd;
     342
     343    /* can't search something which isn't there. */
     344    if (gmtxThrdDB.fs == _FMS_UNINIT)
     345        LIBCLOG_RETURN_P(NULL);
     346
     347    rc = _fmutex_request(&gmtxThrdDB, 0);
     348    if (rc)
     349        LIBCLOG_RETURN_MSG(NULL, "ret NULL (fmutex f**ked. rc=%d)\n", rc);
     350
     351    for (pThrd = gpThrdDB; pThrd; pThrd = pThrd->pNext)
     352        if (pThrd->tid == tid)
     353        {
     354            pThrd->cRefs++;
     355            break;
     356        }
     357
     358    _fmutex_release(&gmtxThrdDB);
     359
     360    LIBCLOG_RETURN_P(pThrd);
     361}
     362
     363
     364__LIBC_PTHREAD __libc_threadLookup2(int (pfnCallback)(__LIBC_PTHREAD pCur, __LIBC_PTHREAD pBest, void *pvParam), void *pvParam)
     365{
     366    LIBCLOG_ENTER("pfnCallback=%p pvParam=%p\n", (void *)pfnCallback, pvParam);
     367    int             rc;
     368    __LIBC_PTHREAD  pThrd;
     369    __LIBC_PTHREAD  pBest = NULL;
     370
     371    /* can't search something which isn't there. */
     372    if (gmtxThrdDB.fs == _FMS_UNINIT)
     373        LIBCLOG_RETURN_P(NULL);
     374
     375    rc = _fmutex_request(&gmtxThrdDB, 0);
     376    if (rc)
     377        LIBCLOG_RETURN_MSG(NULL, "ret NULL (fmutex f**ked. rc=%d)\n", rc);
     378
     379    for (pThrd = gpThrdDB; pThrd; pThrd = pThrd->pNext)
     380    {
     381        rc = pfnCallback(pThrd, pBest, pvParam);
     382        if (rc == 0)
     383            continue;
     384        else if (rc == 1)
     385        {
     386            pBest = pThrd;
     387            continue;
     388        }
     389        else if (rc == 2)
     390        {
     391            pBest = pThrd;
     392            break;
     393        }
     394        else if (rc == -1)
     395            break;
     396        else
     397        {
     398            LIBC_ASSERTM_FAILED("Callback returned %d, allowed values are 2, 1, 0 and -1!\n", rc);
     399            break;
     400        }
     401    }
     402
     403    if (pBest)
     404        pBest->cRefs++;
     405
     406    _fmutex_release(&gmtxThrdDB);
     407
     408    LIBCLOG_RETURN_MSG(pBest, "ret %p (tid=%d)\n", (void *)pBest, pBest ? pBest->tid : 0);
     409}
     410
     411
     412
     413int         __libc_threadEnum(int (pfnCallback)(__LIBC_PTHREAD pCur, void *pvParam), void *pvParam)
     414{
     415    LIBCLOG_ENTER("pfnCallback=%p pvParam=%p\n", (void *)pfnCallback, pvParam);
     416    int             rc;
     417    __LIBC_PTHREAD  pThrd;
     418
     419    /* can't search something which isn't there. */
     420    if (gmtxThrdDB.fs == _FMS_UNINIT)
     421        LIBCLOG_RETURN_P(NULL);
     422
     423    rc = _fmutex_request(&gmtxThrdDB, 0);
     424    if (rc)
     425        LIBCLOG_RETURN_MSG(NULL, "ret NULL (fmutex f**ked. rc=%d)\n", rc);
     426
     427    for (pThrd = gpThrdDB; pThrd; pThrd = pThrd->pNext)
     428    {
     429        rc = pfnCallback(pThrd, pvParam);
     430        if (rc == 0)
     431            continue;
     432        else if (rc == -1)
     433            break;
     434        else
     435        {
     436            LIBC_ASSERTM_FAILED("Callback returned %d, allowed values are 0 and -1!\n", rc);
     437            break;
     438        }
     439    }
     440
     441    _fmutex_release(&gmtxThrdDB);
     442
     443    LIBCLOG_RETURN_INT(rc);
     444}
    138445
    139446int     __libc_ThreadRegisterTermCallback(__LIBC_PTHREADTERMCBREGREC pRegRec)
     
    151458        ||  pRegRec->fFlags)
    152459    {
    153         LIBC_ASSERTM(!pRegRec->pNext, "pNext must be NULL not %p\n", pRegRec->pNext);
     460        LIBC_ASSERTM(!pRegRec->pNext, "pNext must be NULL not %p\n", (void * )pRegRec->pNext);
    154461        LIBC_ASSERTM(pRegRec->pfnCallback, "pfnCallback not be NULL\n");
    155462        LIBC_ASSERTM(!pRegRec->fFlags, "fFlags must be ZERO not %u\n", pRegRec->fFlags);
     
    175482    {
    176483        _smutex_release(&gsmtxTerm);
    177         LIBC_ASSERTM_FAILED("Double registration of %p\n", pRegRec);
     484        LIBC_ASSERTM_FAILED("Double registration of %p\n", (void *)pRegRec);
    178485        LIBCLOG_RETURN_INT(-1);
    179486    }
     
    201508    {
    202509        /* call it */
    203         LIBCLOG_MSG("calling %p with %p\n", pCur->pfnCallback, pCur);
     510        LIBCLOG_MSG("calling %p with %p\n", (void *)pCur->pfnCallback, (void *)pCur);
    204511        pCur->pfnCallback(pCur, fFlags);
    205512
Note: See TracChangeset for help on using the changeset viewer.