posix: mutexattr: improvements for pthread_mutexattr_t

Previously, pthread_mutexattr_gettype() and
pthread_mutexattr_settype() were non-conformant and also
less safe, as they would not check whether a pthread_mutexattr_t
had been initialized prior to manipulating them. Furthermore,
they would potentially dereference NULL pointers.

Additionally, move the pthread_mutexattr_init() and
pthread_mutexattr_destroy() functions to the library, and add
some level of checking to them so that they are more than simply
static inline / no-op calls.

Lastly, reduce the size of struct pthread_mutexattr to only
what is necessary (one byte should suffice).

Signed-off-by: Christopher Friedt <cfriedt@meta.com>
This commit is contained in:
Christopher Friedt 2024-02-18 10:37:44 -05:00 committed by Chris Friedt
commit ec27e8875d
3 changed files with 52 additions and 25 deletions

View file

@ -60,7 +60,8 @@ typedef struct k_sem sem_t;
typedef uint32_t pthread_mutex_t; typedef uint32_t pthread_mutex_t;
struct pthread_mutexattr { struct pthread_mutexattr {
int type; unsigned char type: 2;
bool initialized: 1;
}; };
#if defined(CONFIG_MINIMAL_LIBC) || defined(CONFIG_PICOLIBC) || defined(CONFIG_ARMCLANG_STD_LIBC) \ #if defined(CONFIG_MINIMAL_LIBC) || defined(CONFIG_PICOLIBC) || defined(CONFIG_ARMCLANG_STD_LIBC) \
|| defined(CONFIG_ARCMWDT_LIBC) || defined(CONFIG_ARCMWDT_LIBC)

View file

@ -253,12 +253,7 @@ int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
* *
* Note that pthread attribute structs are currently noops in Zephyr. * Note that pthread attribute structs are currently noops in Zephyr.
*/ */
static inline int pthread_mutexattr_init(pthread_mutexattr_t *m) int pthread_mutexattr_init(pthread_mutexattr_t *attr);
{
ARG_UNUSED(m);
return 0;
}
/** /**
* @brief POSIX threading compatibility API * @brief POSIX threading compatibility API
@ -267,12 +262,7 @@ static inline int pthread_mutexattr_init(pthread_mutexattr_t *m)
* *
* Note that pthread attribute structs are currently noops in Zephyr. * Note that pthread attribute structs are currently noops in Zephyr.
*/ */
static inline int pthread_mutexattr_destroy(pthread_mutexattr_t *m) int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
{
ARG_UNUSED(m);
return 0;
}
/** /**
* @brief Declare a pthread barrier * @brief Declare a pthread barrier

View file

@ -311,16 +311,48 @@ int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr,
return 0; return 0;
} }
int pthread_mutexattr_init(pthread_mutexattr_t *attr)
{
struct pthread_mutexattr *const a = (struct pthread_mutexattr *)attr;
if (a == NULL) {
return EINVAL;
}
a->type = PTHREAD_MUTEX_DEFAULT;
a->initialized = true;
return 0;
}
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
{
struct pthread_mutexattr *const a = (struct pthread_mutexattr *)attr;
if (a == NULL || !a->initialized) {
return EINVAL;
}
*a = (struct pthread_mutexattr){0};
return 0;
}
/** /**
* @brief Read type attribute for mutex. * @brief Read type attribute for mutex.
* *
* See IEEE 1003.1 * See IEEE 1003.1
*/ */
int pthread_mutexattr_gettype(const pthread_mutexattr_t *_attr, int *type) int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
{ {
const struct pthread_mutexattr *attr = (const struct pthread_mutexattr *)_attr; const struct pthread_mutexattr *a = (const struct pthread_mutexattr *)attr;
if (a == NULL || type == NULL || !a->initialized) {
return EINVAL;
}
*type = a->type;
*type = attr->type;
return 0; return 0;
} }
@ -329,19 +361,23 @@ int pthread_mutexattr_gettype(const pthread_mutexattr_t *_attr, int *type)
* *
* See IEEE 1003.1 * See IEEE 1003.1
*/ */
int pthread_mutexattr_settype(pthread_mutexattr_t *_attr, int type) int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
{ {
struct pthread_mutexattr *attr = (struct pthread_mutexattr *)_attr; struct pthread_mutexattr *const a = (struct pthread_mutexattr *)attr;
int retc = EINVAL;
if ((type == PTHREAD_MUTEX_NORMAL) || if (a == NULL || !a->initialized) {
(type == PTHREAD_MUTEX_RECURSIVE) || return EINVAL;
(type == PTHREAD_MUTEX_ERRORCHECK)) {
attr->type = type;
retc = 0;
} }
return retc; switch (type) {
case PTHREAD_MUTEX_NORMAL:
case PTHREAD_MUTEX_RECURSIVE:
case PTHREAD_MUTEX_ERRORCHECK:
a->type = type;
return 0;
default:
return EINVAL;
}
} }
static int pthread_mutex_pool_init(void) static int pthread_mutex_pool_init(void)