diff --git a/headers/posix/pthread.h b/headers/posix/pthread.h index b4bb1abb44..0961b06191 100644 --- a/headers/posix/pthread.h +++ b/headers/posix/pthread.h @@ -21,10 +21,10 @@ typedef int pthread_key_t; typedef struct _pthread_once pthread_once_t; typedef struct _pthread_rwlock pthread_rwlock_t; typedef struct _pthread_rwlockattr *pthread_rwlockattr_t; +typedef struct _pthread_spinlock pthread_spinlock_t; /* typedef struct _pthread_barrier *pthread_barrier_t; typedef struct _pthread_barrierattr *pthread_barrierattr_t; -typedef struct _pthread_spinlock *pthread_spinlock_t; */ struct _pthread_mutex { @@ -64,6 +64,10 @@ struct _pthread_rwlock { }; }; +struct _pthread_spinlock { + int32_t lock; +}; + #define PTHREAD_MUTEX_DEFAULT 0 #define PTHREAD_MUTEX_NORMAL 1 #define PTHREAD_MUTEX_ERRORCHECK 2 @@ -206,6 +210,13 @@ extern int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, extern int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int shared); +/* spinlock functions */ +extern int pthread_spin_init(pthread_spinlock_t* spinlock, int pshared); +extern int pthread_spin_destroy(pthread_spinlock_t* spinlock); +extern int pthread_spin_lock(pthread_spinlock_t* spinlock); +extern int pthread_spin_trylock(pthread_spinlock_t* spinlock); +extern int pthread_spin_unlock(pthread_spinlock_t* spinlock); + /* misc. functions */ extern int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)); diff --git a/src/system/libroot/posix/pthread/Jamfile b/src/system/libroot/posix/pthread/Jamfile index 64294ee377..087b5f8d08 100644 --- a/src/system/libroot/posix/pthread/Jamfile +++ b/src/system/libroot/posix/pthread/Jamfile @@ -18,5 +18,6 @@ MergeObject posix_pthread.o : pthread_mutexattr.c pthread_once.cpp pthread_rwlock.cpp + pthread_spinlock.c ; diff --git a/src/system/libroot/posix/pthread/pthread_spinlock.c b/src/system/libroot/posix/pthread/pthread_spinlock.c new file mode 100644 index 0000000000..d9881feb7a --- /dev/null +++ b/src/system/libroot/posix/pthread/pthread_spinlock.c @@ -0,0 +1,57 @@ +/* + * Copyright 2010, Lucian Adrian Grijincu, lucian.grijincu@gmail.com. + * Distributed under the terms of the MIT License. + */ + + +#include +#include "pthread_private.h" + + +#define UNLOCKED 0 +#define LOCKED 1 + + +int +pthread_spin_init(pthread_spinlock_t* lock, int pshared) +{ + // this implementation of spinlocks doesn't differentiate + // between spin locks used by threads in the same process or + // between threads of different processes. + + lock->lock = UNLOCKED; + return 0; +} + + +int +pthread_spin_destroy(pthread_spinlock_t* lock) +{ + return 0; +} + + +int +pthread_spin_lock(pthread_spinlock_t* lock) +{ + while (atomic_test_and_set((int32*)&lock->lock, LOCKED, UNLOCKED) == LOCKED) + ; // spin + return 0; +} + + +int +pthread_spin_trylock(pthread_spinlock_t* lock) +{ + if (atomic_test_and_set((int32*)&lock->lock, LOCKED, UNLOCKED) == LOCKED) + return EBUSY; + return 0; +} + + +int +pthread_spin_unlock(pthread_spinlock_t* lock) +{ + lock->lock = UNLOCKED; + return 0; +}