tobudos-kernel/core/include/tos_rwlock.h

193 lines
6.7 KiB
C

/*----------------------------------------------------------------------------
* 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_ */