| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- /************************************************************************
- * AUTHOR: NiuJiuRu
- * FILENAME: swstack.c
- * DESCRIPTION: 内存栈-先进后出
- * NOTE:
- * HISTORY:
- * 1, [2014-01-15] created by NiuJiuRu
- * 2, [2016-08-08] 添加互斥锁, 保障线程安全
- ***********************************************************************/
- #include "swapi.h"
- #include "swmutex.h"
- #include "swmem.h"
- // node
- struct stk_node
- {
- struct stk_data data;
- struct stk_node *next;
- };
- // stack
- struct stk_stack
- {
- void *hMem;
- struct stk_node *top;
- int nodesCnt;
- void *hMutex;
- };
- // 创建一个栈, "hMem"为空时在系统内存中创建, "hMem"不为空时在给定的内存中创建
- void *sw_stack_create(void *hMem)
- {
- struct stk_stack *newStack = NULL;
- newStack = (struct stk_stack *)(hMem ? sw_mem_alloc(hMem, sizeof(struct stk_stack), __FILE__, __LINE__) : \
- malloc(sizeof(struct stk_stack)));
- if(newStack)
- {
- newStack->hMem = hMem;
- newStack->top = NULL;
- newStack->nodesCnt = 0;
- newStack->hMutex = sw_mutex_create();
- if(!newStack->hMutex)
- {
- newStack->hMem ? sw_mem_free(newStack->hMem, newStack, __FILE__, __LINE__) : free(newStack);
- return NULL;
- }
- }
- return newStack;
- }
- // 数据压栈
- bool sw_stack_push(void *hStack, struct stk_data data)
- {
- struct stk_stack *theStack = (struct stk_stack *)hStack;
- struct stk_node *newNode = NULL;
- if(theStack)
- {
- newNode = (struct stk_node *)(theStack->hMem ? sw_mem_alloc(theStack->hMem, sizeof(struct stk_node), __FILE__, __LINE__) : \
- malloc(sizeof(struct stk_node)));
- if(newNode)
- {
- newNode->data.addr = data.addr;
- newNode->data.size = data.size;
- newNode->data.freeFun = data.freeFun;
- newNode->data.wParam = data.wParam;
- newNode->data.lParam = data.lParam;
- sw_mutex_lock(theStack->hMutex, WAIT_FOREVER); // lock
- newNode->next = theStack->top;
- theStack->top = newNode;
- theStack->nodesCnt += 1;
- sw_mutex_unlock(theStack->hMutex); // unlock
- return true;
- }
- }
- return false;
- }
- // 数据弹出栈
- // 注意: 如果只弹出数据而不接收结果("result"为空时), 弹出过程中将会自动调用数据压栈时设定的内存释放回调函数
- void sw_stack_pop(void *hStack, struct stk_data *result)
- {
- struct stk_stack *theStack = (struct stk_stack *)hStack;
- struct stk_node *topNode = NULL;
- if(theStack && theStack->top)
- {
- sw_mutex_lock(theStack->hMutex, WAIT_FOREVER); // lock
- topNode = theStack->top;
- theStack->top = theStack->top->next;
- theStack->nodesCnt -= 1;
- sw_mutex_unlock(theStack->hMutex); // unlock
- if(result)
- {
- result->addr = topNode->data.addr;
- result->size = topNode->data.size;
- result->freeFun = topNode->data.freeFun;
- result->wParam = topNode->data.wParam;
- result->lParam = topNode->data.lParam;
- }
- else
- {
- if(topNode->data.freeFun) topNode->data.freeFun((void *)topNode->data.addr, topNode->data.size);
- }
- theStack->hMem ? sw_mem_free(theStack->hMem, topNode, __FILE__, __LINE__) : free(topNode);
- }
- }
- // 得到一个栈内当前的数据元个数
- int sw_stack_getDataElementsCnt(const void *hStack)
- {
- struct stk_stack *theStack = (struct stk_stack *)hStack;
- int num;
- if(theStack)
- {
- sw_mutex_lock(theStack->hMutex, WAIT_FOREVER); // lock
- num = theStack->nodesCnt;
- sw_mutex_unlock(theStack->hMutex); // unlock
- }
- else num = -1;
- return num;
- }
- // 销毁一个栈, 并在销毁过程中自动调用数据压栈时设定的内存释放回调函数
- void sw_stack_destroy(void *hStack)
- {
- struct stk_stack *theStack = (struct stk_stack *)hStack;
- struct stk_node *delNode = NULL, *nextNode = NULL;
- if(theStack)
- {
- delNode = theStack->top;
- while(delNode)
- {
- nextNode = delNode->next;
- if(delNode->data.freeFun) delNode->data.freeFun((void *)delNode->data.addr, delNode->data.size);
- theStack->hMem ? sw_mem_free(theStack->hMem, delNode, __FILE__, __LINE__) : free(delNode);
- delNode = nextNode;
- }
- sw_mutex_destroy(theStack->hMutex);
- theStack->hMem ? sw_mem_free(theStack->hMem, theStack, __FILE__, __LINE__) : free(theStack);
- }
- }
|