ldrex 和 strex 本来就是为了实现“读-修改-写”的原子操作并且不关中断而提供的,作为 semaphore 来说,除了没有阻塞机制外,它与 OS 的 semaphore 的操作是一致的。
semaphore 应该这样实现:
- uint_fast8_t sem_try_get (uint32_t* sem)
- {
- do {
- uint32_t data = __LDREXW (sem);
- if (data == 0)
- return 0;
- data--;
- } while (__STREXW (data, sem) != 0);
- return 1;
- }
- void sem_free (uint32_t* sem)
- {
- while (__STREXW (__LDREXW (sem) + 1, sem) != 0);
- }
sem_try_get 的参数是一个指针,指向 semaphore 计数器。如果计数器为 0,表示 sem 不可用,返回 0;如果计数器不为 0,则计数器 - 1,返回 1。
sem_free 使指针指向的计数器值 + 1。
|