swstack.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /************************************************************************
  2. * AUTHOR: NiuJiuRu
  3. * FILENAME: swstack.c
  4. * DESCRIPTION: 内存栈-先进后出
  5. * NOTE:
  6. * HISTORY:
  7. * 1, [2014-01-15] created by NiuJiuRu
  8. * 2, [2016-08-08] 添加互斥锁, 保障线程安全
  9. ***********************************************************************/
  10. #include "swapi.h"
  11. #include "swmutex.h"
  12. #include "swmem.h"
  13. // node
  14. struct stk_node
  15. {
  16. struct stk_data data;
  17. struct stk_node *next;
  18. };
  19. // stack
  20. struct stk_stack
  21. {
  22. void *hMem;
  23. struct stk_node *top;
  24. int nodesCnt;
  25. void *hMutex;
  26. };
  27. // 创建一个栈, "hMem"为空时在系统内存中创建, "hMem"不为空时在给定的内存中创建
  28. void *sw_stack_create(void *hMem)
  29. {
  30. struct stk_stack *newStack = NULL;
  31. newStack = (struct stk_stack *)(hMem ? sw_mem_alloc(hMem, sizeof(struct stk_stack), __FILE__, __LINE__) : \
  32. malloc(sizeof(struct stk_stack)));
  33. if(newStack)
  34. {
  35. newStack->hMem = hMem;
  36. newStack->top = NULL;
  37. newStack->nodesCnt = 0;
  38. newStack->hMutex = sw_mutex_create();
  39. if(!newStack->hMutex)
  40. {
  41. newStack->hMem ? sw_mem_free(newStack->hMem, newStack, __FILE__, __LINE__) : free(newStack);
  42. return NULL;
  43. }
  44. }
  45. return newStack;
  46. }
  47. // 数据压栈
  48. bool sw_stack_push(void *hStack, struct stk_data data)
  49. {
  50. struct stk_stack *theStack = (struct stk_stack *)hStack;
  51. struct stk_node *newNode = NULL;
  52. if(theStack)
  53. {
  54. newNode = (struct stk_node *)(theStack->hMem ? sw_mem_alloc(theStack->hMem, sizeof(struct stk_node), __FILE__, __LINE__) : \
  55. malloc(sizeof(struct stk_node)));
  56. if(newNode)
  57. {
  58. newNode->data.addr = data.addr;
  59. newNode->data.size = data.size;
  60. newNode->data.freeFun = data.freeFun;
  61. newNode->data.wParam = data.wParam;
  62. newNode->data.lParam = data.lParam;
  63. sw_mutex_lock(theStack->hMutex, WAIT_FOREVER); // lock
  64. newNode->next = theStack->top;
  65. theStack->top = newNode;
  66. theStack->nodesCnt += 1;
  67. sw_mutex_unlock(theStack->hMutex); // unlock
  68. return true;
  69. }
  70. }
  71. return false;
  72. }
  73. // 数据弹出栈
  74. // 注意: 如果只弹出数据而不接收结果("result"为空时), 弹出过程中将会自动调用数据压栈时设定的内存释放回调函数
  75. void sw_stack_pop(void *hStack, struct stk_data *result)
  76. {
  77. struct stk_stack *theStack = (struct stk_stack *)hStack;
  78. struct stk_node *topNode = NULL;
  79. if(theStack && theStack->top)
  80. {
  81. sw_mutex_lock(theStack->hMutex, WAIT_FOREVER); // lock
  82. topNode = theStack->top;
  83. theStack->top = theStack->top->next;
  84. theStack->nodesCnt -= 1;
  85. sw_mutex_unlock(theStack->hMutex); // unlock
  86. if(result)
  87. {
  88. result->addr = topNode->data.addr;
  89. result->size = topNode->data.size;
  90. result->freeFun = topNode->data.freeFun;
  91. result->wParam = topNode->data.wParam;
  92. result->lParam = topNode->data.lParam;
  93. }
  94. else
  95. {
  96. if(topNode->data.freeFun) topNode->data.freeFun((void *)topNode->data.addr, topNode->data.size);
  97. }
  98. theStack->hMem ? sw_mem_free(theStack->hMem, topNode, __FILE__, __LINE__) : free(topNode);
  99. }
  100. }
  101. // 得到一个栈内当前的数据元个数
  102. int sw_stack_getDataElementsCnt(const void *hStack)
  103. {
  104. struct stk_stack *theStack = (struct stk_stack *)hStack;
  105. int num;
  106. if(theStack)
  107. {
  108. sw_mutex_lock(theStack->hMutex, WAIT_FOREVER); // lock
  109. num = theStack->nodesCnt;
  110. sw_mutex_unlock(theStack->hMutex); // unlock
  111. }
  112. else num = -1;
  113. return num;
  114. }
  115. // 销毁一个栈, 并在销毁过程中自动调用数据压栈时设定的内存释放回调函数
  116. void sw_stack_destroy(void *hStack)
  117. {
  118. struct stk_stack *theStack = (struct stk_stack *)hStack;
  119. struct stk_node *delNode = NULL, *nextNode = NULL;
  120. if(theStack)
  121. {
  122. delNode = theStack->top;
  123. while(delNode)
  124. {
  125. nextNode = delNode->next;
  126. if(delNode->data.freeFun) delNode->data.freeFun((void *)delNode->data.addr, delNode->data.size);
  127. theStack->hMem ? sw_mem_free(theStack->hMem, delNode, __FILE__, __LINE__) : free(delNode);
  128. delNode = nextNode;
  129. }
  130. sw_mutex_destroy(theStack->hMutex);
  131. theStack->hMem ? sw_mem_free(theStack->hMem, theStack, __FILE__, __LINE__) : free(theStack);
  132. }
  133. }