From 36b74bab024b2b3bb4bfbf75c2f098a9e828fcfe Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Fri, 20 Jan 2023 22:06:45 +0800 Subject: [PATCH] libc/pthread: Implement pthread_rwlockattr API https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlockattr_getpshared.html Signed-off-by: Xiang Xiao --- Documentation/reference/user/08_pthread.rst | 8 -- include/pthread.h | 70 +++++++++---- libs/libc/pthread/Make.defs | 2 + .../libc/pthread/pthread_rwlockattr_destroy.c | 64 ++++++++++++ .../pthread/pthread_rwlockattr_getpshared.c | 68 +++++++++++++ libs/libc/pthread/pthread_rwlockattr_init.c | 67 +++++++++++++ .../pthread/pthread_rwlockattr_setpshared.c | 99 +++++++++++++++++++ 7 files changed, 351 insertions(+), 27 deletions(-) create mode 100644 libs/libc/pthread/pthread_rwlockattr_destroy.c create mode 100644 libs/libc/pthread/pthread_rwlockattr_getpshared.c create mode 100644 libs/libc/pthread/pthread_rwlockattr_init.c create mode 100644 libs/libc/pthread/pthread_rwlockattr_setpshared.c diff --git a/Documentation/reference/user/08_pthread.rst b/Documentation/reference/user/08_pthread.rst index 68f94bca63..d951b1f369 100644 --- a/Documentation/reference/user/08_pthread.rst +++ b/Documentation/reference/user/08_pthread.rst @@ -131,14 +131,6 @@ No support for the following pthread interfaces is provided by NuttX: attribute of the mutex attributes object. - ``pthread_mutexattr_setprioceiling``. get and set the prioceiling attribute of the mutex attributes object. - - ``pthread_rwlockattr_destroy``. destroy and initialize the read-write - lock attributes object. - - ``pthread_rwlockattr_getpshared``. get and set the process-shared - attribute of the read-write lock attributes object. - - ``pthread_rwlockattr_init``. destroy and initialize the read-write - lock attributes object. - - ``pthread_rwlockattr_setpshared``. get and set the process-shared - attribute of the read-write lock attributes object. - ``pthread_setconcurrency``. get and set the level of concurrency. .. c:function:: int pthread_attr_init(pthread_attr_t *attr); diff --git a/include/pthread.h b/include/pthread.h index d7d01c2c89..496234e250 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -199,12 +199,12 @@ extern "C" #ifndef __PTHREAD_KEY_T_DEFINED typedef int pthread_key_t; -#define __PTHREAD_KEY_T_DEFINED 1 +# define __PTHREAD_KEY_T_DEFINED 1 #endif #ifndef __PTHREAD_ADDR_T_DEFINED typedef FAR void *pthread_addr_t; -#define __PTHREAD_ADDR_T_DEFINED 1 +# define __PTHREAD_ADDR_T_DEFINED 1 #endif typedef CODE pthread_addr_t (*pthread_startroutine_t)(pthread_addr_t); @@ -238,12 +238,12 @@ struct pthread_attr_s #ifndef __PTHREAD_ATTR_T_DEFINED typedef struct pthread_attr_s pthread_attr_t; -#define __PTHREAD_ATTR_T_DEFINED 1 +# define __PTHREAD_ATTR_T_DEFINED 1 #endif #ifndef __PTHREAD_T_DEFINED typedef pid_t pthread_t; -#define __PTHREAD_T_DEFINED 1 +# define __PTHREAD_T_DEFINED 1 #endif struct pthread_condattr_s @@ -253,7 +253,7 @@ struct pthread_condattr_s #ifndef __PTHREAD_CONDATTR_T_DEFINED typedef struct pthread_condattr_s pthread_condattr_t; -#define __PTHREAD_CONDATTR_T_DEFINED 1 +# define __PTHREAD_CONDATTR_T_DEFINED 1 #endif struct pthread_cond_s @@ -264,7 +264,7 @@ struct pthread_cond_s #ifndef __PTHREAD_COND_T_DEFINED typedef struct pthread_cond_s pthread_cond_t; -#define __PTHREAD_COND_T_DEFINED 1 +# define __PTHREAD_COND_T_DEFINED 1 #endif #define PTHREAD_COND_INITIALIZER {SEM_INITIALIZER(0), CLOCK_REALTIME } @@ -285,7 +285,7 @@ struct pthread_mutexattr_s #ifndef __PTHREAD_MUTEXATTR_T_DEFINED typedef struct pthread_mutexattr_s pthread_mutexattr_t; -#define __PTHREAD_MUTEXATTR_T_DEFINED 1 +# define __PTHREAD_MUTEXATTR_T_DEFINED 1 #endif struct pthread_mutex_s @@ -311,7 +311,7 @@ struct pthread_mutex_s #ifndef __PTHREAD_MUTEX_T_DEFINED typedef struct pthread_mutex_s pthread_mutex_t; -#define __PTHREAD_MUTEX_T_DEFINED 1 +# define __PTHREAD_MUTEX_T_DEFINED 1 #endif #ifndef CONFIG_PTHREAD_MUTEX_UNSAFE @@ -350,7 +350,7 @@ struct pthread_barrierattr_s #ifndef __PTHREAD_BARRIERATTR_T_DEFINED typedef struct pthread_barrierattr_s pthread_barrierattr_t; -#define __PTHREAD_BARRIERATTR_T_DEFINED 1 +# define __PTHREAD_BARRIERATTR_T_DEFINED 1 #endif struct pthread_barrier_s @@ -361,12 +361,22 @@ struct pthread_barrier_s #ifndef __PTHREAD_BARRIER_T_DEFINED typedef struct pthread_barrier_s pthread_barrier_t; -#define __PTHREAD_BARRIER_T_DEFINED 1 +# define __PTHREAD_BARRIER_T_DEFINED 1 #endif #ifndef __PTHREAD_ONCE_T_DEFINED typedef bool pthread_once_t; -#define __PTHREAD_ONCE_T_DEFINED 1 +# define __PTHREAD_ONCE_T_DEFINED 1 +#endif + +struct pthread_rwlockattr_s +{ + int pshared; +}; + +#ifndef __PTHREAD_RWLOCKATTR_T_DEFINED +typedef struct pthread_rwlockattr_s pthread_rwlockattr_t; +# define __PTHREAD_RWLOCKATTR_T_DEFINED 1 #endif struct pthread_rwlock_s @@ -378,9 +388,10 @@ struct pthread_rwlock_s bool write_in_progress; }; +#ifndef __PTHREAD_RWLOCK_T_DEFINED typedef struct pthread_rwlock_s pthread_rwlock_t; - -typedef int pthread_rwlockattr_t; +# define __PTHREAD_RWLOCK_T_DEFINED 1 +#endif #define PTHREAD_RWLOCK_INITIALIZER {PTHREAD_MUTEX_INITIALIZER, \ PTHREAD_COND_INITIALIZER, \ @@ -396,12 +407,12 @@ struct pthread_spinlock_s * SP_UNLOCKED. */ pthread_t sp_holder; /* ID of the thread that holds the spinlock */ }; -#ifndef __PTHREAD_SPINLOCK_T_DEFINED +# ifndef __PTHREAD_SPINLOCK_T_DEFINED /* It is referenced via this standard type */ typedef FAR struct pthread_spinlock_s pthread_spinlock_t; -#define __PTHREAD_SPINLOCK_T_DEFINED 1 -#endif +# define __PTHREAD_SPINLOCK_T_DEFINED 1 +# endif #endif /* CONFIG_PTHREAD_SPINLOCKS */ #ifdef CONFIG_PTHREAD_CLEANUP @@ -651,6 +662,15 @@ int pthread_barrier_wait(FAR pthread_barrier_t *barrier); int pthread_once(FAR pthread_once_t *once_control, CODE void (*init_routine)(void)); +/* Pthread rwlock attributes */ + +int pthread_rwlockattr_init(FAR pthread_rwlockattr_t *attr); +int pthread_rwlockattr_destroy(FAR pthread_rwlockattr_t *attr); +int pthread_rwlockattr_getpshared(FAR const pthread_rwlockattr_t *attr, + FAR int *pshared); +int pthread_rwlockattr_setpshared(FAR pthread_rwlockattr_t *attr, + int pshared); + /* Pthread rwlock */ int pthread_rwlock_destroy(FAR pthread_rwlock_t *rw_lock); @@ -772,12 +792,24 @@ typedef struct pthread_barrier_s pthread_barrier_t; # define __PTHREAD_BARRIER_T_DEFINED 1 #endif +#ifndef __PTHREAD_RWLOCKATTR_T_DEFINED +struct pthread_rwlockattr_s; +typedef struct pthread_rwlockattr_s pthread_rwlockattr_t; +# define __PTHREAD_RWLOCKATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_RWLOCK_T_DEFINED +struct pthread_rwlock_s; +typedef struct pthread_rwlock_s pthread_rwlock_t; +# define __PTHREAD_RWLOCK_T_DEFINED 1 +#endif + #ifdef CONFIG_PTHREAD_SPINLOCKS -#ifndef __PTHREAD_SPINLOCK_T_DEFINED +# ifndef __PTHREAD_SPINLOCK_T_DEFINED struct pthread_spinlock_s; typedef FAR struct pthread_spinlock_s pthread_spinlock_t; -#define __PTHREAD_SPINLOCK_T_DEFINED 1 -#endif +# define __PTHREAD_SPINLOCK_T_DEFINED 1 +# endif #endif /* CONFIG_PTHREAD_SPINLOCKS */ #ifndef __PTHREAD_ONCE_T_DEFINED diff --git a/libs/libc/pthread/Make.defs b/libs/libc/pthread/Make.defs index 3ae2f03c66..0e2e152ea0 100644 --- a/libs/libc/pthread/Make.defs +++ b/libs/libc/pthread/Make.defs @@ -50,6 +50,8 @@ CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c CSRCS += pthread_mutexattr_setrobust.c pthread_mutexattr_getrobust.c CSRCS += pthread_mutex_lock.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 CSRCS += pthread_rwlock.c pthread_rwlock_rdlock.c pthread_rwlock_wrlock.c CSRCS += pthread_setcancelstate.c pthread_setcanceltype.c CSRCS += pthread_testcancel.c diff --git a/libs/libc/pthread/pthread_rwlockattr_destroy.c b/libs/libc/pthread/pthread_rwlockattr_destroy.c new file mode 100644 index 0000000000..6e3889c4c8 --- /dev/null +++ b/libs/libc/pthread/pthread_rwlockattr_destroy.c @@ -0,0 +1,64 @@ +/******************************************************************************** + * libs/libc/pthread/pthread_rwlockattr_destroy.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 + +#include +#include +#include + +/******************************************************************************** + * Public Functions + ********************************************************************************/ + +/******************************************************************************** + * Name: pthread_rwlockattr_destroy + * + * Description: + * The pthread_rwlockattr_destroy() function will destroy a rwlock attributes + * object. A destroyed attr attributes object can be reinitialized using + * pthread_rwlockattr_init(); the results of otherwise referencing the object + * after it has been destroyed are undefined. + * + * Input Parameters: + * attr - rwlock attributes to be destroyed. + * + * Returned Value: + * 0 (OK) on success or EINVAL if attr is invalid. + * + * Assumptions: + * + ********************************************************************************/ + +int pthread_rwlockattr_destroy(FAR pthread_rwlockattr_t *attr) +{ + int ret = OK; + + if (!attr) + { + ret = EINVAL; + } + + return ret; +} diff --git a/libs/libc/pthread/pthread_rwlockattr_getpshared.c b/libs/libc/pthread/pthread_rwlockattr_getpshared.c new file mode 100644 index 0000000000..f68f1a4367 --- /dev/null +++ b/libs/libc/pthread/pthread_rwlockattr_getpshared.c @@ -0,0 +1,68 @@ +/******************************************************************************** + * libs/libc/pthread/pthread_rwlockattr_getpshared.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 + +#include +#include +#include + +/******************************************************************************** + * Public Functions + ********************************************************************************/ + +/******************************************************************************** + * Name: pthread_rwlockattr_getpshared + * + * Description: + * The pthread_rwlockattr_getpshared() function will obtain the value of the + * process-shared attribute from the attributes object referenced by attr. + * + * Input Parameters: + * attr - rwlock attributes to be queried. + * pshared - the location to stored the current value of the pshared attribute. + * + * Returned Value: + * 0 (OK) on success or EINVAL if either attr or pshared is invalid. + * + * Assumptions: + * + ********************************************************************************/ + +int pthread_rwlockattr_getpshared(FAR const pthread_rwlockattr_t *attr, + FAR int *pshared) +{ + int ret = OK; + + if (!attr || !pshared) + { + ret = EINVAL; + } + else + { + *pshared = attr->pshared; + } + + return ret; +} diff --git a/libs/libc/pthread/pthread_rwlockattr_init.c b/libs/libc/pthread/pthread_rwlockattr_init.c new file mode 100644 index 0000000000..8d75b2dece --- /dev/null +++ b/libs/libc/pthread/pthread_rwlockattr_init.c @@ -0,0 +1,67 @@ +/******************************************************************************** + * libs/libc/pthread/pthread_rwlockattr_init.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 + +#include +#include +#include + +/******************************************************************************** + * Public Functions + ********************************************************************************/ + +/******************************************************************************** + * Name: pthread_rwlockattr_init + * + * Description: + * The pthread_rwlockattr_init() function will initialize a rwlock attribute + * object attr with the default value for all of the attributes defined by the + * implementation. + * + * Input Parameters: + * attr - rwlock attributes to be initialized. + * + * Returned Value: + * 0 (OK) on success or EINVAL if attr is invalid. + * + * Assumptions: + * + ********************************************************************************/ + +int pthread_rwlockattr_init(FAR pthread_rwlockattr_t *attr) +{ + int ret = OK; + + if (!attr) + { + ret = EINVAL; + } + else + { + attr->pshared = PTHREAD_PROCESS_PRIVATE; + } + + return ret; +} diff --git a/libs/libc/pthread/pthread_rwlockattr_setpshared.c b/libs/libc/pthread/pthread_rwlockattr_setpshared.c new file mode 100644 index 0000000000..a3c35d3c34 --- /dev/null +++ b/libs/libc/pthread/pthread_rwlockattr_setpshared.c @@ -0,0 +1,99 @@ +/******************************************************************************** + * libs/libc/pthread/pthread_rwlockattr_setpshared.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 + +#include +#include +#include + +/******************************************************************************** + * Pre-processor Definitions + ********************************************************************************/ + +/******************************************************************************** + * Private Type Declarations + ********************************************************************************/ + +/******************************************************************************** + * Public Data + ********************************************************************************/ + +/******************************************************************************** + * Private Data + ********************************************************************************/ + +/******************************************************************************** + * Private Function Prototypes + ********************************************************************************/ + +/******************************************************************************** + * Public Functions + ********************************************************************************/ + +/******************************************************************************** + * Name: pthread_rwlockattr_setpshared + * + * Description: + * The process-shared attribute is set to PTHREAD_PROCESS_SHARED to permit + * a rwlock to be operated upon by any thread that has access to the + * memory where the rwlock is allocated. If the process-shared attribute + * is PTHREAD_PROCESS_PRIVATE, the rwlock can only be operated upon by + * threads created within the same process as the thread that initialized + * the rwlock. + * If threads of different processes attempt to operate on such a rwlock, + * the behavior is undefined. The default value of the attribute is + * PTHREAD_PROCESS_PRIVATE. + * + * Both constants PTHREAD_PROCESS_SHARED and PTHREAD_PROCESS_PRIVATE are + * defined in pthread.h. + * + * Input Parameters: + * attr - rwlock attributes to be modified. + * pshared - the new value of the pshared attribute. + * + * Returned Value: + * 0 (OK) on success or EINVAL if either attr is invalid or pshared is not + * one of PTHREAD_PROCESS_SHARED or PTHREAD_PROCESS_PRIVATE. + * + * Assumptions: + * + ********************************************************************************/ + +int pthread_rwlockattr_setpshared(FAR pthread_rwlockattr_t *attr, int pshared) +{ + int ret = OK; + + if (!attr || (pshared != PTHREAD_PROCESS_SHARED && + pshared != PTHREAD_PROCESS_PRIVATE)) + { + ret = EINVAL; + } + else + { + attr->pshared = pshared; + } + + return ret; +}