fsemaphore.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. * Copyright : (C) 2022 Phytium Information Technology, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is OPEN SOURCE software: you can redistribute it and/or modify it
  6. * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
  7. * either version 1.0 of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
  10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See the Phytium Public License for more details.
  12. *
  13. *
  14. * FilePath: fsemaphore.c
  15. * Date: 2022-02-10 14:53:42
  16. * LastEditTime: 2022-02-18 08:25:29
  17. * Description:  This files is for semaphore user api implmentation
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. * 1.0 zhugengyu 2022/5/23 init commit
  23. */
  24. /***************************** Include Files *********************************/
  25. #include <string.h>
  26. #include "fio.h"
  27. #include "ferror_code.h"
  28. #include "ftypes.h"
  29. #include "fdebug.h"
  30. #include "fassert.h"
  31. #include "fsemaphore_hw.h"
  32. #include "fsemaphore.h"
  33. /************************** Constant Definitions *****************************/
  34. /**************************** Type Definitions *******************************/
  35. /***************** Macros (Inline Functions) Definitions *********************/
  36. #define FSEMA_DEBUG_TAG "SEMA"
  37. #define FSEMA_ERROR(format, ...) FT_DEBUG_PRINT_E(FSEMA_DEBUG_TAG, format, ##__VA_ARGS__)
  38. #define FSEMA_WARN(format, ...) FT_DEBUG_PRINT_W(FSEMA_DEBUG_TAG, format, ##__VA_ARGS__)
  39. #define FSEMA_INFO(format, ...) FT_DEBUG_PRINT_I(FSEMA_DEBUG_TAG, format, ##__VA_ARGS__)
  40. #define FSEMA_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSEMA_DEBUG_TAG, format, ##__VA_ARGS__)
  41. /************************** Function Prototypes ******************************/
  42. /************************** Variable Definitions *****************************/
  43. /*****************************************************************************/
  44. /**
  45. * @name: FSemaCfgInitialize
  46. * @msg: 初始化Semaphore控制器
  47. * @return {FError} FSEMA_SUCCESS 表示初始化成功
  48. * @param {FSema} *instance, Semaphore控制器实例
  49. * @param {FSemaConfig} *input_config, Semaphore控制器配置
  50. */
  51. FError FSemaCfgInitialize(FSema *const instance, const FSemaConfig *input_config)
  52. {
  53. FASSERT(instance && input_config);
  54. uintptr base_addr = input_config->base_addr;
  55. FASSERT_MSG((0 != base_addr), "invalid base addr");
  56. FError ret = FSEMA_SUCCESS;
  57. if (FT_COMPONENT_IS_READY == instance->is_ready)
  58. {
  59. FSEMA_WARN("device is already initialized!!!");
  60. }
  61. if (&instance->config != input_config)
  62. instance->config = *input_config;
  63. FSemaHwResetAll(base_addr); /* 重置所有的锁 */
  64. if (FSEMA_SUCCESS == ret)
  65. instance->is_ready = FT_COMPONENT_IS_READY;
  66. return ret;
  67. }
  68. /**
  69. * @name: FSemaDeInitialize
  70. * @msg: 去初始化Semaphore控制器
  71. * @return {void} 无
  72. * @param {FSema} *instance, Semaphore控制器实例
  73. */
  74. void FSemaDeInitialize(FSema *const instance)
  75. {
  76. FASSERT(instance);
  77. u32 loop;
  78. uintptr base_addr = instance->config.base_addr;
  79. for (loop = 0; loop < FSEMA_NUM_OF_LOCKER; loop++)
  80. {
  81. if (NULL != instance->locker[loop])
  82. {
  83. FSEMA_WARN("locker %d @%p is not yet deleted !!!", loop, instance->locker[loop]);
  84. memset(instance->locker[loop], 0, sizeof(*instance->locker[loop]));
  85. }
  86. }
  87. if (0 != base_addr) /* 如果base addr为0,实例可能还没有初始化 */
  88. {
  89. FSemaHwResetAll(base_addr);
  90. }
  91. memset(instance, 0, sizeof(*instance));
  92. return;
  93. }
  94. /**
  95. * @name: FSemaCreateLocker
  96. * @msg: 分配和创建Semaphore锁
  97. * @return {FError} FSEMA_SUCCESS 表示分配成功
  98. * @param {FSema} *instance, Semaphore控制器实例
  99. * @param {FSemaLocker} *locker, Semaphore锁的实例
  100. */
  101. FError FSemaCreateLocker(FSema *const instance, FSemaLocker *const locker)
  102. {
  103. FASSERT(instance && locker);
  104. u32 locker_idx;
  105. if (FT_COMPONENT_IS_READY != instance->is_ready)
  106. {
  107. FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
  108. return FSEMA_ERR_NOT_INIT;
  109. }
  110. for (locker_idx = 0; locker_idx < FSEMA_NUM_OF_LOCKER; locker_idx++)
  111. {
  112. /* 分配一把未创建的锁 */
  113. if (NULL == instance->locker[locker_idx])
  114. {
  115. FSEMA_INFO("allocate locker %d", locker_idx);
  116. break;
  117. }
  118. }
  119. if (locker_idx >= FSEMA_NUM_OF_LOCKER)
  120. {
  121. FSEMA_ERROR("no locker available !!!");
  122. return FSEMA_ERR_NO_AVAILABLE_LOCKER; /* 所有的锁都已经分配创建 */
  123. }
  124. instance->locker[locker_idx] = locker;
  125. locker->index = locker_idx; /* 分配锁,将锁的实例挂在控制器实例上 */
  126. locker->owner = FSEMA_OWNER_NONE; /* 当前锁还没有owner */
  127. locker->name[0] = '\0';
  128. locker->sema = instance;
  129. return FSEMA_SUCCESS;
  130. }
  131. /**
  132. * @name: FSemaTryLock
  133. * @msg: 尝试获取Semaphore锁
  134. * @return {FError} FSEMA_SUCCESS 表示成功获取锁,FSEMA_ERR_LOCK_TIMEOUT 表示锁已经被占用
  135. * @param {FSemaLocker} *locker, Semaphore锁的实例
  136. * @param {u32} owner, 当前尝试获取锁的是谁
  137. * @param {u32} try_times, 尝试获取的次数
  138. * @param {FSemaRelaxHandler} relax_handler, 每次尝试获取锁失败后的relax函数
  139. */
  140. FError FSemaTryLock(FSemaLocker *const locker, u32 owner, u32 try_times, FSemaRelaxHandler relax_handler)
  141. {
  142. FASSERT(locker && locker->sema);
  143. FSema *const instance = locker->sema;
  144. uintptr base_addr = instance->config.base_addr;
  145. boolean lock_success = FALSE;
  146. FError ret = FSEMA_SUCCESS;
  147. if (FT_COMPONENT_IS_READY != instance->is_ready)
  148. {
  149. FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
  150. return FSEMA_ERR_NOT_INIT;
  151. }
  152. while (try_times > 0)
  153. {
  154. /* 尝试获取锁 */
  155. lock_success = FSemaTryLockOnce(base_addr, locker->index);
  156. if (TRUE == lock_success)
  157. break;
  158. if (relax_handler)
  159. relax_handler(instance);
  160. try_times--;
  161. }
  162. if (FALSE == lock_success)
  163. {
  164. ret = FSEMA_ERR_LOCK_TIMEOUT;
  165. FSEMA_ERROR("locker-%d has been taken by owner 0x%x", locker->index, locker->owner);
  166. }
  167. else
  168. {
  169. locker->owner = owner; /* 记录当前locker的owner */
  170. FSEMA_INFO("locker-%d taken success by owner 0x%x", locker->index, owner);
  171. }
  172. return ret;
  173. }
  174. /**
  175. * @name: FSemaUnlock
  176. * @msg: 尝试释放Semaphore锁
  177. * @return {FError} FSEMA_SUCCESS释放锁成功
  178. * @param {FSemaLocker} *locker, Semaphore锁实例
  179. * @param {u32} owner, 当前尝试释放锁的身份
  180. */
  181. FError FSemaUnlock(FSemaLocker *const locker, u32 owner)
  182. {
  183. FASSERT(locker && locker->sema);
  184. FSema *const instance = locker->sema;
  185. uintptr base_addr = instance->config.base_addr;
  186. FError ret = FSEMA_SUCCESS;
  187. u32 reg_val;
  188. if (FT_COMPONENT_IS_READY != instance->is_ready)
  189. {
  190. FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
  191. return FSEMA_ERR_NOT_INIT;
  192. }
  193. if (locker->owner != owner)
  194. {
  195. FSEMA_ERROR("locker is owned by 0x%x, 0x%x has no premission to unlock it !!!",
  196. locker->owner, owner);
  197. return FSEMA_ERR_NO_PERMISSION;
  198. }
  199. if (FALSE == FSemaHwGetStatus(base_addr, locker->index))
  200. {
  201. FSEMA_INFO("locker-%d is not in locked status 0x%x!!!",
  202. locker->index, FSemaReadReg(base_addr, FSEMA_STATE_REG_OFFSET));
  203. return ret;
  204. }
  205. reg_val = FSEMA_RLOCK_X_UNLOCK;
  206. FSemaWriteReg(base_addr, FSEMA_RLOCK_X_REG_OFFSET(locker->index), reg_val); /* 写0解锁信号量 */
  207. locker->owner = FSEMA_OWNER_NONE; /* 解锁成功,当前锁持有者为None */
  208. return ret;
  209. }
  210. /**
  211. * @name: FSemaUnlockAll
  212. * @msg: 强制解除所有Semaphore锁
  213. * @return {FError} FSEMA_SUCCESS表示强制解锁成功
  214. * @param {FSema} *instance, Semaphore控制器实例
  215. */
  216. FError FSemaUnlockAll(FSema *const instance)
  217. {
  218. FASSERT(instance);
  219. uintptr base_addr = instance->config.base_addr;
  220. u32 loop;
  221. if (FT_COMPONENT_IS_READY != instance->is_ready)
  222. {
  223. FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
  224. return FSEMA_ERR_NOT_INIT;
  225. }
  226. FSemaHwResetAll(base_addr);
  227. for (loop = 0; loop < FSEMA_NUM_OF_LOCKER; loop++)
  228. {
  229. if (NULL != instance->locker[loop])
  230. {
  231. instance->locker[loop]->owner = FSEMA_OWNER_NONE; /* 解锁成功,当前锁持有者为None */
  232. }
  233. }
  234. return FSEMA_SUCCESS;
  235. }
  236. /**
  237. * @name: FSemaDeleteLocker
  238. * @msg: 强制解除Semaphore锁并删除锁实例
  239. * @return {FError} FSEMA_SUCCESS 表示删除锁成功
  240. * @param {FSemaLocker} *locker, Semaphore锁实例
  241. */
  242. FError FSemaDeleteLocker(FSemaLocker *const locker)
  243. {
  244. FASSERT(locker && locker->sema);
  245. FSema *const instance = locker->sema;
  246. uintptr base_addr = instance->config.base_addr;
  247. u32 locker_idx = locker->index;
  248. if (FT_COMPONENT_IS_READY != instance->is_ready)
  249. {
  250. FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
  251. return FSEMA_ERR_NOT_INIT;
  252. }
  253. if (TRUE == FSemaHwGetStatus(base_addr, locker_idx))
  254. {
  255. FSEMA_WARN("caution, locker-%d has been taken by 0x%x !!!",
  256. locker_idx, locker->owner);
  257. }
  258. FASSERT_MSG((instance->locker[locker_idx] == locker), "invalid locker index %d", locker_idx);
  259. FSemaWriteReg(base_addr, FSEMA_RLOCK_X_REG_OFFSET(locker->index), FSEMA_RLOCK_X_UNLOCK); /* 写0解锁信号量 */
  260. instance->locker[locker_idx] = NULL;
  261. memset(locker, 0, sizeof(*locker));
  262. return FSEMA_SUCCESS;
  263. }
  264. /**
  265. * @name: FSemaIsLocked
  266. * @msg: 检查指定Semaphore锁是否处于锁定状态
  267. * @return {boolean} TRUE: 处于锁定状态
  268. * @param {FSemaLocker} *locker, Semaphore锁实例
  269. */
  270. boolean FSemaIsLocked(FSemaLocker *locker)
  271. {
  272. FASSERT(locker && locker->sema);
  273. FSema *const instance = locker->sema;
  274. uintptr base_addr = instance->config.base_addr;
  275. if (FT_COMPONENT_IS_READY != instance->is_ready)
  276. {
  277. FSEMA_ERROR("device@%p not yet inited !!!", instance->config.base_addr);
  278. return FSEMA_ERR_NOT_INIT;
  279. }
  280. return FSemaHwGetStatus(base_addr, locker->index);
  281. }