posix/pthreads: fix pthread_barrier_wait() behavior to match Posix
Exactly one caller of pthread_barrier_wait() should receive a return value of PTHREAD_BARRIER_SERIAL_WAIT; all others should receive zero (or an error code). Added a test to match. Fixes: #9953 Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
parent
6c8825fc96
commit
3522e05f76
3 changed files with 20 additions and 7 deletions
|
@ -334,6 +334,8 @@ static inline int pthread_mutexattr_destroy(pthread_mutexattr_t *m)
|
||||||
.max = count, \
|
.max = count, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PTHREAD_BARRIER_SERIAL_THREAD 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief POSIX threading compatibility API
|
* @brief POSIX threading compatibility API
|
||||||
*
|
*
|
||||||
|
|
|
@ -11,10 +11,8 @@
|
||||||
|
|
||||||
int pthread_barrier_wait(pthread_barrier_t *b)
|
int pthread_barrier_wait(pthread_barrier_t *b)
|
||||||
{
|
{
|
||||||
/* FIXME: This function should return PTHREAD_BARRIER_SERIAL_THREAD
|
unsigned int key = irq_lock();
|
||||||
* for an arbitrary thread and 0 for the others.
|
int ret = 0;
|
||||||
*/
|
|
||||||
int key = irq_lock();
|
|
||||||
|
|
||||||
b->count++;
|
b->count++;
|
||||||
|
|
||||||
|
@ -25,8 +23,10 @@ int pthread_barrier_wait(pthread_barrier_t *b)
|
||||||
_ready_one_thread(&b->wait_q);
|
_ready_one_thread(&b->wait_q);
|
||||||
}
|
}
|
||||||
_reschedule_irqlock(key);
|
_reschedule_irqlock(key);
|
||||||
return 0;
|
ret = PTHREAD_BARRIER_SERIAL_THREAD;
|
||||||
} else {
|
} else {
|
||||||
return _pend_curr_irqlock(key, &b->wait_q, K_FOREVER);
|
(void) _pend_curr_irqlock(key, &b->wait_q, K_FOREVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ static int curr_bounce_thread;
|
||||||
|
|
||||||
static int barrier_failed;
|
static int barrier_failed;
|
||||||
static int barrier_done[N_THR_E];
|
static int barrier_done[N_THR_E];
|
||||||
|
static int barrier_return[N_THR_E];
|
||||||
|
|
||||||
/* First phase bounces execution between two threads using a condition
|
/* First phase bounces execution between two threads using a condition
|
||||||
* variable, continuously testing that no other thread is mucking with
|
* variable, continuously testing that no other thread is mucking with
|
||||||
|
@ -138,7 +139,7 @@ void *thread_top_exec(void *p1)
|
||||||
sem_post(&main_sem);
|
sem_post(&main_sem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_barrier_wait(&barrier);
|
barrier_return[id] = pthread_barrier_wait(&barrier);
|
||||||
barrier_done[id] = 1;
|
barrier_done[id] = 1;
|
||||||
sem_post(&main_sem);
|
sem_post(&main_sem);
|
||||||
pthread_exit(p1);
|
pthread_exit(p1);
|
||||||
|
@ -231,6 +232,7 @@ void test_posix_pthread_execution(void)
|
||||||
int schedpolicy = SCHED_FIFO;
|
int schedpolicy = SCHED_FIFO;
|
||||||
void *retval, *stackaddr;
|
void *retval, *stackaddr;
|
||||||
size_t stacksize;
|
size_t stacksize;
|
||||||
|
int serial_threads = 0;
|
||||||
|
|
||||||
sem_init(&main_sem, 0, 1);
|
sem_init(&main_sem, 0, 1);
|
||||||
schedparam.sched_priority = CONFIG_NUM_COOP_PRIORITIES - 1;
|
schedparam.sched_priority = CONFIG_NUM_COOP_PRIORITIES - 1;
|
||||||
|
@ -346,6 +348,15 @@ void test_posix_pthread_execution(void)
|
||||||
pthread_join(newthread[i], &retval);
|
pthread_join(newthread[i], &retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < N_THR_E; i++) {
|
||||||
|
if (barrier_return[i] == PTHREAD_BARRIER_SERIAL_THREAD) {
|
||||||
|
++serial_threads;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TESTPOINT: Check only one PTHREAD_BARRIER_SERIAL_THREAD returned. */
|
||||||
|
zassert_true(serial_threads == 1, "Bungled barrier return value(s)");
|
||||||
|
|
||||||
printk("Barrier test OK\n");
|
printk("Barrier test OK\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue