pthread_mutex implementation
This commit is contained in:
parent
9251a3b7cc
commit
2fdcc4b557
@ -12,6 +12,7 @@
|
||||
#define ENAMETOOLONG 0xBAD8
|
||||
#define ENOSYS 0xBAD9
|
||||
#define EAGAIN 0xBADA
|
||||
#define EBUSY 0xBADB
|
||||
|
||||
#endif /* __ERRNO_H__ */
|
||||
|
||||
|
@ -2,12 +2,17 @@
|
||||
#ifndef __PTHREAD_H__
|
||||
#define __PTHREAD_H__
|
||||
|
||||
#define PTHREAD_MUTEX_INITIALIZER NULL
|
||||
#define PTHREAD_COND_INITIALIZER NULL
|
||||
|
||||
typedef struct pthread *pthread_t;
|
||||
typedef struct pthread_attr *pthread_attr_t;
|
||||
typedef struct pthread_barrier *pthread_barrier_t;
|
||||
typedef struct pthread_barrierattr *pthread_barrierattr_t;
|
||||
typedef struct pthread_mutex *pthread_mutex_t;
|
||||
typedef struct pthread_mutexattr *pthread_mutexattr_t;
|
||||
typedef struct pthread_cond *pthread_cond_t;
|
||||
typedef struct pthread_condattr *pthread_condattr_t;
|
||||
|
||||
pthread_t pthread_self(void);
|
||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
@ -45,5 +50,11 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex);
|
||||
* Condition Variables
|
||||
*/
|
||||
|
||||
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
|
||||
int pthread_cond_destroy(pthread_cond_t *cond);
|
||||
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
|
||||
int pthread_cond_signal(pthread_cond_t *cond);
|
||||
int pthread_cond_broadcast(pthread_cond_t *cond);
|
||||
|
||||
#endif /* __PTHREAD_H__ */
|
||||
|
||||
|
@ -113,45 +113,123 @@ pthread_barrier_init(pthread_barrier_t *barrier,
|
||||
const pthread_barrierattr_t *attr,
|
||||
unsigned count)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_barrier_destroy(pthread_barrier_t *barrier)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_barrier_wait(pthread_barrier_t *barrier)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mutex
|
||||
*/
|
||||
|
||||
struct pthread_mutexattr {
|
||||
uint64_t _unused;
|
||||
};
|
||||
|
||||
struct pthread_mutex {
|
||||
uint64_t lock;
|
||||
};
|
||||
|
||||
int
|
||||
pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
|
||||
{
|
||||
struct pthread_mutex *mtx = (struct pthread_mutex *)malloc(sizeof(*mtx));
|
||||
|
||||
if (mtx == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
mtx->lock = 0;
|
||||
*mutex = mtx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_mutex_destroy(pthread_mutex_t *mutex)
|
||||
{
|
||||
struct pthread_mutex *mtx = *mutex;
|
||||
|
||||
if (mtx == NULL) {
|
||||
return EINVAL;
|
||||
} else if (mtx->lock == 1) {
|
||||
return EBUSY;
|
||||
} else {
|
||||
*mutex = NULL;
|
||||
free(mtx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pthread_mutex_lock(pthread_mutex_t *mutex)
|
||||
{
|
||||
struct pthread_mutex *mtx;
|
||||
|
||||
if (*mutex == NULL) {
|
||||
int status = pthread_mutex_init(mutex, NULL);
|
||||
if (status != 0)
|
||||
return status;
|
||||
}
|
||||
|
||||
mtx = *mutex;
|
||||
|
||||
// XXX: Should have the kernel wait kernel instead of yielding
|
||||
while (__sync_lock_test_and_set(&mtx->lock, 1) == 1) {
|
||||
OSThreadSleep(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_mutex_trylock(pthread_mutex_t *mutex)
|
||||
{
|
||||
struct pthread_mutex *mtx;
|
||||
|
||||
if (*mutex == NULL) {
|
||||
int status = pthread_mutex_init(mutex, NULL);
|
||||
if (status != 0)
|
||||
return status;
|
||||
}
|
||||
|
||||
mtx = *mutex;
|
||||
|
||||
if (__sync_lock_test_and_set(&mtx->lock, 1) == 1) {
|
||||
return EBUSY;
|
||||
} else {
|
||||
// Lock acquired
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pthread_mutex_unlock(pthread_mutex_t *mutex)
|
||||
{
|
||||
struct pthread_mutex *mtx;
|
||||
|
||||
if (*mutex == NULL) {
|
||||
int status = pthread_mutex_init(mutex, NULL);
|
||||
if (status != 0)
|
||||
return status;
|
||||
}
|
||||
|
||||
mtx = *mutex;
|
||||
|
||||
__sync_lock_release(&mtx->lock);
|
||||
// XXX: Wakeup a sleeping thread
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -163,3 +241,40 @@ pthread_mutex_unlock(pthread_mutex_t *mutex)
|
||||
* Condition Variables
|
||||
*/
|
||||
|
||||
struct pthread_cond {
|
||||
};
|
||||
|
||||
struct pthread_condattr {
|
||||
};
|
||||
|
||||
int
|
||||
pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_cond_destroy(pthread_cond_t *cond)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pthread_cond_signal(pthread_cond_t *cond)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user