os_sem_wait
所属模块:同步机制 | 类型:信号量获取函数
函数简介
os_sem_wait 用于获取信号量资源(P操作),
当资源可用时直接获取,否则进入阻塞等待状态。
该函数采用“快路径 + 慢路径”双通道设计,
以保证在资源充足时具备极高执行效率。
函数原型
u8 os_sem_wait(u8 sid);
参数说明
| 参数 |
说明 |
| sid |
信号量ID(0 ~ OS_RESOURCE_MAX-1) |
返回值
WAIT_SIGNAL - 成功立即获取信号量
其他值 - 进入等待状态后的任务ID或调度返回值
0 - 参数非法或获取失败
源码实现
/*------------------------------------------------------------------------
| FILE DESCRIPTION |
------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
| - File name : semaphore_wait.c
| - Author : 谭舒
| - Update date : 2026-09-19
| - Copyright(C) : 2026 HRTOS. All rights reserved.
------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
| INCLUDES |
------------------------------------------------------------------------*/
#include "hrtos_internal.h"
/*------------------------------------------------------------------------
| API FUNCTIONS |
------------------------------------------------------------------------*/
/**
* @brief 获取指定的信号量资源。
*
* @param[in] sid 信号量资源槽位编号。
*
* @return 操作结果。
* @retval WAIT_SIGNAL 信号量获取成功。
* @retval 其他 等待操作返回的结果。
* @retval 0 信号量资源槽位编号无效。
*
* @note 当信号量计数大于 0 时,直接获取一个信号量资源。
* 当信号量计数为 0 时,当前任务进入信号量等待状态,
* 并由系统在信号量释放后进行唤醒。
*/
u8 os_sem_wait(u8 sid)
{
OS_RESOURCE *s;
u8 tid;
/* 参数检查 */
if (sid >= OS_RESOURCE_MAX)
{
return 0;
}
EA = 0;
s = &OS_RES[sid];
//tid = OS_CURRENT_TASK;
if(s->value == 0)
{
EA = 1;
tid = os_wait(WAIT_SEM, sid, 0);
}
/* -------------------------------------------------
* 快路径:信号量可用(无阻塞获取)
* -------------------------------------------------
* 这是性能最关键路径:
* 避免进入 wait_core,减少调度开销
* ------------------------------------------------- */
if(s->value > 0)
{
s->value--; /* 消费一个信号量资源 */
EA = 1;
return WAIT_SIGNAL; /* 表示成功获取资源 */
}
/* -------------------------------------------------
* 慢路径:资源不可用 -> 进入阻塞等待
* -------------------------------------------------
* 任务将进入统一 WAIT 框架:
* - state = WAIT
* - wait_type = WAIT_SEM
* - wait_obj = sid
* - wait_mask 插入资源队列
* ------------------------------------------------- */
EA = 1;
return tid;
}
/*------------------------------------------------------------------------
| END OF FILE: semaphore_wait.c |
------------------------------------------------------------------------*/
使用示例
void task()
{
if(os_sem_wait(0) == WAIT_SIGNAL)
{
// 成功获取资源
}
}
注意事项
信号量采用“双通道模型”,
在资源充足时走快路径,在资源不足时进入统一调度等待机制。