swmutex.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /************************************************************************
  2. * AUTHOR: NiuJiuRu
  3. * FILENAME: swmutex.c
  4. * DESCRIPTION: 互斥量, 也称独占锁
  5. * NOTE: 主要用于多线程同步访问全局共享资源
  6. * HISTORY:
  7. * 1, [2010-12-17] created by NiuJiuRu
  8. * 2, [2026-03-17] 优化修改"sw_mutex_lock()"函数, 避免依赖系统时间, 导致的超
  9. * 时误差或跳变问题
  10. ***********************************************************************/
  11. #include "swapi.h"
  12. #include "swmem.h"
  13. #include "swmutex.h"
  14. /* 创建互斥量 */
  15. void *sw_mutex_create()
  16. {
  17. pthread_mutex_t *mt = NULL;
  18. pthread_mutexattr_t attr;
  19. mt = (pthread_mutex_t *)sw_heap_malloc(sizeof(pthread_mutex_t));
  20. if(mt)
  21. {
  22. if(pthread_mutexattr_init(&attr) != 0) { sw_heap_free(mt); return NULL; }
  23. if(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0 || pthread_mutex_init(mt, &attr) != 0) { sw_heap_free(mt); mt = NULL; }
  24. pthread_mutexattr_destroy(&attr);
  25. }
  26. return mt;
  27. }
  28. /* 销毁互斥量 */
  29. void sw_mutex_destroy(void *hMutex)
  30. {
  31. pthread_mutex_t *mt = (pthread_mutex_t *)hMutex;
  32. pthread_mutex_destroy(mt);
  33. sw_heap_free(mt);
  34. }
  35. /* 互斥量上锁(超时设置的时间单位为: 毫秒, 并且当timeout = -1时表示无限等待) */
  36. int sw_mutex_lock(void *hMutex, int timeout)
  37. {
  38. pthread_mutex_t *mt = (pthread_mutex_t *)hMutex;
  39. struct timespec start, now; int ret;
  40. if(timeout < 0)
  41. {
  42. return pthread_mutex_lock(mt);
  43. }
  44. clock_gettime(CLOCK_MONOTONIC, &start);
  45. while((ret = pthread_mutex_trylock(mt)) == EBUSY)
  46. {
  47. clock_gettime(CLOCK_MONOTONIC, &now);
  48. long long elapsed = (now.tv_sec*1000LL + now.tv_nsec/1000000) - (start.tv_sec*1000LL + start.tv_nsec/1000000);
  49. if(elapsed >= timeout) { errno = ETIMEDOUT; return -1; }
  50. else delay_ms(1); // 释放CPU占用, 避免过载
  51. }
  52. return ret == 0 ? 0 : -1;
  53. }
  54. /* 互斥量解锁 */
  55. void sw_mutex_unlock(void *hMutex)
  56. {
  57. pthread_mutex_t *mt = (pthread_mutex_t *)hMutex;
  58. pthread_mutex_unlock(mt);
  59. }