swsignal.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /************************************************************************
  2. * AUTHOR: NiuJiuRu
  3. * FILENAME: swsignal.c
  4. * DESCRIPTION: 信号量
  5. * NOTE: 主要用于状态通知
  6. * HISTORY:
  7. * 1, [2010-12-17] created by NiuJiuRu
  8. * 2, [2025-11-24] 优化修改"sw_signal_wait()"函数, 使其不依赖系统时间,实现
  9. * 超时等待
  10. ***********************************************************************/
  11. #include "swapi.h"
  12. #include "swmem.h"
  13. #include "swsignal.h"
  14. /* 创建信号量 */
  15. void *sw_signal_create()
  16. {
  17. sem_t *sem = NULL;
  18. sem = (sem_t *)sw_heap_malloc(sizeof(sem_t));
  19. if(sem)
  20. {
  21. memset(sem, 0, sizeof(sem_t));
  22. sem_init(sem, 0, 0);
  23. }
  24. return sem;
  25. }
  26. /* 销毁信号量 */
  27. void sw_signal_destroy(void *hSignal)
  28. {
  29. sem_t *sem = (sem_t *)hSignal;
  30. sem_destroy(sem);
  31. sw_heap_free(sem);
  32. }
  33. /* 等待信号量, timeout(ms) = -1时表示无限等待 */
  34. int sw_signal_wait(void *hSignal, int timeout)
  35. {
  36. sem_t *sem = (sem_t *)hSignal;
  37. int ret;
  38. if(timeout < 0)
  39. {
  40. wait_p1:
  41. ret = sem_wait(sem);
  42. if(ret < 0 && errno == EINTR) goto wait_p1;
  43. else return ret;
  44. }
  45. else
  46. {
  47. if(0)
  48. { // 依赖系统时间的超时等待, 内核唤醒
  49. struct timespec ts, now;
  50. clock_gettime(CLOCK_REALTIME, &now);
  51. ts.tv_sec = now.tv_sec + timeout/1000;
  52. ts.tv_nsec = now.tv_nsec + (timeout%1000)*1000*1000;
  53. if(ts.tv_nsec >= (1000*1000*1000))
  54. {
  55. ts.tv_sec += ts.tv_nsec/(1000*1000*1000);
  56. ts.tv_nsec %= (1000*1000*1000);
  57. }
  58. wait_p2:
  59. ret = sem_timedwait(sem, &ts);
  60. if(ret < 0 && errno == EINTR) goto wait_p2;
  61. else return ret;
  62. }
  63. else
  64. { // 无视系统时间的超时等待, 轮询检查
  65. struct timespec ts = {0, 1000*1000}; // 1ms
  66. while((ret = sem_trywait(sem)) < 0 && errno == EAGAIN)
  67. {
  68. if(timeout <= 0) return -1;
  69. nanosleep(&ts, NULL);
  70. timeout -= 1;
  71. }
  72. return ret;
  73. }
  74. }
  75. }
  76. /* 点亮信号量 */
  77. void sw_signal_give(void *hSignal)
  78. {
  79. sem_t *sem = (sem_t *)hSignal;
  80. sem_post(sem);
  81. }