pthread_mutex implementation

This commit is contained in:
Ali Mashtizadeh 2015-01-30 18:40:25 -08:00
parent 9251a3b7cc
commit 2fdcc4b557
3 changed files with 127 additions and 0 deletions

View File

@ -12,6 +12,7 @@
#define ENAMETOOLONG 0xBAD8
#define ENOSYS 0xBAD9
#define EAGAIN 0xBADA
#define EBUSY 0xBADB
#endif /* __ERRNO_H__ */

View File

@ -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__ */

View File

@ -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;
}