Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 : #include "mem_pool.h"
11 : #include "mmpa_api.h"
12 : #ifdef __cplusplus
13 : extern "C" {
14 : #endif
15 :
16 0 : void InitMemPoolWithCSingleList(MemPool *pool, size_t memSize)
17 : {
18 0 : InitCSingleList(&pool->idleList);
19 0 : pool->memSize = memSize;
20 0 : pool->updating = 0;
21 0 : pool->seq = 0;
22 0 : pool->reuseMemFlag = false;
23 0 : }
24 :
25 0 : void DeInitMemPoolWithCSingleList(MemPool *pool)
26 : {
27 : CSingleListNode *curNode;
28 : CSingleListNode *nextNode;
29 0 : while (!mmCompareAndSwap64(&pool->updating, 0, 1)) {
30 : }
31 0 : CSingleListForEach(&pool->idleList, curNode, nextNode) {
32 0 : RemoveCSingleListNode(&pool->idleList, curNode);
33 0 : MemNode *memNode = GET_MAIN_BY_MEMBER(curNode, MemNode, node);
34 0 : mmFree(memNode);
35 : }
36 0 : mmSetData64(&pool->updating, 0);
37 0 : }
38 :
39 0 : void* MemPoolAllocWithCSingleList(MemPool *pool)
40 : {
41 0 : MemNode *memNode = NULL;
42 0 : while (!mmCompareAndSwap64(&pool->updating, 0, 1)) {
43 : }
44 0 : if (IsSingleListEmpty(&pool->idleList)) {
45 0 : memNode = (MemNode*)mmMalloc(sizeof(MemNode) + pool->memSize);
46 : } else {
47 0 : memNode = GET_MAIN_BY_MEMBER(GetSingleListHead(&pool->idleList), MemNode, node);
48 0 : RemoveCSingleListHead(&pool->idleList);
49 : }
50 0 : if (memNode != NULL) {
51 0 : memNode->flag = MEM_POOL_NODE_USED_FLAG | (((uint64_t)pool->seq) << MEM_POOL_NODE_SEQ_BITNUM);
52 0 : pool->seq++;
53 : }
54 0 : mmSetData64(&pool->updating, 0);
55 0 : return (void*)((memNode == NULL) ? NULL : memNode->data);
56 : }
57 :
58 0 : void MemPoolFreeWithCSingleList(MemPool *pool, void *mem, FnDestroy pfnDestroy)
59 : {
60 0 : if (mem == NULL) {
61 0 : return;
62 : }
63 :
64 0 : MemNode *memNode = GET_MAIN_BY_MEMBER(mem, MemNode, data);
65 0 : if (memNode == NULL) {
66 0 : return;
67 : }
68 :
69 0 : mmAtomicType64 flag = memNode->flag;
70 0 : if ((flag & MEM_POOL_NODE_USED_FLAG) != MEM_POOL_NODE_USED_FLAG) {
71 0 : return;
72 : }
73 0 : if (mmCompareAndSwap64(&memNode->flag, flag, MEM_POOL_NODE_IDLE_FLAG)) {
74 0 : if (pfnDestroy != NULL) {
75 0 : pfnDestroy(mem);
76 : }
77 0 : while (!mmCompareAndSwap64(&pool->updating, 0, 1)) {
78 : }
79 0 : if (GetMemPoolReuseFlag(pool)) {
80 0 : InsertCSingleListTail(&pool->idleList, &memNode->node);
81 : } else {
82 : // No insert to IDEL list, free memNode immediately
83 0 : mmFree(memNode);
84 0 : memNode = NULL;
85 : }
86 0 : mmSetData64(&pool->updating, 0);
87 : }
88 0 : return;
89 : }
90 :
91 0 : bool GetMemPoolReuseFlag(MemPool *pool)
92 : {
93 0 : return (pool->reuseMemFlag);
94 : }
95 :
96 : #ifdef __cplusplus
97 : }
98 : #endif
|