Skip to content

Commit

Permalink
tests: posix: common: rwlock: remove overspecified pthread_attr_t
Browse files Browse the repository at this point in the history
Much of tests/posix/common still overspecifies pthread_attr_t
options.

Default thread attributes are perfectly fine for the vast
majority of spawned threads in this testsuite, so simply use
a NULL pthread_attr_t* argument.

This fixes piles of bugs because we have not properly used
pthread_attr_destroy() appropriately.

Signed-off-by: Christopher Friedt <cfriedt@meta.com>
  • Loading branch information
cfriedt committed Jan 4, 2024
1 parent e14f362 commit 80e3f4a
Showing 1 changed file with 43 additions and 71 deletions.
114 changes: 43 additions & 71 deletions tests/posix/common/src/rwlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,50 @@

#include <pthread.h>

#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>
#include <zephyr/ztest.h>

#define N_THR 3
#define STACKSZ (MAX(1024, PTHREAD_STACK_MIN) + CONFIG_TEST_EXTRA_STACK_SIZE)

K_THREAD_STACK_ARRAY_DEFINE(stack, N_THR, STACKSZ);
pthread_rwlock_t rwlock;
LOG_MODULE_REGISTER(posix_rwlock_test);

static pthread_rwlock_t rwlock;

static void *thread_top(void *p1)
{
pthread_t pthread;
uint32_t policy, ret = 0U;
struct sched_param param;
int id = POINTER_TO_INT(p1);

pthread = (pthread_t) pthread_self();
pthread_getschedparam(pthread, &policy, &param);
printk("Thread %d scheduling policy = %d & priority %d started\n",
id, policy, param.sched_priority);
int ret;
pthread_t id;

id = (pthread_t)pthread_self();
ret = pthread_rwlock_tryrdlock(&rwlock);
if (ret) {
printk("Not able to get RD lock on trying, try again\n");
zassert_false(pthread_rwlock_rdlock(&rwlock),
"Failed to acquire write lock");
if (ret != 0) {
LOG_DBG("Not able to get RD lock on trying, try again");
zassert_ok(pthread_rwlock_rdlock(&rwlock), "Failed to acquire write lock");
}

printk("Thread %d got RD lock\n", id);
LOG_DBG("Thread %d got RD lock", id);
usleep(USEC_PER_MSEC);
printk("Thread %d releasing RD lock\n", id);
zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock");
LOG_DBG("Thread %d releasing RD lock", id);
zassert_ok(pthread_rwlock_unlock(&rwlock), "Failed to unlock");

printk("Thread %d acquiring WR lock\n", id);
LOG_DBG("Thread %d acquiring WR lock", id);
ret = pthread_rwlock_trywrlock(&rwlock);
if (ret != 0U) {
zassert_false(pthread_rwlock_wrlock(&rwlock),
"Failed to acquire WR lock");
if (ret != 0) {
zassert_ok(pthread_rwlock_wrlock(&rwlock), "Failed to acquire WR lock");
}

printk("Thread %d acquired WR lock\n", id);
LOG_DBG("Thread %d acquired WR lock", id);
usleep(USEC_PER_MSEC);
printk("Thread %d releasing WR lock\n", id);
zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock");
pthread_exit(NULL);
LOG_DBG("Thread %d releasing WR lock", id);
zassert_ok(pthread_rwlock_unlock(&rwlock), "Failed to unlock");

return NULL;
}

ZTEST(posix_apis, test_rw_lock)
{
int32_t i, ret;
pthread_attr_t attr[N_THR];
struct sched_param schedparam;
int ret;
pthread_t newthread[N_THR];
struct timespec time;
void *status;
Expand All @@ -75,72 +66,53 @@ ZTEST(posix_apis, test_rw_lock)
zassert_equal(pthread_rwlock_timedrdlock(&rwlock, &time), EINVAL);
zassert_equal(pthread_rwlock_unlock(&rwlock), EINVAL);

zassert_false(pthread_rwlock_init(&rwlock, NULL),
"Failed to create rwlock");
printk("\nmain acquire WR lock and 3 threads acquire RD lock\n");
zassert_false(pthread_rwlock_timedwrlock(&rwlock, &time),
"Failed to acquire write lock");
zassert_ok(pthread_rwlock_init(&rwlock, NULL), "Failed to create rwlock");
LOG_DBG("main acquire WR lock and 3 threads acquire RD lock");
zassert_ok(pthread_rwlock_timedwrlock(&rwlock, &time), "Failed to acquire write lock");

/* Creating N preemptive threads in increasing order of priority */
for (i = 0; i < N_THR; i++) {
zassert_equal(pthread_attr_init(&attr[i]), 0,
"Unable to create pthread object attrib");

/* Setting scheduling priority */
schedparam.sched_priority = i + 1;
pthread_attr_setschedparam(&attr[i], &schedparam);

/* Setting stack */
pthread_attr_setstack(&attr[i], &stack[i][0], STACKSZ);

ret = pthread_create(&newthread[i], &attr[i], thread_top,
INT_TO_POINTER(i));
zassert_false(ret, "Low memory to thread new thread");

for (int i = 0; i < N_THR; i++) {
zassert_ok(pthread_create(&newthread[i], NULL, thread_top, NULL),
"Low memory to thread new thread");
}

/* Delay to give change to child threads to run */
usleep(USEC_PER_MSEC);
printk("Parent thread releasing WR lock\n");
zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock");
LOG_DBG("Parent thread releasing WR lock");
zassert_ok(pthread_rwlock_unlock(&rwlock), "Failed to unlock");

/* Let child threads acquire RD Lock */
usleep(USEC_PER_MSEC);
printk("Parent thread acquiring WR lock again\n");
LOG_DBG("Parent thread acquiring WR lock again");

time.tv_sec = 2;
time.tv_nsec = 0;
ret = pthread_rwlock_timedwrlock(&rwlock, &time);

if (ret) {
zassert_false(pthread_rwlock_wrlock(&rwlock),
"Failed to acquire write lock");
zassert_ok(pthread_rwlock_wrlock(&rwlock), "Failed to acquire write lock");
}

printk("Parent thread acquired WR lock again\n");
LOG_DBG("Parent thread acquired WR lock again");
usleep(USEC_PER_MSEC);
printk("Parent thread releasing WR lock again\n");
zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock");
LOG_DBG("Parent thread releasing WR lock again");
zassert_ok(pthread_rwlock_unlock(&rwlock), "Failed to unlock");

printk("\n3 threads acquire WR lock\n");
printk("Main thread acquiring RD lock\n");
LOG_DBG("3 threads acquire WR lock");
LOG_DBG("Main thread acquiring RD lock");

ret = pthread_rwlock_timedrdlock(&rwlock, &time);

if (ret != 0) {
zassert_false(pthread_rwlock_rdlock(&rwlock), "Failed to lock");
zassert_ok(pthread_rwlock_rdlock(&rwlock), "Failed to lock");
}

printk("Main thread acquired RD lock\n");
LOG_DBG("Main thread acquired RD lock");
usleep(USEC_PER_MSEC);
printk("Main thread releasing RD lock\n");
zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock");
LOG_DBG("Main thread releasing RD lock");
zassert_ok(pthread_rwlock_unlock(&rwlock), "Failed to unlock");

for (i = 0; i < N_THR; i++) {
zassert_false(pthread_join(newthread[i], &status),
"Failed to join");
for (int i = 0; i < N_THR; i++) {
zassert_ok(pthread_join(newthread[i], &status), "Failed to join");
}

zassert_false(pthread_rwlock_destroy(&rwlock),
"Failed to destroy rwlock");
zassert_ok(pthread_rwlock_destroy(&rwlock), "Failed to destroy rwlock");
}

0 comments on commit 80e3f4a

Please sign in to comment.