| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- /************************************************************************
- * AUTHOR: NiuJiuRu
- * FILENAME: swsignal.c
- * DESCRIPTION: 信号量
- * NOTE: 主要用于状态通知
- * HISTORY:
- * 1, [2010-12-17] created by NiuJiuRu
- * 2, [2025-11-24] 优化修改"sw_signal_wait()"函数, 使其不依赖系统时间,实现
- * 超时等待
- ***********************************************************************/
- #include "swapi.h"
- #include "swmem.h"
- #include "swsignal.h"
- /* 创建信号量 */
- void *sw_signal_create()
- {
- sem_t *sem = NULL;
-
- sem = (sem_t *)sw_heap_malloc(sizeof(sem_t));
- if(sem)
- {
- memset(sem, 0, sizeof(sem_t));
- sem_init(sem, 0, 0);
- }
-
- return sem;
- }
- /* 销毁信号量 */
- void sw_signal_destroy(void *hSignal)
- {
- sem_t *sem = (sem_t *)hSignal;
- sem_destroy(sem);
- sw_heap_free(sem);
- }
- /* 等待信号量, timeout(ms) = -1时表示无限等待 */
- int sw_signal_wait(void *hSignal, int timeout)
- {
- sem_t *sem = (sem_t *)hSignal;
- int ret;
-
- if(timeout < 0)
- {
- wait_p1:
- ret = sem_wait(sem);
- if(ret < 0 && errno == EINTR) goto wait_p1;
- else return ret;
- }
- else
- {
- if(0)
- { // 依赖系统时间的超时等待, 内核唤醒
- struct timespec ts, now;
- clock_gettime(CLOCK_REALTIME, &now);
- ts.tv_sec = now.tv_sec + timeout/1000;
- ts.tv_nsec = now.tv_nsec + (timeout%1000)*1000*1000;
- if(ts.tv_nsec >= (1000*1000*1000))
- {
- ts.tv_sec += ts.tv_nsec/(1000*1000*1000);
- ts.tv_nsec %= (1000*1000*1000);
- }
- wait_p2:
- ret = sem_timedwait(sem, &ts);
- if(ret < 0 && errno == EINTR) goto wait_p2;
- else return ret;
- }
- else
- { // 无视系统时间的超时等待, 轮询检查
- struct timespec ts = {0, 1000*1000}; // 1ms
- while((ret = sem_trywait(sem)) < 0 && errno == EAGAIN)
- {
- if(timeout <= 0) return -1;
- nanosleep(&ts, NULL);
- timeout -= 1;
- }
- return ret;
- }
- }
- }
- /* 点亮信号量 */
- void sw_signal_give(void *hSignal)
- {
- sem_t *sem = (sem_t *)hSignal;
- sem_post(sem);
- }
|