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 : {
33 0 : RemoveCSingleListNode(&pool->idleList, curNode);
34 0 : MemNode* memNode = GET_MAIN_BY_MEMBER(curNode, MemNode, node);
35 0 : mmFree(memNode);
36 : }
37 0 : mmSetData64(&pool->updating, 0);
38 0 : }
39 :
40 0 : void* MemPoolAllocWithCSingleList(MemPool* pool)
41 : {
42 0 : MemNode* memNode = NULL;
43 0 : while (!mmCompareAndSwap64(&pool->updating, 0, 1)) {
44 : }
45 0 : if (IsSingleListEmpty(&pool->idleList)) {
46 0 : memNode = (MemNode*)mmMalloc(sizeof(MemNode) + pool->memSize);
47 : } else {
48 0 : memNode = GET_MAIN_BY_MEMBER(GetSingleListHead(&pool->idleList), MemNode, node);
49 0 : RemoveCSingleListHead(&pool->idleList);
50 : }
51 0 : if (memNode != NULL) {
52 0 : memNode->flag = MEM_POOL_NODE_USED_FLAG | (((uint64_t)pool->seq) << MEM_POOL_NODE_SEQ_BITNUM);
53 0 : pool->seq++;
54 : }
55 0 : mmSetData64(&pool->updating, 0);
56 0 : return (void*)((memNode == NULL) ? NULL : memNode->data);
57 : }
58 :
59 0 : void MemPoolFreeWithCSingleList(MemPool* pool, void* mem, FnDestroy pfnDestroy)
60 : {
61 0 : if (mem == NULL) {
62 0 : return;
63 : }
64 :
65 0 : MemNode* memNode = GET_MAIN_BY_MEMBER(mem, MemNode, data);
66 0 : if (memNode == NULL) {
67 0 : return;
68 : }
69 :
70 0 : mmAtomicType64 flag = memNode->flag;
71 0 : if ((flag & MEM_POOL_NODE_USED_FLAG) != MEM_POOL_NODE_USED_FLAG) {
72 0 : return;
73 : }
74 0 : if (mmCompareAndSwap64(&memNode->flag, flag, MEM_POOL_NODE_IDLE_FLAG)) {
75 0 : if (pfnDestroy != NULL) {
76 0 : pfnDestroy(mem);
77 : }
78 0 : while (!mmCompareAndSwap64(&pool->updating, 0, 1)) {
79 : }
80 0 : if (GetMemPoolReuseFlag(pool)) {
81 0 : InsertCSingleListTail(&pool->idleList, &memNode->node);
82 : } else {
83 : // No insert to IDEL list, free memNode immediately
84 0 : mmFree(memNode);
85 0 : memNode = NULL;
86 : }
87 0 : mmSetData64(&pool->updating, 0);
88 : }
89 0 : return;
90 : }
91 :
92 0 : bool GetMemPoolReuseFlag(MemPool* pool) { return (pool->reuseMemFlag); }
93 :
94 : #ifdef __cplusplus
95 : }
96 : #endif
|