Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

posix: implement pthread_attr_getscope() and pthread_attr_setscope() #68450

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/services/portability/posix/option_groups/index.rst
Expand Up @@ -440,10 +440,10 @@ _POSIX_THREAD_PRIORITY_SCHEDULING

pthread_attr_getinheritsched(),
pthread_attr_getschedpolicy(),yes
pthread_attr_getscope(),
pthread_attr_getscope(),yes
pthread_attr_setinheritsched(),
pthread_attr_setschedpolicy(),yes
pthread_attr_setscope(),
pthread_attr_setscope(),yes
pthread_getschedparam(),yes
pthread_setschedparam(),yes
pthread_setschedprio(),yes
Expand Down
8 changes: 8 additions & 0 deletions include/zephyr/posix/pthread.h
Expand Up @@ -39,6 +39,12 @@ extern "C" {
#define PTHREAD_CANCEL_DEFERRED 0
#define PTHREAD_CANCEL_ASYNCHRONOUS 1

/* Pthread scope */
#undef PTHREAD_SCOPE_PROCESS
cfriedt marked this conversation as resolved.
Show resolved Hide resolved
#define PTHREAD_SCOPE_PROCESS 1
#undef PTHREAD_SCOPE_SYSTEM
#define PTHREAD_SCOPE_SYSTEM 0

/* Passed to pthread_once */
#define PTHREAD_ONCE_INIT {0}

Expand Down Expand Up @@ -429,6 +435,8 @@ int pthread_attr_getstack(const pthread_attr_t *attr,
void **stackaddr, size_t *stacksize);
int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr,
size_t stacksize);
int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope);
int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);
#ifdef CONFIG_PTHREAD_IPC
int pthread_once(pthread_once_t *once, void (*initFunc)(void));
#endif
Expand Down
1 change: 1 addition & 0 deletions lib/posix/options/posix_internal.h
Expand Up @@ -29,6 +29,7 @@ struct posix_thread_attr {
uint16_t guardsize : CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_BITS;
int8_t priority;
uint8_t schedpolicy: 2;
bool contentionscope: 1;
union {
bool caller_destroys: 1;
bool initialized: 1;
Expand Down
44 changes: 44 additions & 0 deletions lib/posix/options/pthread.c
Expand Up @@ -384,6 +384,49 @@ int pthread_attr_setstack(pthread_attr_t *_attr, void *stackaddr, size_t stacksi
return 0;
}

/**
* @brief Get scope attributes in thread attributes object.
*
* See IEEE 1003.1
*/
int pthread_attr_getscope(const pthread_attr_t *_attr, int *contentionscope)
{
struct posix_thread_attr *attr = (struct posix_thread_attr *)_attr;

if (!__attr_is_initialized(attr) || contentionscope == NULL) {
return EINVAL;
}
*contentionscope = attr->contentionscope;
return 0;
}

/**
* @brief Set scope attributes in thread attributes object.
*
* See IEEE 1003.1
*/
int pthread_attr_setscope(pthread_attr_t *_attr, int contentionscope)
{
struct posix_thread_attr *attr = (struct posix_thread_attr *)_attr;

if (!__attr_is_initialized(attr)) {
LOG_DBG("attr %p is not initialized", attr);
return EINVAL;
}
if (!(contentionscope == PTHREAD_SCOPE_PROCESS ||
contentionscope == PTHREAD_SCOPE_SYSTEM)) {
LOG_DBG("%s contentionscope %d", "Invalid", contentionscope);
return EINVAL;
}
if (contentionscope == PTHREAD_SCOPE_PROCESS) {
/* Zephyr does not yet support processes or process scheduling */
LOG_DBG("%s contentionscope %d", "Unsupported", contentionscope);
return ENOTSUP;
}
attr->contentionscope = contentionscope;
cfriedt marked this conversation as resolved.
Show resolved Hide resolved
return 0;
}

static void posix_thread_recycle_work_handler(struct k_work *work)
{
ARG_UNUSED(work);
Expand Down Expand Up @@ -797,6 +840,7 @@ int pthread_attr_init(pthread_attr_t *_attr)

*attr = (struct posix_thread_attr){0};
attr->guardsize = CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_DEFAULT;
attr->contentionscope = PTHREAD_SCOPE_SYSTEM;

if (DYNAMIC_STACK_SIZE > 0) {
attr->stack = k_thread_stack_alloc(DYNAMIC_STACK_SIZE + attr->guardsize,
Expand Down
42 changes: 42 additions & 0 deletions tests/posix/common/src/pthread_attr.c
Expand Up @@ -439,6 +439,48 @@ ZTEST(pthread_attr, test_pthread_attr_setstacksize)
}
}

ZTEST(pthread_attr, test_pthread_attr_getscope)
{
int contentionscope = BIOS_FOOD;

/* degenerate cases */
{
if (false) {
/* undefined behaviour */
zassert_equal(pthread_attr_getscope(NULL, NULL), EINVAL);
zassert_equal(pthread_attr_getscope(NULL, &contentionscope), EINVAL);
zassert_equal(pthread_attr_getscope(&uninit_attr, &contentionscope),
EINVAL);
}
zassert_equal(pthread_attr_getscope(&attr, NULL), EINVAL);
}

zassert_ok(pthread_attr_getscope(&attr, &contentionscope));
zassert_equal(contentionscope, PTHREAD_SCOPE_SYSTEM);
}

ZTEST(pthread_attr, test_pthread_attr_setscope)
{
int contentionscope = BIOS_FOOD;

/* degenerate cases */
{
if (false) {
/* undefined behaviour */
zassert_equal(pthread_attr_setscope(NULL, PTHREAD_SCOPE_SYSTEM), EINVAL);
zassert_equal(pthread_attr_setscope(NULL, contentionscope), EINVAL);
zassert_equal(pthread_attr_setscope((pthread_attr_t *)&uninit_attr,
contentionscope), EINVAL);
}
zassert_equal(pthread_attr_setscope(&attr, 3), EINVAL);
}

zassert_equal(pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS), ENOTSUP);
zassert_ok(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM));
zassert_ok(pthread_attr_getscope(&attr, &contentionscope));
zassert_equal(contentionscope, PTHREAD_SCOPE_SYSTEM);
}

ZTEST(pthread_attr, test_pthread_attr_large_stacksize)
{
size_t actual_size;
Expand Down
8 changes: 4 additions & 4 deletions tests/posix/headers/src/pthread_h.c
Expand Up @@ -53,8 +53,8 @@ ZTEST(posix_headers, test_pthread_h)
zassert_not_equal(-1, PTHREAD_PROCESS_SHARED);
zassert_not_equal(-1, PTHREAD_PROCESS_PRIVATE);

/* zassert_not_equal(-1, PTHREAD_SCOPE_PROCESS); */ /* not implemented */
/* zassert_not_equal(-1, PTHREAD_SCOPE_SYSTEM); */ /* not implemented */
zassert_not_equal(-1, PTHREAD_SCOPE_PROCESS);
zassert_not_equal(-1, PTHREAD_SCOPE_SYSTEM);

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
Expand All @@ -68,7 +68,7 @@ ZTEST(posix_headers, test_pthread_h)
/* zassert_not_null(pthread_attr_getinheritsched); */ /* not implemented */
zassert_not_null(pthread_attr_getschedparam);
zassert_not_null(pthread_attr_getschedpolicy);
/* zassert_not_null(pthread_attr_getscope); */ /* not implemented */
zassert_not_null(pthread_attr_getscope);
zassert_not_null(pthread_attr_getstack);
zassert_not_null(pthread_attr_getstacksize);
zassert_not_null(pthread_attr_init);
Expand All @@ -77,7 +77,7 @@ ZTEST(posix_headers, test_pthread_h)
/* zassert_not_null(pthread_attr_setinheritsched); */ /* not implemented */
zassert_not_null(pthread_attr_setschedparam);
zassert_not_null(pthread_attr_setschedpolicy);
/* zassert_not_null(pthread_attr_setscope); */ /* not implemented */
zassert_not_null(pthread_attr_setscope);
zassert_not_null(pthread_attr_setstack);
zassert_not_null(pthread_attr_setstacksize);
zassert_not_null(pthread_barrier_destroy);
Expand Down