/*---------------------------------------------------------------------------- * Tencent is pleased to support the open source community by making TencentOS * available. * * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. * If you have downloaded a copy of the TencentOS binary from Tencent, please * note that the TencentOS binary is licensed under the BSD 3-Clause License. * * If you have downloaded a copy of the TencentOS source code from Tencent, * please note that TencentOS source code is licensed under the BSD 3-Clause * License, except for the third-party components listed below which are * subject to different license terms. Your integration of TencentOS into your * own projects may require compliance with the BSD 3-Clause License, as well * as the other licenses applicable to the third-party components included * within TencentOS. *---------------------------------------------------------------------------*/ #ifndef _TOS_RWLOCK_H_ #define _TOS_RWLOCK_H_ __CDECLS_BEGIN #if (TOS_CFG_SEM_EN > 0u) && (TOS_CFG_MUTEX_EN > 0u) typedef uint16_t rw_cnt_t; typedef struct k_rwlock_st { knl_obj_t knl_obj; k_mutex_t lock; k_sem_t signal; rw_cnt_t n_readers; /* how many readers are reading? */ rw_cnt_t n_writers; /* how many writers are waiting to obtain the wlock? */ int is_writting; } k_rwlock_t; /** * @brief Create a read-write lock. * * @attention a read-write lock can be hold by multi-readers, that means simultaneously reading is allowed; * but a read-write lock can only be hold by one writes, that means simultaneously writting or read while writting is not allowed. * * @param[in] rwlock the read-write lock. * * @return errcode * @retval #K_ERR_NONE return successfully. */ __API__ k_err_t tos_rwlock_create(k_rwlock_t *rwlock); /** * @brief Destroy a read-write lock. * * @attention * * @param[in] rwlock the read-write lock. * * @return errcode * @retval #K_ERR_NONE return successfully. */ __API__ k_err_t tos_rwlock_destroy(k_rwlock_t *rwlock); /** * @brief Pend on the read-lock of a read-write lock. * * @attention if one reader already hold the read-lock, other reader can hold the read-lock simultaneously. * and no writers can hold the write-lock. * * @param[in] rwlock the read-write lock. * @param[in] timeout how much time(in k_tick_t) we would like to wait. * * @return errcode * @retval #K_ERR_NONE return successfully. * @retval #K_ERR_RWLOCK_READERS_TO_MANY too many reader are holding the read-lock */ __API__ k_err_t tos_rwlock_rpend_timed(k_rwlock_t *rwlock, k_tick_t timeout); /** * @brief Pend on the read-lock of a read-write lock. * * @attention if one reader already hold the read-lock, other reader can hold the read-lock simultaneously. * and no writers can hold the write-lock. * * @param[in] rwlock the read-write lock. * * @return errcode * @retval #K_ERR_NONE return successfully. * @retval #K_ERR_RWLOCK_READERS_TO_MANY too many reader are holding the read-lock */ __API__ k_err_t tos_rwlock_rpend(k_rwlock_t *rwlock); /** * @brief Try pend on the read-lock of a read-write lock. * * @attention Try means just take a look, if can obtain the read-lock, then we obtain it; otherwise, just return with no-waiting. * * @param[in] rwlock the read-write lock. * * @return errcode * @retval #K_ERR_NONE return successfully. * @retval #K_ERR_RWLOCK_IS_WRITTING the read-write lock is hold by a writter(is writting). */ __API__ k_err_t tos_rwlock_rpend_try(k_rwlock_t *rwlock); /** * @brief Pend on the write-lock of a read-write lock. * * @attention if one writer already hold the write-lock, other writer CANNOT hold the write-lock any more. * and no readers can hold the read-lock. * * @param[in] rwlock the read-write lock. * @param[in] timeout how much time(in k_tick_t) we would like to wait. * * @return errcode * @retval #K_ERR_NONE return successfully. * @retval #K_ERR_RWLOCK_WAITING_WRITERS_TO_MANY too many writers are waiting for the write-lock */ __API__ k_err_t tos_rwlock_wpend_timed(k_rwlock_t *rwlock, k_tick_t timeout); /** * @brief Pend on the write-lock of a read-write lock. * * @attention if one writer already hold the write-lock, other writer CANNOT hold the write-lock any more. * and no readers can hold the read-lock. * * @param[in] rwlock the read-write lock. * * @return errcode * @retval #K_ERR_NONE return successfully. * @retval #K_ERR_RWLOCK_WAITING_WRITERS_TO_MANY too many writers are waiting for the write-lock */ __API__ k_err_t tos_rwlock_wpend(k_rwlock_t *rwlock); /** * @brief Pend on the write-lock of a read-write lock. * * @attention Try means just take a look, if can obtain the write-lock, then we obtain it; otherwise, just return with no-waiting. * * @param[in] rwlock the read-write lock. * * @return errcode * @retval #K_ERR_NONE return successfully. * @retval #K_ERR_RWLOCK_IS_READING the read-write lock is hold by other reader[s](is reading). * @retval #K_ERR_RWLOCK_IS_WRITTING the read-write lock is hold by another writter(is writting). */ __API__ k_err_t tos_rwlock_wpend_try(k_rwlock_t *rwlock); /** * @brief Post the read-lock of a read-write lock. * * @attention * * @param[in] rwlock the read-write lock. * * @return errcode * @retval #K_ERR_NONE return successfully. * @retval #K_ERR_RWLOCK_NOT_READING the read-lock is not held by reader[s]. */ __API__ k_err_t tos_rwlock_rpost(k_rwlock_t *rwlock); /** * @brief Post the write-lock of a read-write lock. * * @attention * * @param[in] rwlock the read-write lock. * * @return errcode * @retval #K_ERR_NONE return successfully. * @retval #K_ERR_RWLOCK_NOT_WRITTING the write-lock is not held by a writter. */ __API__ k_err_t tos_rwlock_wpost(k_rwlock_t *rwlock); /** * @brief Post the read&write-lock of a read-write lock. * * @attention * * @param[in] rwlock the read-write lock. * * @return errcode * @retval #K_ERR_NONE return successfully. * @retval #K_ERR_RWLOCK_NOT_TAKEN the read-write lock is neither held by reader[s] nor held by a writter. */ __API__ k_err_t tos_rwlock_post(k_rwlock_t *rwlock); #endif __CDECLS_END #endif /* _TOS_RWLOCK_H_ */