⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gthr-default.h

📁 mingw32.rar
💻 H
📖 第 1 页 / 共 2 页
字号:
/* Wake up all threads waiting on this condition.  */
int
__gthread_objc_condition_broadcast (objc_condition_t condition)
{
  /* Unimplemented.  */
  return -1;
}

/* Wake up one thread waiting on this condition.  */
int
__gthread_objc_condition_signal (objc_condition_t condition)
{
  /* Unimplemented.  */
  return -1;
}

#else /* _LIBOBJC */

#ifdef __cplusplus
extern "C" {
#endif

typedef unsigned long __gthread_key_t;

typedef struct {
  int done;
  long started;
} __gthread_once_t;

typedef struct {
  long counter;
  void *sema;
} __gthread_mutex_t;

#define __GTHREAD_ONCE_INIT {0, -1}
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
#define __GTHREAD_MUTEX_INIT_DEFAULT {-1, 0}

#if __MINGW32_MAJOR_VERSION >= 1 || \
  (__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2)
#define MINGW32_SUPPORTS_MT_EH 1
/* Mingw runtime >= v0.3 provides a magic variable that is set to nonzero
   if -mthreads option was specified, or 0 otherwise. This is to get around
   the lack of weak symbols in PE-COFF.  */
extern int _CRT_MT;
extern int __mingwthr_key_dtor (unsigned long, void (*) (void *));
#endif /* __MINGW32__ version */

#ifdef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES

static inline long
__gthr_i486_lock_cmp_xchg(long *dest, long xchg, long comperand)
{
  long result;
  __asm__ __volatile__ ("\n\
	lock\n\
	cmpxchg{l} {%4, %1|%1, %4}\n"
	: "=a" (result), "=m" (*dest)
	: "0" (comperand), "m" (*dest), "r" (xchg)
	: "cc");
  return result;
}

#define __GTHR_W32_InterlockedCompareExchange __gthr_i486_lock_cmp_xchg

#else  /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */

#define __GTHR_W32_InterlockedCompareExchange InterlockedCompareExchange

#endif /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */

static inline int
__gthread_active_p (void)
{
#ifdef MINGW32_SUPPORTS_MT_EH
  return _CRT_MT;
#else
  return 1;
#endif
}

#if __GTHREAD_HIDE_WIN32API

/* The implementations are in config/i386/gthr-win32.c in libgcc.a.
   Only stubs are exposed to avoid polluting the C++ namespace with
   windows api definitions.  */

extern int __gthr_win32_once (__gthread_once_t *, void (*) (void));
extern int __gthr_win32_key_create (__gthread_key_t *, void (*) (void*));
extern int __gthr_win32_key_delete (__gthread_key_t);
extern void * __gthr_win32_getspecific (__gthread_key_t);
extern int __gthr_win32_setspecific (__gthread_key_t, const void *);
extern void __gthr_win32_mutex_init_function (__gthread_mutex_t *);
extern int __gthr_win32_mutex_lock (__gthread_mutex_t *);
extern int __gthr_win32_mutex_trylock (__gthread_mutex_t *);
extern int __gthr_win32_mutex_unlock (__gthread_mutex_t *);

static inline int
__gthread_once (__gthread_once_t *once, void (*func) (void))
{
  if (__gthread_active_p ())
    return __gthr_win32_once (once, func);
  else
    return -1;
}

static inline int
__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
{
  return __gthr_win32_key_create (key, dtor);
}

static inline int
__gthread_key_delete (__gthread_key_t key)
{
  return __gthr_win32_key_delete (key);
}

static inline void *
__gthread_getspecific (__gthread_key_t key)
{
  return __gthr_win32_getspecific (key);
}

static inline int
__gthread_setspecific (__gthread_key_t key, const void *ptr)
{
  return __gthr_win32_setspecific (key, ptr);
}

static inline void
__gthread_mutex_init_function (__gthread_mutex_t *mutex)
{
  __gthr_win32_mutex_init_function (mutex);
}

static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
  if (__gthread_active_p ())
    return __gthr_win32_mutex_lock (mutex);
  else
    return 0;
}

static inline int
__gthread_mutex_trylock (__gthread_mutex_t *mutex)
{
  if (__gthread_active_p ())
    return __gthr_win32_mutex_trylock (mutex);
  else
    return 0;
}

static inline int
__gthread_mutex_unlock (__gthread_mutex_t *mutex)
{
  if (__gthread_active_p ())
    return __gthr_win32_mutex_unlock (mutex);
  else
    return 0;
}

#else /* ! __GTHREAD_HIDE_WIN32API */

#include <windows.h>
#include <errno.h>

static inline int
__gthread_once (__gthread_once_t *once, void (*func) (void))
{
  if (! __gthread_active_p ())
    return -1;
  else if (once == NULL || func == NULL)
    return EINVAL;

  if (! once->done)
    {
      if (InterlockedIncrement (&(once->started)) == 0)
	{
	  (*func) ();
	  once->done = TRUE;
	}
      else
	{
	  /* Another thread is currently executing the code, so wait for it
	     to finish; yield the CPU in the meantime.  If performance
	     does become an issue, the solution is to use an Event that
	     we wait on here (and set above), but that implies a place to
	     create the event before this routine is called.  */
	  while (! once->done)
	    Sleep (0);
	}
    }

  return 0;
}

/* Windows32 thread local keys don't support destructors; this leads to
   leaks, especially in threaded applications making extensive use of
   C++ EH. Mingw uses a thread-support DLL to work-around this problem.  */
static inline int
__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
{
  int status = 0;
  DWORD tls_index = TlsAlloc ();
  if (tls_index != 0xFFFFFFFF)
    {
      *key = tls_index;
#ifdef MINGW32_SUPPORTS_MT_EH
      /* Mingw runtime will run the dtors in reverse order for each thread
         when the thread exits.  */
      status = __mingwthr_key_dtor (*key, dtor);
#endif
    }
  else
    status = (int) GetLastError ();
  return status;
}

static inline int
__gthread_key_delete (__gthread_key_t key)
{
  return (TlsFree (key) != 0) ? 0 : (int) GetLastError ();
}

static inline void *
__gthread_getspecific (__gthread_key_t key)
{
  DWORD lasterror;
  void *ptr;

  lasterror = GetLastError ();

  ptr = TlsGetValue (key);

  SetLastError (lasterror);

  return ptr;
}

static inline int
__gthread_setspecific (__gthread_key_t key, const void *ptr)
{
  return (TlsSetValue (key, (void*) ptr) != 0) ? 0 : (int) GetLastError ();
}

static inline void
__gthread_mutex_init_function (__gthread_mutex_t *mutex)
{
  mutex->counter = -1;
  mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
}

static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
  int status = 0;

  if (__gthread_active_p ())
    {
      if (InterlockedIncrement (&mutex->counter) == 0 ||
	  WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0)
	status = 0;
      else
	{
	  /* WaitForSingleObject returns WAIT_FAILED, and we can only do
	     some best-effort cleanup here.  */
	  InterlockedDecrement (&mutex->counter);
	  status = 1;
	}
    }
  return status;
}

static inline int
__gthread_mutex_trylock (__gthread_mutex_t *mutex)
{
  int status = 0;

  if (__gthread_active_p ())
    {
      if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0)
	status = 0;
      else
	status = 1;
    }
  return status;
}

static inline int
__gthread_mutex_unlock (__gthread_mutex_t *mutex)
{
  if (__gthread_active_p ())
    {
      if (InterlockedDecrement (&mutex->counter) >= 0)
	return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1;
    }
  return 0;
}

#endif /*  __GTHREAD_HIDE_WIN32API */

#ifdef __cplusplus
}
#endif

#endif /* _LIBOBJC */

#endif /* ! GCC_GTHR_WIN32_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -