pthread_mutex implementation
This commit is contained in:
parent
9251a3b7cc
commit
2fdcc4b557
@ -12,6 +12,7 @@
|
|||||||
#define ENAMETOOLONG 0xBAD8
|
#define ENAMETOOLONG 0xBAD8
|
||||||
#define ENOSYS 0xBAD9
|
#define ENOSYS 0xBAD9
|
||||||
#define EAGAIN 0xBADA
|
#define EAGAIN 0xBADA
|
||||||
|
#define EBUSY 0xBADB
|
||||||
|
|
||||||
#endif /* __ERRNO_H__ */
|
#endif /* __ERRNO_H__ */
|
||||||
|
|
||||||
|
@ -2,12 +2,17 @@
|
|||||||
#ifndef __PTHREAD_H__
|
#ifndef __PTHREAD_H__
|
||||||
#define __PTHREAD_H__
|
#define __PTHREAD_H__
|
||||||
|
|
||||||
|
#define PTHREAD_MUTEX_INITIALIZER NULL
|
||||||
|
#define PTHREAD_COND_INITIALIZER NULL
|
||||||
|
|
||||||
typedef struct pthread *pthread_t;
|
typedef struct pthread *pthread_t;
|
||||||
typedef struct pthread_attr *pthread_attr_t;
|
typedef struct pthread_attr *pthread_attr_t;
|
||||||
typedef struct pthread_barrier *pthread_barrier_t;
|
typedef struct pthread_barrier *pthread_barrier_t;
|
||||||
typedef struct pthread_barrierattr *pthread_barrierattr_t;
|
typedef struct pthread_barrierattr *pthread_barrierattr_t;
|
||||||
typedef struct pthread_mutex *pthread_mutex_t;
|
typedef struct pthread_mutex *pthread_mutex_t;
|
||||||
typedef struct pthread_mutexattr *pthread_mutexattr_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);
|
pthread_t pthread_self(void);
|
||||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
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
|
* 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__ */
|
#endif /* __PTHREAD_H__ */
|
||||||
|
|
||||||
|
@ -113,45 +113,123 @@ pthread_barrier_init(pthread_barrier_t *barrier,
|
|||||||
const pthread_barrierattr_t *attr,
|
const pthread_barrierattr_t *attr,
|
||||||
unsigned count)
|
unsigned count)
|
||||||
{
|
{
|
||||||
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pthread_barrier_destroy(pthread_barrier_t *barrier)
|
pthread_barrier_destroy(pthread_barrier_t *barrier)
|
||||||
{
|
{
|
||||||
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pthread_barrier_wait(pthread_barrier_t *barrier)
|
pthread_barrier_wait(pthread_barrier_t *barrier)
|
||||||
{
|
{
|
||||||
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mutex
|
* Mutex
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct pthread_mutexattr {
|
||||||
|
uint64_t _unused;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pthread_mutex {
|
||||||
|
uint64_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
|
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
|
int
|
||||||
pthread_mutex_destroy(pthread_mutex_t *mutex)
|
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
|
int
|
||||||
pthread_mutex_lock(pthread_mutex_t *mutex)
|
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
|
int
|
||||||
pthread_mutex_trylock(pthread_mutex_t *mutex)
|
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
|
int
|
||||||
pthread_mutex_unlock(pthread_mutex_t *mutex)
|
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
|
* 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