Changeset 2699 for branches


Ignore:
Timestamp:
May 28, 2006, 11:26:36 PM (19 years ago)
Author:
bird
Message:

Fixes #109. This also fixes a bug in the ghtread_once implementation where any racing thread didn't stop and wait.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/libc-0.6/src/gcc/gcc/gthr-os2.h

    r1404 r2699  
    4444#include <errno.h>
    4545#include <InnoTekLIBC/thread.h>
     46#include <InnoTekLIBC/backend.h>
    4647
    4748typedef int __gthread_key_t;
    48 typedef volatile signed char __gthread_once_t;
     49typedef struct
     50{
     51  signed char volatile done;
     52  signed char volatile started;
     53} __gthread_once_t;
    4954typedef _fmutex __gthread_mutex_t;
    5055
    51 #define __GTHREAD_ONCE_INIT             0
     56#define __GTHREAD_ONCE_INIT             { 0, 0 }
    5257#define __GTHREAD_MUTEX_INIT_FUNCTION   __gthread_mutex_init_function
    5358
     
    6368  if (once == NULL || func == NULL)
    6469      return EINVAL;
    65   if (__cxchg (once, 1) == 0)
    66     func ();
     70  if (__cxchg (&once->started, 1) == 0)
     71    {
     72      func ();
     73      __cxchg (&once->done, 1);
     74    }
     75  else if (!once->done)
     76    {
     77      unsigned outer = 0;
     78      do
     79        {
     80          int i = 4096;
     81          while (i-- > 0 && !once->done)
     82            __libc_Back_threadSleep(0, NULL);
     83          if (once->done)
     84            break;
     85          __libc_Back_threadSleep(++outer % 32, NULL);
     86        }
     87      while (!once->done);
     88    }
    6789  return 0;
    6890}
     
    95117__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
    96118{
    97     int iTLS = __libc_TLSAlloc();
    98     if (iTLS < 0)
    99         return errno;
    100     __libc_TLSDestructor(iTLS, (void (*)(void *, int, unsigned))dtor, 0);
    101     *key = iTLS;
    102     return 0;
     119  int iTLS = __libc_TLSAlloc ();
     120  if (iTLS < 0)
     121    return errno;
     122  __libc_TLSDestructor (iTLS, (void (*)(void *, int, unsigned))dtor, 0);
     123  *key = iTLS;
     124  return 0;
    103125}
    104126
     
    106128__gthread_key_dtor (__gthread_key_t key, void *ptr)
    107129{
    108     void (*pfnDestructor)(void *pvValue, int iTLSIndex, unsigned fFlags) = __libc_TLSGetDestructor(key, NULL);
    109     if (pfnDestructor)
    110     {
    111         pfnDestructor(ptr, key, 0);
    112         __libc_TLSSet(key, NULL);
    113     }
    114     return 0;
     130  if (__libc_TLSSet (key, NULL))
     131    return errno;
     132  return 0;
    115133}
    116134
     
    118136__gthread_key_delete (__gthread_key_t key)
    119137{
    120     if (__libc_TLSFree(key))
    121         return errno;
    122     return 0;
     138  if (__libc_TLSFree (key))
     139    return errno;
     140  return 0;
    123141}
    124142
     
    126144__gthread_getspecific (__gthread_key_t key)
    127145{
    128     return __libc_TLSGet(key);
     146  return __libc_TLSGet (key);
    129147}
    130148
     
    132150__gthread_setspecific (__gthread_key_t key, const void *ptr)
    133151{
    134     if (__libc_TLSSet(key, (void *)ptr))
    135         return errno;
    136     return 0;
     152  if (__libc_TLSSet (key, (void *)ptr))
     153    return errno;
     154  return 0;
    137155}
    138156
Note: See TracChangeset for help on using the changeset viewer.