]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/audio-preprocessing.git/blob - file_demo_bios/k2g/components/mhm/src/mhm.c
audio-preprocessing-fw: Add TI license header; remove the PDF file.
[processor-sdk/audio-preprocessing.git] / file_demo_bios / k2g / components / mhm / src / mhm.c
1 /******************************************************************************\r
2  * FILE PURPOSE: Multiple heap manager.\r
3  ******************************************************************************\r
4  * FILE NAME:   mhm.c\r
5  *\r
6  * DESCRIPTION: Contains routines for multiple heap management. These functions\r
7  *              may be used in allocating memory from several independent\r
8  *              memory pools.\r
9  *\r
10  *              NOTE: Current implementation does NOT provide deallocation!\r
11  *\r
12  * TABS: NONE\r
13  *\r
14  * $Id: mhm.c 1.1 1997/06/25 11:40:55 BOGDANK Exp $\r
15  *\r
16  * REVISION HISTORY:\r
17  *\r
18  * $Log: mhm.c $\r
19  * Revision 1.1  1997/06/25 11:40:55  BOGDANK\r
20  * Initial revision\r
21  *\r
22  * Copyright (c) 2016, Texas Instruments Incorporated
23  * All rights reserved.
24  *
25  * Redistribution and use in source and binary forms, with or without
26  * modification, are permitted provided that the following conditions
27  * are met:
28  *
29  * *  Redistributions of source code must retain the above copyright
30  *    notice, this list of conditions and the following disclaimer.
31  *
32  * *  Redistributions in binary form must reproduce the above copyright
33  *    notice, this list of conditions and the following disclaimer in the
34  *    documentation and/or other materials provided with the distribution.
35  *
36  * *  Neither the name of Texas Instruments Incorporated nor the names of
37  *    its contributors may be used to endorse or promote products derived
38  *    from this software without specific prior written permission.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
42  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
44  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
46  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
47  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
48  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
49  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
50  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51  *
52  */
53 \r
54 #include <stdlib.h>\r
55 #include <string.h>                                            /* for memset */\r
56 \r
57 #include <xdc/std.h>\r
58 /* System definitions and utilities */\r
59 #include <ti/mas/types/types.h>               /* DSP types                   */\r
60 \r
61 //#include <ti/mas/mhm/mhm.h>\r
62 //#include <ti/mas/mhm/src/mhmport.h>\r
63 \r
64 #include "../mhm.h"\r
65 #include "mhmport.h"\r
66 \r
67 /* Heap header that is placed at the beginning of a memory pool. */\r
68 typedef struct {\r
69   tuint  total_size;   /* total number of words in a memory pool */\r
70   tuint  used_size;    /* index of the first available word */\r
71 } mhmHead_t;\r
72 \r
73 /* The minimum and maximum number of words in a memory pool. Align gap and\r
74  *  maximum size value are specified in mhmport.h. */\r
75 #define MHM_MIN_POOLSIZE  (sizeof(mhmHead_t)+MHM_MAX_ALIGNGAP+1)\r
76 #define MHM_MAX_POOLSIZE  MHM_MAX_SIZEVAL\r
77 \f\r
78 /******************************************************************************\r
79  * FUNCTION PURPOSE: Create and initialize a heap.\r
80  ******************************************************************************\r
81  * DESCRIPTION: Creates and initializes a heap. If successful returns a heap\r
82  *              handle, otherwise returns NULL.\r
83  *\r
84  *  void *mhmCreate (\r
85  *    void *base,         - base address of a memory pool (!= NULL)\r
86  *    tuint size,          - number of words within the memory pool\r
87  *    word initPattern)   - initializing pattern for the heap\r
88  *\r
89  *  RETURN VALUE: A heap handle, or NULL in case of error.\r
90  *\r
91  *****************************************************************************/\r
92 \r
93 void *mhmCreate (void *base, tuint size, tword initPattern)\r
94 {\r
95   tuint      used_size;\r
96   mhmHead_t *head;\r
97   tword      *w_base = (tword *)base;\r
98   tword      *block;\r
99   mhmAddress_t  wa_base_new, wa_block_new;\r
100 \r
101   /* initialize the raw space */\r
102   memset (w_base, initPattern, size);\r
103   \r
104   /* In the first part we align the base address of the memory pool */\r
105   used_size = 0;\r
106   wa_base_new = ((mhmAddress_t)w_base + MHM_MAX_ALIGNGAP) & (~MHM_ALIGN_MASK);\r
107   used_size += wa_base_new - (mhmAddress_t)w_base;\r
108   w_base = (tword *)wa_base_new;        /* this is the new base after any gap */\r
109 \r
110   if (size < used_size+MHM_MIN_POOLSIZE || size-used_size > MHM_MAX_POOLSIZE ||\r
111       base == NULL)\r
112     return(NULL);\r
113 \r
114   /* Skip the pool alignment gap and start fresh. Do not forget to reset used size. */\r
115   /* w_base points to aligned address now and used_size is currently the gap size (if any) */\r
116   head = (mhmHead_t*)w_base;            /* This will be the actual head of the heap */\r
117   head->total_size = size - used_size;  /* record total heap size by removing the gap size */\r
118 \r
119   used_size = sizeof(mhmHead_t);    /* reserve space for the header and make that the used size */\r
120   block     = &w_base[used_size];   /* skip the header */\r
121 \r
122   /* Remember to align the remaining pool to the minimum alignment required by MHM  */\r
123   wa_block_new = ((mhmAddress_t)block + MHM_MAX_ALIGNGAP) & (~MHM_ALIGN_MASK);\r
124   used_size += wa_block_new - (mhmAddress_t)block;\r
125 \r
126   head->used_size = used_size;    /* record an index to empty space which is with minimum alignment */\r
127   return(head);                   /* return heap handle */\r
128 } /* mhmCreate */\r
129 \f\r
130 /******************************************************************************\r
131  * FUNCTION PURPOSE: Allocate a block of memory from a heap.\r
132  ******************************************************************************\r
133  * DESCRIPTION: Allocates a block of memory from a heap. Block size must be\r
134  *              bigger than zero. It returns a pointer to block start or a\r
135  *              NULL if unsuccessful.\r
136  *\r
137  *  void *mhmAlloc (\r
138  *    void *handle,     - heap handle obtained in mhmCreate()\r
139  *    tuint size)        - number of words to allocate for the block\r
140  *\r
141  *  RETURN VALUE: A pointer to block start, or NULL when unsuccessful.\r
142  *\r
143  *****************************************************************************/\r
144 \r
145 void *mhmAlloc (void *handle, tuint size)\r
146 {\r
147   tuint      left;\r
148   mhmHead_t *head = (mhmHead_t*)handle;\r
149   tword      *w_base = (tword *)handle;\r
150   tword      *block;\r
151 \r
152   if (size == 0 || size > MHM_MAX_SIZE || head->total_size <= head->used_size)\r
153     return(NULL);\r
154 \r
155   /* Make sure the actual used size will be resulting in minimum required MHM alignment */\r
156   size = (tuint)((size + MHM_MAX_ALIGNGAP) & (~MHM_ALIGN_MASK));\r
157 \r
158   left = head->total_size - head->used_size;\r
159   if (left < size)                      /* do we have space for this block? */\r
160     return(NULL);\r
161   block = &w_base[head->used_size];\r
162   head->used_size += (tuint)size;       /* increase the used space */\r
163 \r
164   /* no need for additional alignment since the size was already aligned above and base is\r
165    *  always kept aligned to the minimum requried MHM alignment */\r
166 \r
167   return(block);                        /* return a pointer to start */\r
168 } /* mhmAlloc */\r
169 \r
170 /******************************************************************************\r
171  * FUNCTION PURPOSE: Allocate a block of memory from a heap log2 aligned\r
172  ******************************************************************************\r
173  * DESCRIPTION: Allocates a block of memory from a heap. Block size must be\r
174  *              bigger than zero. It returns a pointer to block start or a\r
175  *              NULL if unsuccessful. The start address will be aligned to pow-2\r
176  *              boundary.\r
177  *\r
178  *  void *mhmAllocAligned (\r
179  *    void *handle,     - heap handle obtained in mhmCreate()\r
180  *    tuint size,       - number of words to allocate for the block\r
181  *    tint  log2align)  - log2 alignment that is required (e.g. 3 for 0xFF..FF8 mask)\r
182  *\r
183  *  RETURN VALUE: A pointer to block start, or NULL when unsuccessful.\r
184  *\r
185  *****************************************************************************/\r
186 \r
187 void *mhmAllocAligned (void *handle, tuint size, tint log2align)\r
188 {\r
189   tuint         left, used_size;\r
190   mhmHead_t     *head   = (mhmHead_t*)handle;\r
191   tword         *w_base = (tword *)handle;\r
192   tword         *block;\r
193   tulong        align_mask, align_gap;\r
194   mhmAddress_t  wa_block_new;\r
195 \r
196   if (size == 0 || size > MHM_MAX_SIZE || head->total_size <= head->used_size)\r
197     return(NULL);\r
198 \r
199   if (log2align < 1) {                  /* use simple alloc function if no alignment required */\r
200     block = mhmAlloc(handle, size);\r
201     return(block);\r
202   }\r
203   used_size = head->used_size;      /* current used size */\r
204   block     = &w_base[used_size];   /* skip the already used size */\r
205 \r
206   /* Remember to align the new block address to the requested alignment */\r
207   align_mask = ((~0UL) << log2align);\r
208   align_gap = (~align_mask);\r
209 \r
210   wa_block_new = (((mhmAddress_t)block + align_gap) & align_mask);\r
211   size += wa_block_new - (mhmAddress_t)block;       /* update size with the gap (if any) */\r
212 \r
213   /* Make sure the actual used size will be resulting in minimum required MHM alignment */\r
214   /* This in general may be different from the requested start address alignment! */\r
215   size = (tuint)((size + MHM_MAX_ALIGNGAP) & (~MHM_ALIGN_MASK));\r
216 \r
217   left = head->total_size - used_size;\r
218   if (left < size)                      /* do we have space for this block? (and any gaps) */\r
219     return(NULL);\r
220   block = (tword*)wa_block_new;         /* this is where we would start new block */\r
221   head->used_size = used_size+size;     /* increase the used space */\r
222 \r
223   /* no need for additional alignment since the size and base were already aligned above */\r
224 \r
225   return(block);                        /* return a pointer to start */\r
226 } /* mhmAllocAligned */\r
227 \r
228 /******************************************************************************\r
229  * FUNCTION PURPOSE: Deallocate a memory block from a heap.\r
230  ******************************************************************************\r
231  * DESCRIPTION: Deallocates a memory block from a heap.\r
232  *\r
233  *  void mhmFree (\r
234  *    void *handle,     - a heap handle\r
235  *    void *base)       - base address of a block\r
236  *\r
237  *****************************************************************************/\r
238 \r
239 void mhmFree (void *handle, void *base)\r
240 {\r
241   return;           /* currently NOT supported */\r
242 } /* mhmFree */\r
243 \r
244 /******************************************************************************\r
245  * FUNCTION PURPOSE: Reset heap and start allocating form the beginning.\r
246  ******************************************************************************\r
247  * DESCRIPTION: Resets heap and allows for allocation to start from the beginning.\r
248  *\r
249  *  void mhmReset (\r
250  *    void *handle)     - a heap handle\r
251  *\r
252  *****************************************************************************/\r
253 \r
254 void mhmReset (void *handle)\r
255 {\r
256   tuint         used_size;\r
257   mhmHead_t     *head = (mhmHead_t*)handle;\r
258   tword         *w_base = (tword*)handle;\r
259   tword         *block;\r
260   mhmAddress_t  wa_block_new;\r
261 \r
262   /* no need to change the total size */\r
263   /* we start from empty heap */\r
264   used_size = sizeof(mhmHead_t);    /* reserve space for the header and make that the used size */\r
265   block     = &w_base[used_size];   /* skip the header */\r
266 \r
267   /* Remember to align the remaining pool to the minimum alignment required by MHM  */\r
268   wa_block_new = ((mhmAddress_t)block + MHM_MAX_ALIGNGAP) & (~MHM_ALIGN_MASK);\r
269   used_size += wa_block_new - (mhmAddress_t)block;\r
270 \r
271   head->used_size = used_size;    /* record an index to empty space which is with minimum alignment */\r
272 \r
273   /* the head which is the base of the heap is already aligned */\r
274   return;\r
275 } /* mhmreset */\r
276 \r
277 /* nothing past this point */\r
278 \r