pthread/realtime: export interfaces about pthread ceiling priority

pthread_mutex_setprioceiling and pthread_mutex_getprioceiling refers
https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_setprioceiling.html
Signed-off-by: makejian <makejian@xiaomi.com>
This commit is contained in:
makejian 2024-08-06 23:39:14 +08:00 committed by Xiang Xiao
parent 85f8677e21
commit 3240540952
12 changed files with 354 additions and 45 deletions

View file

@ -279,9 +279,12 @@ typedef struct pthread_cond_s pthread_cond_t;
struct pthread_mutexattr_s
{
uint8_t pshared : 1; /* PTHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED */
#ifdef CONFIG_PRIORITY_INHERITANCE
#if defined(CONFIG_PRIORITY_INHERITANCE) || defined(CONFIG_PRIORITY_PROTECT)
uint8_t proto : 2; /* See PTHREAD_PRIO_* definitions */
#endif
#ifdef CONFIG_PRIORITY_PROTECT
uint8_t ceiling; /* Priority ceiling */
#endif
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
uint8_t type : 2; /* Type of the mutex. See PTHREAD_MUTEX_* definitions */
#endif
@ -612,6 +615,14 @@ int pthread_mutexattr_getrobust(FAR const pthread_mutexattr_t *attr,
FAR int *robust);
int pthread_mutexattr_setrobust(FAR pthread_mutexattr_t *attr,
int robust);
int pthread_mutexattr_getprioceiling(FAR const pthread_mutexattr_t *attr,
FAR int *prioceiling);
int pthread_mutexattr_setprioceiling(FAR pthread_mutexattr_t *attr,
int prioceiling);
int pthread_mutex_getprioceiling(FAR const pthread_mutex_t *mutex,
FAR int *prioceiling);
int pthread_mutex_setprioceiling(FAR pthread_mutex_t *mutex,
int prioceiling, FAR int *old_ceiling);
/* The following routines create, delete, lock and unlock mutexes. */

View file

@ -217,11 +217,15 @@
"pthread_gettid_np","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","pid_t","pthread_t"
"pthread_key_create","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && CONFIG_TLS_NELEM > 0","int","FAR pthread_key_t *","FAR void (*) (void *)|FAR void *"
"pthread_key_delete","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && CONFIG_TLS_NELEM > 0","int","pthread_key_t"
"pthread_mutex_getprioceiling","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_PRIORITY_PROTECT)","int","FAR const pthread_mutex_t *","FAR int *"
"pthread_mutex_lock","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutex_t *"
"pthread_mutex_setprioceiling","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_PRIORITY_PROTECT)","int","FAR pthread_mutex_t *","int","FAR int *"
"pthread_mutexattr_destroy","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutexattr_t *"
"pthread_mutexattr_getprioceiling","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_PRIORITY_PROTECT)","int","FAR pthread_mutexattr_t *","FAR int *"
"pthread_mutexattr_getpshared","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutexattr_t *","FAR int *"
"pthread_mutexattr_gettype","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_PTHREAD_MUTEX_TYPES)","int","FAR const pthread_mutexattr_t *","FAR int *"
"pthread_mutexattr_init","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutexattr_t *"
"pthread_mutexattr_setprioceiling","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_PRIORITY_PROTECT)","int","FAR pthread_mutexattr_t *","int"
"pthread_mutexattr_setpshared","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_mutexattr_t *","int "
"pthread_mutexattr_settype","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_PTHREAD_MUTEX_TYPES)","int","FAR pthread_mutexattr_t *","int"
"pthread_once","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_once_t*","CODE void (*)(void)"

Can't render this file because it has a wrong number of fields in line 3.

View file

@ -79,7 +79,11 @@ if(NOT CONFIG_DISABLE_PTHREAD)
pthread_mutexattr_gettype.c
pthread_mutexattr_setrobust.c
pthread_mutexattr_getrobust.c
pthread_mutexattr_setprioceiling.c
pthread_mutexattr_getprioceiling.c
pthread_mutex_lock.c
pthread_mutex_setprioceiling.c
pthread_mutex_getprioceiling.c
pthread_once.c
pthread_yield.c
pthread_atfork.c

View file

@ -51,7 +51,9 @@ CSRCS += pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c
CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c
CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c
CSRCS += pthread_mutexattr_setrobust.c pthread_mutexattr_getrobust.c
CSRCS += pthread_mutexattr_setprioceiling.c pthread_mutexattr_getprioceiling.c
CSRCS += pthread_mutex_lock.c
CSRCS += pthread_mutex_setprioceiling.c pthread_mutex_getprioceiling.c
CSRCS += pthread_once.c pthread_yield.c pthread_atfork.c
CSRCS += pthread_rwlockattr_init.c pthread_rwlockattr_destroy.c
CSRCS += pthread_rwlockattr_getpshared.c pthread_rwlockattr_setpshared.c

View file

@ -0,0 +1,64 @@
/****************************************************************************
* libs/libc/pthread/pthread_mutex_getprioceiling.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/mutex.h>
#include <pthread.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pthread_mutex_getprioceiling
*
* Description:
* Return the mutex priority ceiling from the mutex.
*
* Input Parameters:
* mutex - The mutex to query
* prioceiling - Location to return the mutex priority ceiling
*
* Returned Value:
* 0, if the mutex type was successfully return in 'prioceiling', or
* EINVAL, if any NULL pointers provided.
*
* Assumptions:
*
****************************************************************************/
int pthread_mutex_getprioceiling(FAR const pthread_mutex_t *mutex,
FAR int *prioceiling)
{
#ifdef CONFIG_PRIORITY_PROTECT
# ifdef CONFIG_PTHREAD_MUTEX_TYPES
return -nxrmutex_getprioceiling(&mutex->mutex, prioceiling);
# else
return -nxmutex_getprioceiling(&mutex->mutex, prioceiling);
# endif
#else
return EINVAL;
#endif
}

View file

@ -0,0 +1,74 @@
/****************************************************************************
* libs/libc/pthread/pthread_mutex_setprioceiling.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/mutex.h>
#include <pthread.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pthread_mutex_setprioceiling
*
* Description:
* Set the priority ceiling of a mutex.
*
* Input Parameters:
* mutex - The mutex in which to set the mutex priority ceiling.
* prioceiling - The mutex priority ceiling value to set.
* old_ceiling - Location to return the mutex ceiling priority set before.
*
* Returned Value:
* 0, indicating the mutex priority ceiling was successfully set, or
* EINVAL, indicating 'mutex' or 'old_ceiling' is NULL, or 'prioceiling'
* is out of range.
*
* Assumptions:
*
****************************************************************************/
int pthread_mutex_setprioceiling(FAR pthread_mutex_t *mutex,
int prioceiling, FAR int *old_ceiling)
{
int ret = EINVAL;
#ifdef CONFIG_PRIORITY_PROTECT
ret = pthread_mutex_lock(mutex);
if (ret != OK)
{
return ret;
}
# ifdef CONFIG_PTHREAD_MUTEX_TYPES
ret = -nxrmutex_setprioceiling(&mutex->mutex, prioceiling, old_ceiling);
# else
ret = -nxmutex_setprioceiling(&mutex->mutex, prioceiling, old_ceiling);
# endif
pthread_mutex_unlock(mutex);
#endif
return ret;
}

View file

@ -0,0 +1,63 @@
/****************************************************************************
* libs/libc/pthread/pthread_mutexattr_getprioceiling.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <pthread.h>
#include <errno.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pthread_mutexattr_getprioceiling
*
* Description:
* Return the mutex ceiling priority from the mutex attributes.
*
* Input Parameters:
* attr - The mutex attributes to query
* prioceiling - Location to return the mutex ceiling priority
*
* Returned Value:
* 0, if the mutex type was successfully return in 'prioceiling', or
* EINVAL, if any NULL pointers provided.
*
* Assumptions:
*
****************************************************************************/
int pthread_mutexattr_getprioceiling(FAR const pthread_mutexattr_t *attr,
FAR int *prioceiling)
{
#ifdef CONFIG_PRIORITY_PROTECT
if (attr != NULL && prioceiling != NULL)
{
*prioceiling = attr->ceiling;
return OK;
}
#endif
return EINVAL;
}

View file

@ -53,13 +53,13 @@ int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr,
{
DEBUGASSERT(attr != NULL && protocol != NULL);
#ifdef CONFIG_PRIORITY_INHERITANCE
#if defined(CONFIG_PRIORITY_INHERITANCE) || defined(CONFIG_PRIORITY_PROTECT)
linfo("Returning %d\n", attr->proto);
*protocol = attr->proto;
#else
linfo("Returning %d\n", PTHREAD_PRIO_NONE);
*protocol = PTHREAD_PRIO_NONE;
#endif /* CONFIG_PRIORITY_INHERITANCE */
#endif /* CONFIG_PRIORITY_INHERITANCE || CONFIG_PRIORITY_PROTECT */
return 0;
}

View file

@ -27,6 +27,7 @@
#include <pthread.h>
#include <errno.h>
#include <debug.h>
#include <sched.h>
/****************************************************************************
* Public Functions
@ -60,6 +61,11 @@ int pthread_mutexattr_init(FAR pthread_mutexattr_t *attr)
{
attr->pshared = 0;
#ifdef CONFIG_PRIORITY_PROTECT
attr->proto = PTHREAD_PRIO_NONE;
attr->ceiling = sched_get_priority_min(SCHED_FIFO);
#endif
#ifdef CONFIG_PRIORITY_INHERITANCE
# ifdef CONFIG_PTHREAD_MUTEX_DEFAULT_PRIO_INHERIT
attr->proto = PTHREAD_PRIO_INHERIT;

View file

@ -0,0 +1,65 @@
/****************************************************************************
* libs/libc/pthread/pthread_mutexattr_setprioceiling.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <pthread.h>
#include <errno.h>
#include <sched.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pthread_mutexattr_setprioceiling
*
* Description:
* Set the mutex ceiling priority in the mutex attributes.
*
* Input Parameters:
* attr - The mutex attributes in which to set the mutex type.
* prioceiling - The mutex ceiling priority value to set.
*
* Returned Value:
* 0, if the mutex type was successfully set in 'attr', or
* EINVAL, if 'attr' is NULL or 'prioceiling' out of range.
*
* Assumptions:
*
****************************************************************************/
int pthread_mutexattr_setprioceiling(FAR pthread_mutexattr_t *attr,
int prioceiling)
{
#ifdef CONFIG_PRIORITY_PROTECT
if (attr && prioceiling >= sched_get_priority_min(SCHED_FIFO) &&
prioceiling <= sched_get_priority_max(SCHED_FIFO))
{
attr->ceiling = prioceiling;
return OK;
}
#endif
return EINVAL;
}

View file

@ -59,15 +59,32 @@ int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr,
switch (protocol)
{
case PTHREAD_PRIO_NONE:
#ifdef CONFIG_PRIORITY_INHERITANCE
#if defined(CONFIG_PRIORITY_INHERITANCE) || defined(CONFIG_PRIORITY_PROTECT)
attr->proto = PTHREAD_PRIO_INHERIT;
#endif
break;
case PTHREAD_PRIO_INHERIT:
attr->proto = protocol;
#ifdef CONFIG_PRIORITY_INHERITANCE
attr->proto = PTHREAD_PRIO_INHERIT;
break;
#else
return ENOTSUP;
#endif /* CONFIG_PRIORITY_INHERITANCE */
return OK;
case PTHREAD_PRIO_PROTECT:
#ifdef CONFIG_PRIORITY_PROTECT
attr->proto = PTHREAD_PRIO_PROTECT;
break;
#else
return ENOTSUP;
#endif /* CONFIG_PRIORITY_PROTECT */
default:
return ENOTSUP;
}
return OK;
}
return EINVAL;

View file

@ -55,62 +55,61 @@
int pthread_mutex_init(FAR pthread_mutex_t *mutex,
FAR const pthread_mutexattr_t *attr)
{
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
uint8_t type = PTHREAD_MUTEX_DEFAULT;
#endif
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
#ifdef CONFIG_PTHREAD_MUTEX_DEFAULT_UNSAFE
uint8_t flags = 0;
#else
uint8_t flags = _PTHREAD_MFLAGS_ROBUST;
#endif
#endif
int ret = OK;
int status;
sinfo("mutex=%p attr=%p\n", mutex, attr);
if (!mutex)
{
ret = EINVAL;
return EINVAL;
}
else
/* Initialize the mutex like a semaphore with initial count = 1 */
status = mutex_init(&mutex->mutex);
if (status < 0)
{
/* Were attributes specified? If so, use them */
return -status;
}
/* Were attributes specified? If so, use them */
if (attr)
{
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
type = attr->type;
mutex->type = attr ? attr->type : PTHREAD_MUTEX_DEFAULT;
#endif
#ifdef CONFIG_PTHREAD_MUTEX_BOTH
flags = attr->robust == PTHREAD_MUTEX_ROBUST ?
_PTHREAD_MFLAGS_ROBUST : 0;
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
mutex->flink = NULL;
# ifdef CONFIG_PTHREAD_MUTEX_BOTH
mutex->flags = attr && attr->robust == PTHREAD_MUTEX_ROBUST ?
_PTHREAD_MFLAGS_ROBUST : 0;
# else
mutex->flags = 0;
# endif
#endif
}
/* Initialize the mutex like a semaphore with initial count = 1 */
status = mutex_init(&mutex->mutex);
#if defined(CONFIG_PRIORITY_INHERITANCE) || defined(CONFIG_PRIORITY_PROTECT)
if (attr)
{
status = mutex_set_protocol(&mutex->mutex, attr->proto);
if (status < 0)
{
ret = -status;
mutex_destroy(&mutex->mutex);
return -status;
}
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
/* Initial internal fields of the mutex */
mutex->flink = NULL;
mutex->flags = flags;
#endif
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
/* Set up attributes unique to the mutex type */
mutex->type = type;
#endif
# ifdef CONFIG_PRIORITY_PROTECT
if (attr->proto == PTHREAD_PRIO_PROTECT)
{
status = mutex_setprioceiling(&mutex->mutex, attr->ceiling, NULL);
if (status < 0)
{
mutex_destroy(&mutex->mutex);
return -status;
}
}
# endif
}
#endif
sinfo("Returning %d\n", ret);
return ret;
return 0;
}