| /**************************************************************************** |
| * |
| * The MIT License (MIT) |
| * |
| * Copyright (c) 2014 - 2016 Vivante Corporation |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| * DEALINGS IN THE SOFTWARE. |
| * |
| ***************************************************************************** |
| * |
| * The GPL License (GPL) |
| * |
| * Copyright (C) 2014 - 2016 Vivante Corporation |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License |
| * as published by the Free Software Foundation; either version 2 |
| * of the License, or (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| * |
| ***************************************************************************** |
| * |
| * Note: This software is released under dual MIT and GPL licenses. A |
| * recipient may use this file under the terms of either the MIT license or |
| * GPL License. If you wish to use only one license not the other, you can |
| * indicate your decision by deleting one of the above license notices in your |
| * version of this file. |
| * |
| *****************************************************************************/ |
| |
| |
| /* |
| ** Include file for the local memory management. |
| */ |
| |
| #ifndef __gc_hal_mem_h_ |
| #define __gc_hal_mem_h_ |
| #if (gcdENABLE_3D || gcdENABLE_VG) |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /******************************************************************************* |
| ** Usage: |
| |
| The macros to declare MemPool type and functions are |
| gcmMEM_DeclareFSMemPool (Type, TypeName, Prefix) |
| gcmMEM_DeclareVSMemPool (Type, TypeName, Prefix) |
| gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) |
| |
| The data structures for MemPool are |
| typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL; |
| typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL; |
| typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL; |
| |
| The MemPool constructor and destructor functions are |
| gcfMEM_InitFSMemPool(gcsMEM_FS_MEM_POOL *, gcoOS, gctUINT, gctUINT); |
| gcfMEM_FreeFSMemPool(gcsMEM_FS_MEM_POOL *); |
| gcfMEM_InitVSMemPool(gcsMEM_VS_MEM_POOL *, gcoOS, gctUINT, gctBOOL); |
| gcfMEM_FreeVSMemPool(gcsMEM_VS_MEM_POOL *); |
| gcfMEM_InitAFSMemPool(gcsMEM_AFS_MEM_POOL *, gcoOS, gctUINT); |
| gcfMEM_FreeAFSMemPool(gcsMEM_AFS_MEM_POOL *); |
| |
| FS: for Fixed-Size data structures |
| VS: for Variable-size data structures |
| AFS: for Array of Fixed-Size data structures |
| |
| |
| // Example 1: For a fixed-size data structure, struct gcsNode. |
| // It is used locally in a file, so the functions are static without prefix. |
| // At top level, declear allocate and free functions. |
| // The first argument is the data type. |
| // The second armument is the short name used in the fuctions. |
| gcmMEM_DeclareFSMemPool(struct gcsNode, Node, ); |
| |
| // The previous macro creates two inline functions, |
| // _AllocateNode and _FreeNode. |
| |
| // In function or struct |
| gcsMEM_FS_MEM_POOL nodeMemPool; |
| |
| // In function, |
| struct gcsNode * node; |
| gceSTATUS status; |
| |
| // Before using the memory pool, initialize it. |
| // The second argument is the gcoOS object. |
| // The third argument is the number of data structures to allocate for each chunk. |
| status = gcfMEM_InitFSMemPool(&nodeMemPool, os, 100, sizeof(struct gcsNode)); |
| ... |
| |
| // Allocate a node. |
| status = _AllocateNode(nodeMemPool, &node); |
| ... |
| // Free a node. |
| _FreeNode(nodeMemPool, node); |
| |
| // After using the memory pool, free it. |
| gcfMEM_FreeFSMemPool(&nodeMemPool); |
| |
| |
| // Example 2: For array of fixed-size data structures, struct gcsNode. |
| // It is used in several files, so the functions are extern with prefix. |
| // At top level, declear allocate and free functions. |
| // The first argument is the data type, and the second one is the short name |
| // used in the fuctions. |
| gcmMEM_DeclareAFSMemPool(struct gcsNode, NodeArray, gcfOpt); |
| |
| // The previous macro creates two inline functions, |
| // gcfOpt_AllocateNodeArray and gcfOpt_FreeNodeArray. |
| |
| // In function or struct |
| gcsMEM_AFS_MEM_POOL nodeArrayMemPool; |
| |
| // In function, |
| struct gcsNode * nodeArray; |
| gceSTATUS status; |
| |
| // Before using the array memory pool, initialize it. |
| // The second argument is the gcoOS object, the third is the number of data |
| // structures to allocate for each chunk. |
| status = gcfMEM_InitAFSMemPool(&nodeArrayMemPool, os, sizeof(struct gcsNode)); |
| ... |
| |
| // Allocate a node array of size 100. |
| status = gcfOpt_AllocateNodeArray(nodeArrayMemPool, &nodeArray, 100); |
| ... |
| // Free a node array. |
| gcfOpt_FreeNodeArray(&nodeArrayMemPool, nodeArray); |
| |
| // After using the array memory pool, free it. |
| gcfMEM_FreeAFSMemPool(&nodeArrayMemPool); |
| |
| *******************************************************************************/ |
| |
| /******************************************************************************* |
| ** To switch back to use gcoOS_Allocate and gcoOS_Free, add |
| ** #define USE_LOCAL_MEMORY_POOL 0 |
| ** before including this file. |
| *******************************************************************************/ |
| #ifndef USE_LOCAL_MEMORY_POOL |
| /* |
| USE_LOCAL_MEMORY_POOL |
| |
| This define enables the local memory management to improve performance. |
| */ |
| #define USE_LOCAL_MEMORY_POOL 1 |
| #endif |
| |
| /******************************************************************************* |
| ** Memory Pool Data Structures |
| *******************************************************************************/ |
| #if USE_LOCAL_MEMORY_POOL |
| typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL; |
| typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL; |
| typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL; |
| #else |
| typedef gcoOS gcsMEM_FS_MEM_POOL; |
| typedef gcoOS gcsMEM_VS_MEM_POOL; |
| typedef gcoOS gcsMEM_AFS_MEM_POOL; |
| #endif |
| |
| /******************************************************************************* |
| ** Memory Pool Macros |
| *******************************************************************************/ |
| #if USE_LOCAL_MEMORY_POOL |
| #define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \ |
| gceSTATUS \ |
| Prefix##_Allocate##TypeName( \ |
| gcsMEM_FS_MEM_POOL MemPool, \ |
| Type ** Pointer \ |
| ) \ |
| { \ |
| return(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_CAllocate##TypeName( \ |
| gcsMEM_FS_MEM_POOL MemPool, \ |
| Type ** Pointer \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ |
| gcmERR_RETURN(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \ |
| gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \ |
| gcmFOOTER(); \ |
| return gcvSTATUS_OK; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_Free##TypeName( \ |
| gcsMEM_FS_MEM_POOL MemPool, \ |
| Type * Pointer \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ |
| status = gcfMEM_FSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_Free##TypeName##List( \ |
| gcsMEM_FS_MEM_POOL MemPool, \ |
| Type * FirstPointer, \ |
| Type * LastPointer \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x FirstPointer=0x%x LastPointer=0x%x", MemPool, FirstPointer, LastPointer); \ |
| status = gcfMEM_FSMemPoolFreeAList(MemPool, (gctPOINTER) FirstPointer, (gctPOINTER) LastPointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } |
| |
| #define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \ |
| gceSTATUS \ |
| Prefix##_Allocate##TypeName( \ |
| gcsMEM_FS_MEM_POOL MemPool, \ |
| Type ** Pointer, \ |
| gctUINT Size \ |
| ) \ |
| { \ |
| gceSTATUS status;\ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \ |
| status = gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_CAllocate##TypeName( \ |
| gcsMEM_FS_MEM_POOL MemPool, \ |
| Type ** Pointer, \ |
| gctUINT Size \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \ |
| gcmERR_RETURN(gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer)); \ |
| gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, size); \ |
| gcmFOOTER(); \ |
| return gcvSTATUS_OK; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_Free##TypeName( \ |
| gcsMEM_FS_MEM_POOL MemPool, \ |
| Type * Pointer \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pinter); \ |
| status = gcfMEM_VSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } |
| |
| #define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \ |
| gceSTATUS \ |
| Prefix##_Allocate##TypeName( \ |
| gcsMEM_AFS_MEM_POOL MemPool, \ |
| Type ** Pointer, \ |
| gctUINT Count \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \ |
| status = gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_CAllocate##TypeName( \ |
| gcsMEM_AFS_MEM_POOL MemPool, \ |
| Type ** Pointer, \ |
| gctUINT Count \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \ |
| gcmERR_RETURN(gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer)); \ |
| gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \ |
| gcmFOOTER(); \ |
| return gcvSTATUS_OK; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_Free##TypeName( \ |
| gcsMEM_AFS_MEM_POOL MemPool, \ |
| Type * Pointer \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ |
| status = gcfMEM_AFSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } |
| |
| #else |
| |
| #define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \ |
| gceSTATUS \ |
| Prefix##_Allocate##TypeName( \ |
| gcsMEM_FS_MEM_POOL MemPool, \ |
| Type ** Pointer \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ |
| status = gcoOS_Allocate(MemPool, \ |
| gcmSIZEOF(Type), \ |
| (gctPOINTER *) Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_CAllocate##TypeName( \ |
| gcsMEM_FS_MEM_POOL MemPool, \ |
| Type ** Pointer \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ |
| gcmERR_RETURN(gcoOS_Allocate(MemPool, \ |
| gcmSIZEOF(Type), \ |
| (gctPOINTER *) Pointer)); \ |
| gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \ |
| gcmFOOTER(); \ |
| return gcvSTATUS_OK; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_Free##TypeName( \ |
| gcsMEM_FS_MEM_POOL MemPool, \ |
| Type * Pointer \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ |
| status = gcmOS_SAFE_FREE(MemPool, Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } |
| |
| #define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \ |
| gceSTATUS \ |
| Prefix##_Allocate##TypeName( \ |
| gcsMEM_VS_MEM_POOL MemPool, \ |
| Type ** Pointer, \ |
| gctUINT Size \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \ |
| status = gcoOS_Allocate(MemPool, \ |
| Size, \ |
| (gctPOINTER *) Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_CAllocate##TypeName( \ |
| gcsMEM_VS_MEM_POOL MemPool, \ |
| Type ** Pointer, \ |
| gctUINT Size \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \ |
| gcmERR_RETURN(gcoOS_Allocate(MemPool, \ |
| Size, \ |
| (gctPOINTER *) Pointer)); \ |
| gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Size); \ |
| gcmFOOTER(); \ |
| return gcvSTATUS_OK; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_Free##TypeName( \ |
| gcsMEM_VS_MEM_POOL MemPool, \ |
| Type * Pointer \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ |
| status = gcmOS_SAFE_FREE(MemPool, Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } |
| |
| #define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \ |
| gceSTATUS \ |
| Prefix##_Allocate##TypeName( \ |
| gcsMEM_AFS_MEM_POOL MemPool, \ |
| Type ** Pointer, \ |
| gctUINT Count \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \ |
| status = gcoOS_Allocate(MemPool, \ |
| Count * gcmSIZEOF(Type), \ |
| (gctPOINTER *) Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_CAllocate##TypeName( \ |
| gcsMEM_AFS_MEM_POOL MemPool, \ |
| Type ** Pointer, \ |
| gctUINT Count \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \ |
| gcmERR_RETURN(gcoOS_Allocate(MemPool, \ |
| Count * gcmSIZEOF(Type), \ |
| (gctPOINTER *) Pointer)); \ |
| gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \ |
| gcmFOOTER(); \ |
| return gcvSTATUS_OK; \ |
| } \ |
| \ |
| gceSTATUS \ |
| Prefix##_Free##TypeName( \ |
| gcsMEM_AFS_MEM_POOL MemPool, \ |
| Type * Pointer \ |
| ) \ |
| { \ |
| gceSTATUS status; \ |
| gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ |
| status = gcmOS_SAFE_FREE(MemPool, Pointer); \ |
| gcmFOOTER(); \ |
| return status; \ |
| } |
| #endif |
| |
| /******************************************************************************* |
| ** Memory Pool Data Functions |
| *******************************************************************************/ |
| gceSTATUS |
| gcfMEM_InitFSMemPool( |
| IN gcsMEM_FS_MEM_POOL * MemPool, |
| IN gcoOS OS, |
| IN gctUINT NodeCount, |
| IN gctUINT NodeSize |
| ); |
| |
| gceSTATUS |
| gcfMEM_FreeFSMemPool( |
| IN gcsMEM_FS_MEM_POOL * MemPool |
| ); |
| |
| gceSTATUS |
| gcfMEM_FSMemPoolGetANode( |
| IN gcsMEM_FS_MEM_POOL MemPool, |
| OUT gctPOINTER * Node |
| ); |
| |
| gceSTATUS |
| gcfMEM_FSMemPoolFreeANode( |
| IN gcsMEM_FS_MEM_POOL MemPool, |
| IN gctPOINTER Node |
| ); |
| |
| gceSTATUS |
| gcfMEM_FSMemPoolFreeAList( |
| IN gcsMEM_FS_MEM_POOL MemPool, |
| IN gctPOINTER FirstNode, |
| IN gctPOINTER LastNode |
| ); |
| |
| gceSTATUS |
| gcfMEM_InitVSMemPool( |
| IN gcsMEM_VS_MEM_POOL * MemPool, |
| IN gcoOS OS, |
| IN gctUINT BlockSize, |
| IN gctBOOL RecycleFreeNode |
| ); |
| |
| gceSTATUS |
| gcfMEM_FreeVSMemPool( |
| IN gcsMEM_VS_MEM_POOL * MemPool |
| ); |
| |
| gceSTATUS |
| gcfMEM_VSMemPoolGetANode( |
| IN gcsMEM_VS_MEM_POOL MemPool, |
| IN gctUINT Size, |
| IN gctUINT Alignment, |
| OUT gctPOINTER * Node |
| ); |
| |
| gceSTATUS |
| gcfMEM_VSMemPoolFreeANode( |
| IN gcsMEM_VS_MEM_POOL MemPool, |
| IN gctPOINTER Node |
| ); |
| |
| gceSTATUS |
| gcfMEM_InitAFSMemPool( |
| IN gcsMEM_AFS_MEM_POOL *MemPool, |
| IN gcoOS OS, |
| IN gctUINT NodeCount, |
| IN gctUINT NodeSize |
| ); |
| |
| gceSTATUS |
| gcfMEM_FreeAFSMemPool( |
| IN gcsMEM_AFS_MEM_POOL *MemPool |
| ); |
| |
| gceSTATUS |
| gcfMEM_AFSMemPoolGetANode( |
| IN gcsMEM_AFS_MEM_POOL MemPool, |
| IN gctUINT Count, |
| OUT gctPOINTER * Node |
| ); |
| |
| gceSTATUS |
| gcfMEM_AFSMemPoolFreeANode( |
| IN gcsMEM_AFS_MEM_POOL MemPool, |
| IN gctPOINTER Node |
| ); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* (gcdENABLE_3D || gcdENABLE_VG) */ |
| #endif /* __gc_hal_mem_h_ */ |