| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- /*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: fsemaphore.c
- * Date: 2022-02-10 14:53:42
- * LastEditTime: 2022-02-18 08:25:29
- * Description: This files is for semaphore user api implmentation
- *
- * Modify History:
- * Ver Who Date Changes
- * ----- ------ -------- --------------------------------------
- * 1.0 zhugengyu 2022/5/23 init commit
- */
- /***************************** Include Files *********************************/
- #include <string.h>
- #include "fio.h"
- #include "ferror_code.h"
- #include "ftypes.h"
- #include "fdebug.h"
- #include "fassert.h"
- #include "fsemaphore_hw.h"
- #include "fsemaphore.h"
- /************************** Constant Definitions *****************************/
- /**************************** Type Definitions *******************************/
- /***************** Macros (Inline Functions) Definitions *********************/
- #define FSEMA_DEBUG_TAG "SEMA"
- #define FSEMA_ERROR(format, ...) FT_DEBUG_PRINT_E(FSEMA_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FSEMA_WARN(format, ...) FT_DEBUG_PRINT_W(FSEMA_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FSEMA_INFO(format, ...) FT_DEBUG_PRINT_I(FSEMA_DEBUG_TAG, format, ##__VA_ARGS__)
- #define FSEMA_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSEMA_DEBUG_TAG, format, ##__VA_ARGS__)
- /************************** Function Prototypes ******************************/
- /************************** Variable Definitions *****************************/
- /*****************************************************************************/
- /**
- * @name: FSemaCfgInitialize
- * @msg: 初始化Semaphore控制器
- * @return {FError} FSEMA_SUCCESS 表示初始化成功
- * @param {FSema} *instance, Semaphore控制器实例
- * @param {FSemaConfig} *input_config, Semaphore控制器配置
- */
- FError FSemaCfgInitialize(FSema *const instance, const FSemaConfig *input_config)
- {
- FASSERT(instance && input_config);
- uintptr base_addr = input_config->base_addr;
- FASSERT_MSG((0 != base_addr), "invalid base addr");
- FError ret = FSEMA_SUCCESS;
- if (FT_COMPONENT_IS_READY == instance->is_ready)
- {
- FSEMA_WARN("device is already initialized!!!");
- }
- if (&instance->config != input_config)
- instance->config = *input_config;
- FSemaHwResetAll(base_addr); /* 重置所有的锁 */
- if (FSEMA_SUCCESS == ret)
- instance->is_ready = FT_COMPONENT_IS_READY;
- return ret;
- }
- /**
- * @name: FSemaDeInitialize
- * @msg: 去初始化Semaphore控制器
- * @return {void} 无
- * @param {FSema} *instance, Semaphore控制器实例
- */
- void FSemaDeInitialize(FSema *const instance)
- {
- FASSERT(instance);
- u32 loop;
- uintptr base_addr = instance->config.base_addr;
- for (loop = 0; loop < FSEMA_NUM_OF_LOCKER; loop++)
- {
- if (NULL != instance->locker[loop])
- {
- FSEMA_WARN("locker %d @%p is not yet deleted !!!", loop, instance->locker[loop]);
- memset(instance->locker[loop], 0, sizeof(*instance->locker[loop]));
- }
- }
- if (0 != base_addr) /* 如果base addr为0,实例可能还没有初始化 */
- {
- FSemaHwResetAll(base_addr);
- }
- memset(instance, 0, sizeof(*instance));
- return;
- }
- /**
- * @name: FSemaCreateLocker
- * @msg: 分配和创建Semaphore锁
- * @return {FError} FSEMA_SUCCESS 表示分配成功
- * @param {FSema} *instance, Semaphore控制器实例
- * @param {FSemaLocker} *locker, Semaphore锁的实例
- */
- FError FSemaCreateLocker(FSema *const instance, FSemaLocker *const locker)
- {
- FASSERT(instance && locker);
- u32 locker_idx;
- if (FT_COMPONENT_IS_READY != instance->is_ready)
- {
- FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
- return FSEMA_ERR_NOT_INIT;
- }
- for (locker_idx = 0; locker_idx < FSEMA_NUM_OF_LOCKER; locker_idx++)
- {
- /* 分配一把未创建的锁 */
- if (NULL == instance->locker[locker_idx])
- {
- FSEMA_INFO("allocate locker %d", locker_idx);
- break;
- }
- }
- if (locker_idx >= FSEMA_NUM_OF_LOCKER)
- {
- FSEMA_ERROR("no locker available !!!");
- return FSEMA_ERR_NO_AVAILABLE_LOCKER; /* 所有的锁都已经分配创建 */
- }
- instance->locker[locker_idx] = locker;
- locker->index = locker_idx; /* 分配锁,将锁的实例挂在控制器实例上 */
- locker->owner = FSEMA_OWNER_NONE; /* 当前锁还没有owner */
- locker->name[0] = '\0';
- locker->sema = instance;
- return FSEMA_SUCCESS;
- }
- /**
- * @name: FSemaTryLock
- * @msg: 尝试获取Semaphore锁
- * @return {FError} FSEMA_SUCCESS 表示成功获取锁,FSEMA_ERR_LOCK_TIMEOUT 表示锁已经被占用
- * @param {FSemaLocker} *locker, Semaphore锁的实例
- * @param {u32} owner, 当前尝试获取锁的是谁
- * @param {u32} try_times, 尝试获取的次数
- * @param {FSemaRelaxHandler} relax_handler, 每次尝试获取锁失败后的relax函数
- */
- FError FSemaTryLock(FSemaLocker *const locker, u32 owner, u32 try_times, FSemaRelaxHandler relax_handler)
- {
- FASSERT(locker && locker->sema);
- FSema *const instance = locker->sema;
- uintptr base_addr = instance->config.base_addr;
- boolean lock_success = FALSE;
- FError ret = FSEMA_SUCCESS;
- if (FT_COMPONENT_IS_READY != instance->is_ready)
- {
- FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
- return FSEMA_ERR_NOT_INIT;
- }
- while (try_times > 0)
- {
- /* 尝试获取锁 */
- lock_success = FSemaTryLockOnce(base_addr, locker->index);
- if (TRUE == lock_success)
- break;
- if (relax_handler)
- relax_handler(instance);
- try_times--;
- }
- if (FALSE == lock_success)
- {
- ret = FSEMA_ERR_LOCK_TIMEOUT;
- FSEMA_ERROR("locker-%d has been taken by owner 0x%x", locker->index, locker->owner);
- }
- else
- {
- locker->owner = owner; /* 记录当前locker的owner */
- FSEMA_INFO("locker-%d taken success by owner 0x%x", locker->index, owner);
- }
- return ret;
- }
- /**
- * @name: FSemaUnlock
- * @msg: 尝试释放Semaphore锁
- * @return {FError} FSEMA_SUCCESS释放锁成功
- * @param {FSemaLocker} *locker, Semaphore锁实例
- * @param {u32} owner, 当前尝试释放锁的身份
- */
- FError FSemaUnlock(FSemaLocker *const locker, u32 owner)
- {
- FASSERT(locker && locker->sema);
- FSema *const instance = locker->sema;
- uintptr base_addr = instance->config.base_addr;
- FError ret = FSEMA_SUCCESS;
- u32 reg_val;
- if (FT_COMPONENT_IS_READY != instance->is_ready)
- {
- FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
- return FSEMA_ERR_NOT_INIT;
- }
- if (locker->owner != owner)
- {
- FSEMA_ERROR("locker is owned by 0x%x, 0x%x has no premission to unlock it !!!",
- locker->owner, owner);
- return FSEMA_ERR_NO_PERMISSION;
- }
- if (FALSE == FSemaHwGetStatus(base_addr, locker->index))
- {
- FSEMA_INFO("locker-%d is not in locked status 0x%x!!!",
- locker->index, FSemaReadReg(base_addr, FSEMA_STATE_REG_OFFSET));
- return ret;
- }
- reg_val = FSEMA_RLOCK_X_UNLOCK;
- FSemaWriteReg(base_addr, FSEMA_RLOCK_X_REG_OFFSET(locker->index), reg_val); /* 写0解锁信号量 */
- locker->owner = FSEMA_OWNER_NONE; /* 解锁成功,当前锁持有者为None */
- return ret;
- }
- /**
- * @name: FSemaUnlockAll
- * @msg: 强制解除所有Semaphore锁
- * @return {FError} FSEMA_SUCCESS表示强制解锁成功
- * @param {FSema} *instance, Semaphore控制器实例
- */
- FError FSemaUnlockAll(FSema *const instance)
- {
- FASSERT(instance);
- uintptr base_addr = instance->config.base_addr;
- u32 loop;
- if (FT_COMPONENT_IS_READY != instance->is_ready)
- {
- FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
- return FSEMA_ERR_NOT_INIT;
- }
- FSemaHwResetAll(base_addr);
- for (loop = 0; loop < FSEMA_NUM_OF_LOCKER; loop++)
- {
- if (NULL != instance->locker[loop])
- {
- instance->locker[loop]->owner = FSEMA_OWNER_NONE; /* 解锁成功,当前锁持有者为None */
- }
- }
- return FSEMA_SUCCESS;
- }
- /**
- * @name: FSemaDeleteLocker
- * @msg: 强制解除Semaphore锁并删除锁实例
- * @return {FError} FSEMA_SUCCESS 表示删除锁成功
- * @param {FSemaLocker} *locker, Semaphore锁实例
- */
- FError FSemaDeleteLocker(FSemaLocker *const locker)
- {
- FASSERT(locker && locker->sema);
- FSema *const instance = locker->sema;
- uintptr base_addr = instance->config.base_addr;
- u32 locker_idx = locker->index;
- if (FT_COMPONENT_IS_READY != instance->is_ready)
- {
- FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
- return FSEMA_ERR_NOT_INIT;
- }
- if (TRUE == FSemaHwGetStatus(base_addr, locker_idx))
- {
- FSEMA_WARN("caution, locker-%d has been taken by 0x%x !!!",
- locker_idx, locker->owner);
- }
- FASSERT_MSG((instance->locker[locker_idx] == locker), "invalid locker index %d", locker_idx);
- FSemaWriteReg(base_addr, FSEMA_RLOCK_X_REG_OFFSET(locker->index), FSEMA_RLOCK_X_UNLOCK); /* 写0解锁信号量 */
- instance->locker[locker_idx] = NULL;
- memset(locker, 0, sizeof(*locker));
- return FSEMA_SUCCESS;
- }
- /**
- * @name: FSemaIsLocked
- * @msg: 检查指定Semaphore锁是否处于锁定状态
- * @return {boolean} TRUE: 处于锁定状态
- * @param {FSemaLocker} *locker, Semaphore锁实例
- */
- boolean FSemaIsLocked(FSemaLocker *locker)
- {
- FASSERT(locker && locker->sema);
- FSema *const instance = locker->sema;
- uintptr base_addr = instance->config.base_addr;
- if (FT_COMPONENT_IS_READY != instance->is_ready)
- {
- FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
- return FSEMA_ERR_NOT_INIT;
- }
- return FSemaHwGetStatus(base_addr, locker->index);
- }
|