Professional Documents
Culture Documents
#include <errno.h>
#ifdef __MINGW32__
#include <_mingw.h>
#endif
#ifdef _LIBOBJC
switch (priority)
{
case OBJC_THREAD_INTERACTIVE_PRIORITY:
sys_priority = THREAD_PRIORITY_NORMAL;
break;
default:
case OBJC_THREAD_BACKGROUND_PRIORITY:
sys_priority = THREAD_PRIORITY_BELOW_NORMAL;
break;
case OBJC_THREAD_LOW_PRIORITY:
sys_priority = THREAD_PRIORITY_LOWEST;
break;
}
/* Change priority */
if (SetThreadPriority (GetCurrentThread (), sys_priority))
return 0;
else
return -1;
}
switch (sys_priority)
{
case THREAD_PRIORITY_HIGHEST:
case THREAD_PRIORITY_TIME_CRITICAL:
case THREAD_PRIORITY_ABOVE_NORMAL:
case THREAD_PRIORITY_NORMAL:
return OBJC_THREAD_INTERACTIVE_PRIORITY;
default:
case THREAD_PRIORITY_BELOW_NORMAL:
return OBJC_THREAD_BACKGROUND_PRIORITY;
case THREAD_PRIORITY_IDLE:
case THREAD_PRIORITY_LOWEST:
return OBJC_THREAD_LOW_PRIORITY;
}
SetLastError (lasterror);
return ptr;
}
/* Allocate a mutex. */
int
__gthread_objc_mutex_allocate (objc_mutex_t mutex)
{
if ((mutex->backend = (void *) CreateMutex (NULL, 0, NULL)) == NULL)
return -1;
else
return 0;
}
/* Deallocate a mutex. */
int
__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
{
CloseHandle ((HANDLE) (mutex->backend));
return 0;
}
/* Allocate a condition. */
int
__gthread_objc_condition_allocate (objc_condition_t condition)
{
/* Unimplemented. */
return -1;
}
/* Deallocate a condition. */
int
__gthread_objc_condition_deallocate (objc_condition_t condition)
{
/* Unimplemented. */
return -1;
}
#else /* _LIBOBJC */
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int done;
long started;
} __gthread_once_t;
typedef struct {
long counter;
void *sema;
} __gthread_mutex_t;
#ifdef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
#else /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */
#endif /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */
#if __GTHREAD_HIDE_WIN32API
#include <windows.h>
#include <errno.h>
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;
}
SetLastError (lasterror);
return ptr;
}
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;
}
if (__gthread_active_p ())
{
if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0)
status = 0;
else
status = 1;
}
return status;
}
#endif /* __GTHREAD_HIDE_WIN32API */
#ifdef __cplusplus
}
#endif
#endif /* _LIBOBJC */
#endif /* ! GCC_GTHR_WIN32_H */