Return errors directly instead of using errno
This commit is contained in:
parent
aba392e630
commit
b1a60476c0
@ -53,10 +53,8 @@ void *arg;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (proc == NULL) {
|
if (proc == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mthread_queue_isempty(&free_threads)) {
|
if (!mthread_queue_isempty(&free_threads)) {
|
||||||
thread = mthread_queue_remove(&free_threads);
|
thread = mthread_queue_remove(&free_threads);
|
||||||
@ -69,10 +67,8 @@ void *arg;
|
|||||||
#endif
|
#endif
|
||||||
return(0);
|
return(0);
|
||||||
} else {
|
} else {
|
||||||
if (mthread_increase_thread_pool() == -1) {
|
if (mthread_increase_thread_pool() == -1)
|
||||||
errno = EAGAIN;
|
return(EAGAIN);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mthread_create(threadid, tattr, proc, arg);
|
return mthread_create(threadid, tattr, proc, arg);
|
||||||
}
|
}
|
||||||
@ -91,15 +87,12 @@ mthread_thread_t detach;
|
|||||||
mthread_tcb_t *tcb;
|
mthread_tcb_t *tcb;
|
||||||
mthread_init(); /* Make sure libmthread is initialized */
|
mthread_init(); /* Make sure libmthread is initialized */
|
||||||
|
|
||||||
if (!isokthreadid(detach)) {
|
if (!isokthreadid(detach))
|
||||||
errno = ESRCH;
|
return(ESRCH);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
tcb = mthread_find_tcb(detach);
|
tcb = mthread_find_tcb(detach);
|
||||||
if (tcb->m_state == MS_DEAD) {
|
if (tcb->m_state == MS_DEAD) {
|
||||||
errno = ESRCH;
|
return(ESRCH);
|
||||||
return(-1);
|
|
||||||
} else if (tcb->m_attr.ma_detachstate != MTHREAD_CREATE_DETACHED) {
|
} else if (tcb->m_attr.ma_detachstate != MTHREAD_CREATE_DETACHED) {
|
||||||
if (tcb->m_state == MS_EXITING)
|
if (tcb->m_state == MS_EXITING)
|
||||||
mthread_thread_stop(detach);
|
mthread_thread_stop(detach);
|
||||||
@ -319,22 +312,16 @@ void **value;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure libmthread is initialized */
|
mthread_init(); /* Make sure libmthread is initialized */
|
||||||
|
|
||||||
if (!isokthreadid(join)) {
|
if (!isokthreadid(join))
|
||||||
errno = ESRCH;
|
return(ESRCH);
|
||||||
return(-1);
|
else if (join == current_thread)
|
||||||
} else if (join == current_thread) {
|
return(EDEADLK);
|
||||||
errno = EDEADLK;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
tcb = mthread_find_tcb(join);
|
tcb = mthread_find_tcb(join);
|
||||||
if (tcb->m_state == MS_DEAD) {
|
if (tcb->m_state == MS_DEAD)
|
||||||
errno = ESRCH;
|
return(ESRCH);
|
||||||
return(-1);
|
else if (tcb->m_attr.ma_detachstate == MTHREAD_CREATE_DETACHED)
|
||||||
} else if (tcb->m_attr.ma_detachstate == MTHREAD_CREATE_DETACHED) {
|
return(EINVAL);
|
||||||
errno = EINVAL;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* When the thread hasn't exited yet, we have to wait for that to happen */
|
/* When the thread hasn't exited yet, we have to wait for that to happen */
|
||||||
if (tcb->m_state != MS_EXITING) {
|
if (tcb->m_state != MS_EXITING) {
|
||||||
@ -381,10 +368,8 @@ void (*proc)(void);
|
|||||||
|
|
||||||
mthread_init(); /* Make sure libmthread is initialized */
|
mthread_init(); /* Make sure libmthread is initialized */
|
||||||
|
|
||||||
if (once == NULL || proc == NULL) {
|
if (once == NULL || proc == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*once != 1) proc();
|
if (*once != 1) proc();
|
||||||
*once = 1;
|
*once = 1;
|
||||||
|
@ -48,15 +48,11 @@ mthread_attr_t *attr;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (attr == NULL) {
|
if (attr == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mthread_attr_valid(attr)) {
|
if (!mthread_attr_valid(attr))
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Valide attribute; invalidate it */
|
/* Valide attribute; invalidate it */
|
||||||
mthread_attr_remove(attr);
|
mthread_attr_remove(attr);
|
||||||
@ -78,13 +74,10 @@ mthread_attr_t *attr; /* Attribute */
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (attr == NULL) {
|
if (attr == NULL)
|
||||||
errno = EAGAIN;
|
return(EAGAIN);
|
||||||
return(-1);
|
else if (mthread_attr_valid(attr))
|
||||||
} else if (mthread_attr_valid(attr)) {
|
return(EBUSY);
|
||||||
errno = EBUSY;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((a = malloc(sizeof(struct __mthread_attr))) == NULL)
|
if ((a = malloc(sizeof(struct __mthread_attr))) == NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
@ -111,16 +104,12 @@ int *detachstate;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (attr == NULL) {
|
if (attr == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
a = (struct __mthread_attr *) *attr;
|
a = (struct __mthread_attr *) *attr;
|
||||||
if (!mthread_attr_valid(attr)) {
|
if (!mthread_attr_valid(attr))
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
*detachstate = a->ma_detachstate;
|
*detachstate = a->ma_detachstate;
|
||||||
|
|
||||||
@ -140,20 +129,15 @@ int detachstate;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (attr == NULL) {
|
if (attr == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
a = (struct __mthread_attr *) *attr;
|
a = (struct __mthread_attr *) *attr;
|
||||||
if (!mthread_attr_valid(attr)) {
|
if (!mthread_attr_valid(attr))
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
else if(detachstate != MTHREAD_CREATE_JOINABLE &&
|
||||||
} else if(detachstate != MTHREAD_CREATE_JOINABLE &&
|
detachstate != MTHREAD_CREATE_DETACHED)
|
||||||
detachstate != MTHREAD_CREATE_DETACHED) {
|
return(EINVAL);
|
||||||
errno = EINVAL;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
a->ma_detachstate = detachstate;
|
a->ma_detachstate = detachstate;
|
||||||
|
|
||||||
@ -174,16 +158,12 @@ size_t *stacksize;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (attr == NULL) {
|
if (attr == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
a = (struct __mthread_attr *) *attr;
|
a = (struct __mthread_attr *) *attr;
|
||||||
if (!mthread_attr_valid(attr)) {
|
if (!mthread_attr_valid(attr))
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
*stackaddr = a->ma_stackaddr;
|
*stackaddr = a->ma_stackaddr;
|
||||||
*stacksize = a->ma_stacksize;
|
*stacksize = a->ma_stacksize;
|
||||||
@ -204,16 +184,12 @@ size_t *stacksize;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (attr == NULL) {
|
if (attr == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
a = (struct __mthread_attr *) *attr;
|
a = (struct __mthread_attr *) *attr;
|
||||||
if (!mthread_attr_valid(attr)) {
|
if (!mthread_attr_valid(attr))
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
*stacksize = a->ma_stacksize;
|
*stacksize = a->ma_stacksize;
|
||||||
|
|
||||||
@ -234,16 +210,13 @@ size_t stacksize;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (attr == NULL) {
|
if (attr == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
a = (struct __mthread_attr *) *attr;
|
a = (struct __mthread_attr *) *attr;
|
||||||
if (!mthread_attr_valid(attr) || stacksize < MTHREAD_STACK_MIN) {
|
if (!mthread_attr_valid(attr) || stacksize < MTHREAD_STACK_MIN)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
/* We don't care about address alignment (POSIX standard). The ucontext
|
/* We don't care about address alignment (POSIX standard). The ucontext
|
||||||
* system calls will make sure that the provided stack will be aligned (at
|
* system calls will make sure that the provided stack will be aligned (at
|
||||||
* the cost of some memory if needed).
|
* the cost of some memory if needed).
|
||||||
@ -268,16 +241,12 @@ size_t stacksize;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (attr == NULL) {
|
if (attr == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
a = (struct __mthread_attr *) *attr;
|
a = (struct __mthread_attr *) *attr;
|
||||||
if (!mthread_attr_valid(attr) || stacksize < MTHREAD_STACK_MIN) {
|
if (!mthread_attr_valid(attr) || stacksize < MTHREAD_STACK_MIN)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
a->ma_stacksize = stacksize;
|
a->ma_stacksize = stacksize;
|
||||||
|
|
||||||
|
@ -58,13 +58,10 @@ mthread_cond_t *cond;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure libmthread is initialized */
|
mthread_init(); /* Make sure libmthread is initialized */
|
||||||
|
|
||||||
if (cond == NULL) {
|
if (cond == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
else if (!mthread_cond_valid(cond))
|
||||||
} else if (!mthread_cond_valid(cond)) {
|
return(EINVAL);
|
||||||
errno = EINVAL;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
tcb = mthread_find_tcb(MAIN_THREAD);
|
tcb = mthread_find_tcb(MAIN_THREAD);
|
||||||
if (tcb->m_state == MS_CONDITION && tcb->m_cond == *cond)
|
if (tcb->m_state == MS_CONDITION && tcb->m_cond == *cond)
|
||||||
@ -92,27 +89,20 @@ mthread_cond_t *cond;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure libmthread is initialized */
|
mthread_init(); /* Make sure libmthread is initialized */
|
||||||
|
|
||||||
if (cond == NULL) {
|
if (cond == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
else if (!mthread_cond_valid(cond))
|
||||||
} else if (!mthread_cond_valid(cond)) {
|
return(EINVAL);
|
||||||
errno = EINVAL;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is another thread currently using this condition variable? */
|
/* Is another thread currently using this condition variable? */
|
||||||
tcb = mthread_find_tcb(MAIN_THREAD);
|
tcb = mthread_find_tcb(MAIN_THREAD);
|
||||||
if (tcb->m_state == MS_CONDITION && tcb->m_cond == *cond) {
|
if (tcb->m_state == MS_CONDITION && tcb->m_cond == *cond)
|
||||||
errno = EBUSY;
|
return(EBUSY);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (t = (mthread_thread_t) 0; t < no_threads; t++) {
|
for (t = (mthread_thread_t) 0; t < no_threads; t++) {
|
||||||
tcb = mthread_find_tcb(t);
|
tcb = mthread_find_tcb(t);
|
||||||
if (tcb->m_state == MS_CONDITION && tcb->m_cond == *cond){
|
if (tcb->m_state == MS_CONDITION && tcb->m_cond == *cond)
|
||||||
errno = EBUSY;
|
return(EBUSY);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not in use; invalidate it. */
|
/* Not in use; invalidate it. */
|
||||||
@ -136,24 +126,18 @@ mthread_condattr_t *cattr;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure libmthread is initialized */
|
mthread_init(); /* Make sure libmthread is initialized */
|
||||||
|
|
||||||
if (cond == NULL) {
|
if (cond == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
else if (cattr != NULL)
|
||||||
} else if (cattr != NULL) {
|
return(ENOSYS);
|
||||||
errno = ENOSYS;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
#ifdef MTHREAD_STRICT
|
#ifdef MTHREAD_STRICT
|
||||||
else if (mthread_cond_valid(cond)) {
|
else if (mthread_cond_valid(cond))
|
||||||
/* Already initialized */
|
/* Already initialized */
|
||||||
errno = EBUSY;
|
return(EBUSY);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
else if ((c = malloc(sizeof(struct __mthread_cond))) == NULL) {
|
else if ((c = malloc(sizeof(struct __mthread_cond))) == NULL)
|
||||||
errno = ENOMEM;
|
return(ENOMEM);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
c->mc_mutex = NULL;
|
c->mc_mutex = NULL;
|
||||||
*cond = (mthread_cond_t) c;
|
*cond = (mthread_cond_t) c;
|
||||||
@ -197,13 +181,10 @@ mthread_cond_t *cond;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure libmthread is initialized */
|
mthread_init(); /* Make sure libmthread is initialized */
|
||||||
|
|
||||||
if (cond == NULL) {
|
if (cond == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
else if (!mthread_cond_valid(cond))
|
||||||
} else if (!mthread_cond_valid(cond)) {
|
return(EINVAL);
|
||||||
errno = EINVAL;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
tcb = mthread_find_tcb(MAIN_THREAD);
|
tcb = mthread_find_tcb(MAIN_THREAD);
|
||||||
if (tcb->m_state == MS_CONDITION && tcb->m_cond == *cond)
|
if (tcb->m_state == MS_CONDITION && tcb->m_cond == *cond)
|
||||||
@ -275,18 +256,14 @@ mthread_mutex_t *mutex;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure libmthread is initialized */
|
mthread_init(); /* Make sure libmthread is initialized */
|
||||||
|
|
||||||
if (cond == NULL || mutex == NULL) {
|
if (cond == NULL || mutex == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
c = (struct __mthread_cond *) *cond;
|
c = (struct __mthread_cond *) *cond;
|
||||||
m = (struct __mthread_mutex *) *mutex;
|
m = (struct __mthread_mutex *) *mutex;
|
||||||
|
|
||||||
if (!mthread_cond_valid(cond) || !mthread_mutex_valid(mutex)) {
|
if (!mthread_cond_valid(cond) || !mthread_mutex_valid(mutex))
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
c->mc_mutex = m; /* Remember we're using this mutex in a cond_wait */
|
c->mc_mutex = m; /* Remember we're using this mutex in a cond_wait */
|
||||||
if (mthread_mutex_unlock(mutex) != 0) /* Fails when we're not the owner */
|
if (mthread_mutex_unlock(mutex) != 0) /* Fails when we're not the owner */
|
||||||
|
@ -56,27 +56,20 @@ mthread_mutex_t *mutex;
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mthread_mutex_valid(mutex)) {
|
if (!mthread_mutex_valid(mutex))
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
else if ((*mutex)->mm_owner != NO_THREAD)
|
||||||
} else if ((*mutex)->mm_owner != NO_THREAD) {
|
return(EBUSY);
|
||||||
errno = EBUSY;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if this mutex is not associated with a condition */
|
/* Check if this mutex is not associated with a condition */
|
||||||
for (t = (mthread_thread_t) 0; t < no_threads; t++) {
|
for (t = (mthread_thread_t) 0; t < no_threads; t++) {
|
||||||
tcb = mthread_find_tcb(t);
|
tcb = mthread_find_tcb(t);
|
||||||
if (tcb->m_state == MS_CONDITION) {
|
if (tcb->m_state == MS_CONDITION) {
|
||||||
if (tcb->m_cond != NULL && tcb->m_cond->mc_mutex == *mutex) {
|
if (tcb->m_cond != NULL && tcb->m_cond->mc_mutex == *mutex)
|
||||||
errno = EBUSY;
|
return(EBUSY);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,23 +95,16 @@ mthread_mutexattr_t *mattr; /* Mutex attribute */
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL)
|
||||||
errno = EAGAIN;
|
return(EAGAIN);
|
||||||
return(-1);
|
else if (mattr != NULL)
|
||||||
} else if (mattr != NULL) {
|
return(ENOSYS);
|
||||||
errno = ENOSYS;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
#ifdef MTHREAD_STRICT
|
#ifdef MTHREAD_STRICT
|
||||||
else if (mthread_mutex_valid(mutex)) {
|
else if (mthread_mutex_valid(mutex))
|
||||||
errno = EBUSY;
|
return(EBUSY);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
else if ((m = malloc(sizeof(struct __mthread_mutex))) == NULL) {
|
else if ((m = malloc(sizeof(struct __mthread_mutex))) == NULL)
|
||||||
errno = ENOMEM;
|
return(ENOMEM);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
mthread_queue_init(&m->mm_queue);
|
mthread_queue_init(&m->mm_queue);
|
||||||
m->mm_owner = NO_THREAD;
|
m->mm_owner = NO_THREAD;
|
||||||
@ -141,22 +127,18 @@ mthread_mutex_t *mutex; /* Mutex that is to be locked */
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
m = (struct __mthread_mutex *) *mutex;
|
m = (struct __mthread_mutex *) *mutex;
|
||||||
if (!mthread_mutex_valid(&m)) {
|
if (!mthread_mutex_valid(&m))
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
else if (m->mm_owner == NO_THREAD) { /* Not locked */
|
||||||
} else if (m->mm_owner == NO_THREAD) { /* Not locked */
|
|
||||||
m->mm_owner = current_thread;
|
m->mm_owner = current_thread;
|
||||||
if (current_thread == MAIN_THREAD)
|
if (current_thread == MAIN_THREAD)
|
||||||
mthread_debug("MAIN_THREAD now mutex owner\n");
|
mthread_debug("MAIN_THREAD now mutex owner\n");
|
||||||
} else if (m->mm_owner == current_thread) {
|
} else if (m->mm_owner == current_thread) {
|
||||||
errno = EDEADLK;
|
return(EDEADLK);
|
||||||
return(-1);
|
|
||||||
} else {
|
} else {
|
||||||
mthread_queue_add(&m->mm_queue, current_thread);
|
mthread_queue_add(&m->mm_queue, current_thread);
|
||||||
if (m->mm_owner == MAIN_THREAD)
|
if (m->mm_owner == MAIN_THREAD)
|
||||||
@ -202,22 +184,18 @@ mthread_mutex_t *mutex; /* Mutex that is to be locked */
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
m = (struct __mthread_mutex *) *mutex;
|
m = (struct __mthread_mutex *) *mutex;
|
||||||
if (!mthread_mutex_valid(&m)) {
|
if (!mthread_mutex_valid(&m))
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
else if (m->mm_owner == NO_THREAD) {
|
||||||
} else if (m->mm_owner == NO_THREAD) {
|
|
||||||
m->mm_owner = current_thread;
|
m->mm_owner = current_thread;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = EBUSY;
|
return(EBUSY);
|
||||||
return(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -234,19 +212,14 @@ mthread_mutex_t *mutex; /* Mutex that is to be unlocked */
|
|||||||
|
|
||||||
mthread_init(); /* Make sure mthreads is initialized */
|
mthread_init(); /* Make sure mthreads is initialized */
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL)
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
m = (struct __mthread_mutex *) *mutex;
|
m = (struct __mthread_mutex *) *mutex;
|
||||||
if (!mthread_mutex_valid(&m)) {
|
if (!mthread_mutex_valid(&m))
|
||||||
errno = EINVAL;
|
return(EINVAL);
|
||||||
return(-1);
|
else if (m->mm_owner != current_thread)
|
||||||
} else if (m->mm_owner != current_thread) {
|
return(EPERM); /* Can't unlock a mutex locked by another thread. */
|
||||||
errno = EPERM;
|
|
||||||
return(-1); /* Can't unlock a mutex locked by another thread. */
|
|
||||||
}
|
|
||||||
|
|
||||||
m->mm_owner = mthread_queue_remove(&m->mm_queue);
|
m->mm_owner = mthread_queue_remove(&m->mm_queue);
|
||||||
if (m->mm_owner != NO_THREAD) mthread_unsuspend(m->mm_owner);
|
if (m->mm_owner != NO_THREAD) mthread_unsuspend(m->mm_owner);
|
||||||
|
@ -220,34 +220,28 @@ PRIVATE void mutex_a(void *arg)
|
|||||||
if (mthread_mutex_lock(&mu[0]) != 0) err(3, 2);
|
if (mthread_mutex_lock(&mu[0]) != 0) err(3, 2);
|
||||||
|
|
||||||
/* Trying to acquire lock again should fail with EDEADLK */
|
/* Trying to acquire lock again should fail with EDEADLK */
|
||||||
if (mthread_mutex_lock(&mu[0]) != -1) err(3, 2);
|
if (mthread_mutex_lock(&mu[0]) != EDEADLK) err(3, 2);
|
||||||
if (errno != EDEADLK) err(3, 3);
|
|
||||||
|
|
||||||
#ifdef MTHREAD_STRICT
|
#ifdef MTHREAD_STRICT
|
||||||
/* Try to acquire lock on uninitialized mutex; should fail with EINVAL */
|
/* Try to acquire lock on uninitialized mutex; should fail with EINVAL */
|
||||||
/* Note: this check only works when libmthread is compiled with
|
/* Note: this check only works when libmthread is compiled with
|
||||||
* MTHREAD_STRICT turned on. In POSIX this situation is a MAY fail if... */
|
* MTHREAD_STRICT turned on. In POSIX this situation is a MAY fail if... */
|
||||||
if (mthread_mutex_lock(&mu2) != -1) {
|
if (mthread_mutex_lock(&mu2) != EINVAL) {
|
||||||
err(3, 4);
|
err(3, 4);
|
||||||
mthread_mutex_unlock(&mu2);
|
mthread_mutex_unlock(&mu2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errno != EINVAL) err(3, 5);
|
if (mthread_mutex_trylock(&mu2) != EINVAL) {
|
||||||
errno = 0;
|
|
||||||
if (mthread_mutex_trylock(&mu2) != -1) {
|
|
||||||
err(3, 6);
|
err(3, 6);
|
||||||
mthread_mutex_unlock(&mu2);
|
mthread_mutex_unlock(&mu2);
|
||||||
}
|
}
|
||||||
if (errno != EINVAL) err(3, 7);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mthread_mutex_trylock(&mu[1]) != 0) err(3, 8);
|
if (mthread_mutex_trylock(&mu[1]) != 0) err(3, 8);
|
||||||
mutex_a_step = 1;
|
mutex_a_step = 1;
|
||||||
mthread_yield();
|
mthread_yield();
|
||||||
VERIFY_MUTEX(1, 0, 0, 3, 9);
|
VERIFY_MUTEX(1, 0, 0, 3, 9);
|
||||||
errno = 0;
|
if (mthread_mutex_trylock(&mu[2]) != EBUSY) err(3, 10);
|
||||||
if (mthread_mutex_trylock(&mu[2]) != -1) err(3, 10);
|
|
||||||
if (errno != EBUSY) err(3, 11);
|
|
||||||
if (mthread_mutex_lock(&mu[2]) != 0) err(3, 12); /* Transfer control to main
|
if (mthread_mutex_lock(&mu[2]) != 0) err(3, 12); /* Transfer control to main
|
||||||
* loop.
|
* loop.
|
||||||
*/
|
*/
|
||||||
@ -282,12 +276,10 @@ PRIVATE void mutex_b(void *arg)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
VERIFY_MUTEX(1, 0, 0, 4, 1);
|
VERIFY_MUTEX(1, 0, 0, 4, 1);
|
||||||
if (mthread_mutex_unlock(&mu[0]) != -1) err(4, 2);
|
if (mthread_mutex_unlock(&mu[0]) != EPERM) err(4, 2);
|
||||||
if (errno != EPERM) err(4, 3);
|
|
||||||
|
|
||||||
/* Probing mu[0] to lock it should tell us it's locked */
|
/* Probing mu[0] to lock it should tell us it's locked */
|
||||||
if (mthread_mutex_trylock(&mu[0]) == 0) err(4, 4);
|
if (mthread_mutex_trylock(&mu[0]) != EBUSY) err(4, 4);
|
||||||
if (errno != EBUSY) err(4, 5);
|
|
||||||
|
|
||||||
if (mthread_mutex_lock(&mu[0]) != 0) err(4, 5);
|
if (mthread_mutex_lock(&mu[0]) != 0) err(4, 5);
|
||||||
mutex_b_step = 1;
|
mutex_b_step = 1;
|
||||||
@ -612,9 +604,8 @@ PRIVATE void test_attributes(void)
|
|||||||
stacksize = 0;
|
stacksize = 0;
|
||||||
if (mthread_attr_init(&tattr) != 0) err(11, 17);
|
if (mthread_attr_init(&tattr) != 0) err(11, 17);
|
||||||
if ((newstackaddr = malloc(newstacksize)) == NULL) err(11, 18);
|
if ((newstackaddr = malloc(newstacksize)) == NULL) err(11, 18);
|
||||||
if (mthread_attr_setstack(&tattr, newstackaddr, newstacksize) == 0)
|
if (mthread_attr_setstack(&tattr, newstackaddr, newstacksize) != EINVAL)
|
||||||
err(11, 19);
|
err(11, 19);
|
||||||
if (errno != EINVAL) err(11, 20);
|
|
||||||
if (mthread_attr_getstack(&tattr, &stackaddr, &stacksize) != 0) err(11, 21);
|
if (mthread_attr_getstack(&tattr, &stackaddr, &stacksize) != 0) err(11, 21);
|
||||||
if (stackaddr == newstackaddr) err(11, 22);
|
if (stackaddr == newstackaddr) err(11, 22);
|
||||||
if (stacksize == newstacksize) err(11, 23);
|
if (stacksize == newstacksize) err(11, 23);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user