forked from KolibriOS/kolibrios
sdk: update
git-svn-id: svn://kolibrios.org@4396 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
c549ddec4c
commit
2fe2d0aeda
@ -1,5 +1,5 @@
|
||||
|
||||
LIBRARY= libsup++
|
||||
LIBRARY= libsupc++
|
||||
|
||||
CC=gcc
|
||||
CPP=g++
|
||||
|
@ -72,8 +72,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
#include <_mingw.h>
|
||||
#endif
|
||||
|
||||
#ifndef ___GLIBCXX_UNUSED_PARAM
|
||||
#define ___GLIBCXX_UNUSED_PARAM(x) x
|
||||
#ifndef __UNUSED_PARAM
|
||||
#define __UNUSED_PARAM(x) x
|
||||
#endif
|
||||
|
||||
#ifdef _LIBOBJC
|
||||
@ -295,7 +295,7 @@ __gthread_objc_mutex_unlock (objc_mutex_t mutex)
|
||||
|
||||
/* Allocate a condition. */
|
||||
int
|
||||
__gthread_objc_condition_allocate (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition))
|
||||
__gthread_objc_condition_allocate (objc_condition_t __UNUSED_PARAM(condition))
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
@ -303,7 +303,7 @@ __gthread_objc_condition_allocate (objc_condition_t ___GLIBCXX_UNUSED_PARAM(cond
|
||||
|
||||
/* Deallocate a condition. */
|
||||
int
|
||||
__gthread_objc_condition_deallocate (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition))
|
||||
__gthread_objc_condition_deallocate (objc_condition_t __UNUSED_PARAM(condition))
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
@ -311,8 +311,8 @@ __gthread_objc_condition_deallocate (objc_condition_t ___GLIBCXX_UNUSED_PARAM(co
|
||||
|
||||
/* Wait on the condition */
|
||||
int
|
||||
__gthread_objc_condition_wait (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition),
|
||||
objc_mutex_t ___GLIBCXX_UNUSED_PARAM(mutex))
|
||||
__gthread_objc_condition_wait (objc_condition_t __UNUSED_PARAM(condition),
|
||||
objc_mutex_t __UNUSED_PARAM(mutex))
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
@ -320,7 +320,7 @@ __gthread_objc_condition_wait (objc_condition_t ___GLIBCXX_UNUSED_PARAM(conditio
|
||||
|
||||
/* Wake up all threads waiting on this condition. */
|
||||
int
|
||||
__gthread_objc_condition_broadcast (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition))
|
||||
__gthread_objc_condition_broadcast (objc_condition_t __UNUSED_PARAM(condition))
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
@ -328,7 +328,7 @@ __gthread_objc_condition_broadcast (objc_condition_t ___GLIBCXX_UNUSED_PARAM(con
|
||||
|
||||
/* Wake up one thread waiting on this condition. */
|
||||
int
|
||||
__gthread_objc_condition_signal (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition))
|
||||
__gthread_objc_condition_signal (objc_condition_t __UNUSED_PARAM(condition))
|
||||
{
|
||||
/* Unimplemented. */
|
||||
return -1;
|
||||
|
@ -1,11 +1,65 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/errno.h>
|
||||
#include <kos32sys.h>
|
||||
|
||||
void __mutex_lock(volatile int *val);
|
||||
|
||||
static inline int tls_get(int key)
|
||||
{
|
||||
int val;
|
||||
__asm__ __volatile__(
|
||||
"movl %%fs:(%1), %0"
|
||||
:"=r"(val)
|
||||
:"r"(key));
|
||||
|
||||
return val;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int done;
|
||||
long started;
|
||||
} __gthread_once_t;
|
||||
|
||||
typedef struct {
|
||||
int counter;
|
||||
void *sema;
|
||||
} __gthread_mutex_t;
|
||||
|
||||
typedef struct {
|
||||
int counter;
|
||||
int depth;
|
||||
unsigned long owner;
|
||||
int sema;
|
||||
} __gthread_recursive_mutex_t;
|
||||
|
||||
|
||||
int
|
||||
__gthr_win32_once (__gthread_once_t *once, void (*func) (void))
|
||||
{
|
||||
if (once == NULL || func == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if (! once->done)
|
||||
{
|
||||
if (__sync_add_and_fetch (&(once->started), 1) == 0)
|
||||
{
|
||||
(*func) ();
|
||||
once->done = 1;
|
||||
}
|
||||
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)
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __gthr_win32_mutex_init_function (__gthread_mutex_t *mutex)
|
||||
{
|
||||
mutex->counter = 0;
|
||||
@ -25,3 +79,72 @@ __gthr_win32_mutex_unlock (__gthread_mutex_t *mutex)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
__gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
|
||||
{
|
||||
mutex->counter = -1;
|
||||
mutex->depth = 0;
|
||||
mutex->owner = 0;
|
||||
mutex->sema = 0;
|
||||
}
|
||||
|
||||
void
|
||||
__gthr_win32_mutex_destroy (__gthread_mutex_t *mutex)
|
||||
{ }
|
||||
|
||||
int
|
||||
__gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
|
||||
{
|
||||
int me = tls_get(0);
|
||||
if ( __sync_add_and_fetch(&mutex->counter, 1) == 0)
|
||||
{
|
||||
mutex->depth = 1;
|
||||
mutex->owner = me;
|
||||
mutex->sema = 1;
|
||||
}
|
||||
else if (mutex->owner == me)
|
||||
{
|
||||
__sync_sub_and_fetch(&mutex->counter, 1);
|
||||
++(mutex->depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
__mutex_lock(&mutex->sema);
|
||||
mutex->depth = 1;
|
||||
mutex->owner = me;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
|
||||
{
|
||||
int me = tls_get(0);
|
||||
if (__sync_val_compare_and_swap (&mutex->counter, -1, 0) < 0)
|
||||
{
|
||||
mutex->depth = 1;
|
||||
mutex->owner = me;
|
||||
mutex->sema = 1;
|
||||
}
|
||||
else if (mutex->owner == me)
|
||||
++(mutex->depth);
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
|
||||
{
|
||||
--(mutex->depth);
|
||||
if (mutex->depth == 0)
|
||||
{
|
||||
mutex->owner = 0;
|
||||
|
||||
if (__sync_sub_and_fetch (&mutex->counter, 1) >= 0)
|
||||
mutex->sema = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user