1717
1818#include "GL/glus.h"
1919
20- // 4 byte alignment.
21- #define GLUS_ALIGNMENT 4
20+ // Data type used for the memory array.
21+ #define GLUS_MEMORY_DATA_TYPE uint32_t
22+
23+ // Data size of the data type.
24+ #define GLUS_MEMORY_DATA_SIZE sizeof(GLUS_MEMORY_DATA_TYPE)
25+
26+ // Alignment in memory.
27+ #define GLUS_MEMORY_DATA_ALIGNMENT_SIZE (GLUS_MEMORY_DATA_SIZE * 2)
28+
29+ // Factor to get the right alignment.
30+ #define GLUS_MEMORY_DATAT_ALIGNMENT_FACTOR (GLUS_MEMORY_DATA_ALIGNMENT_SIZE / GLUS_MEMORY_DATA_SIZE)
2231
2332// 128 MB of memory. Change only here, if more or less is needed.
24- // Division by 4 bytes, as uint32_t is used.
25- #define GLUS_MEMORY_SIZE (128*1024*1024/GLUS_ALIGNMENT)
33+ #define GLUS_MEMORY_SIZE (128*1024*1024/GLUS_MEMORY_DATA_SIZE)
2634
2735// Number of memory table entries.
28- #define GLUS_MEMORY_TABLE_ENTRIES 1024
36+ #define GLUS_MEMORY_TABLE_ENTRIES 2048
2937
3038// States of a memory block entry.
3139#define GLUS_VALID_AND_FREE 1
@@ -55,9 +63,9 @@ typedef struct _GLUSmemoryTable {
5563} GLUSmemoryTable ;
5664
5765/**
58- * Available memory with 4 byte alignment. If alignment is changed, do also adapt size .
66+ * Available memory with given data type .
5967 */
60- static uint32_t g_memory [GLUS_MEMORY_SIZE ];
68+ static GLUS_MEMORY_DATA_TYPE g_memory [GLUS_MEMORY_SIZE ];
6169
6270/**
6371 * Memory table used to manage the memory array.
@@ -69,37 +77,29 @@ static GLUSmemoryTable g_memoryTable[GLUS_MEMORY_TABLE_ENTRIES] = {{GLUS_VALID_A
6977 */
7078static size_t g_memoryTableEntries = 1 ;
7179
72- static GLUSboolean glusMemoryFindTableEntry (size_t * foundTableIndex )
80+ static GLUSboolean glusMemoryInitTableEntry (size_t startIndex , size_t lengthIndices )
7381{
74- GLUSuint tableIndex = 0 ;
82+ size_t tableIndex = 0 ;
7583
76- if (!foundTableIndex )
77- {
78- return GLUS_FALSE ;
79- }
84+ //
8085
81- while (tableIndex < g_memoryTableEntries )
82- {
83- // If not valid, the table entry can be reused.
84- if (g_memoryTable [tableIndex ].status == GLUS_INVALID )
85- {
86- * foundTableIndex = tableIndex ;
86+ while (tableIndex < g_memoryTableEntries )
87+ {
88+ // If not valid, the table entry can be reused.
89+ if (g_memoryTable [tableIndex ].status == GLUS_INVALID )
90+ {
91+ break ;
92+ }
8793
88- return GLUS_TRUE ;
89- }
94+ tableIndex ++ ;
95+ }
9096
91- tableIndex ++ ;
92- }
97+ if (tableIndex >= GLUS_MEMORY_TABLE_ENTRIES )
98+ {
99+ return GLUS_FALSE ;
100+ }
93101
94- return GLUS_FALSE ;
95- }
96-
97- static GLUSboolean glusMemoryInitTableEntry (size_t tableIndex , size_t startIndex , size_t lengthIndices )
98- {
99- if (tableIndex > g_memoryTableEntries || tableIndex >= GLUS_MEMORY_TABLE_ENTRIES )
100- {
101- return GLUS_FALSE ;
102- }
102+ //
103103
104104 g_memoryTable [tableIndex ].status = GLUS_VALID_AND_FREE ;
105105 g_memoryTable [tableIndex ].startIndex = startIndex ;
@@ -148,6 +148,7 @@ static GLUSvoid glusMemoryGarbageCollect()
148148
149149 g_memoryTable [otherTableIndex ].status = GLUS_INVALID ;
150150
151+ // Continue to try to merge.
151152 continueGC = GLUS_TRUE ;
152153 }
153154 }
@@ -165,33 +166,38 @@ static void* glusMemoryInternalMalloc(size_t size)
165166{
166167 GLUSuint tableIndex = 0 ;
167168
168- // 4 byte alignment.
169- size_t lengthIndices = size % GLUS_ALIGNMENT == 0 ? (size / GLUS_ALIGNMENT ) : (size / GLUS_ALIGNMENT + 1 );
169+ // Calculate needed indecies.
170+ size_t lengthIndices = size % GLUS_MEMORY_DATA_SIZE == 0 ? (size / GLUS_MEMORY_DATA_SIZE ) : (size / GLUS_MEMORY_DATA_SIZE + 1 );
171+
172+ size_t alignmentIndicesRest = lengthIndices % GLUS_MEMORY_DATAT_ALIGNMENT_FACTOR ;
170173
171- if (lengthIndices * GLUS_ALIGNMENT < size )
174+ // Needed for overflow of lengthIndices.
175+ if (lengthIndices * GLUS_MEMORY_DATA_SIZE < size )
172176 {
173177 return 0 ;
174178 }
175179
180+ // Test an adjust alignment.
181+ if (alignmentIndicesRest != 0 )
182+ {
183+ lengthIndices += GLUS_MEMORY_DATAT_ALIGNMENT_FACTOR - alignmentIndicesRest ;
184+ }
185+
176186 while (tableIndex < g_memoryTableEntries )
177187 {
178188 // Search for a memory table entry, where the size fits in.
179189 if (g_memoryTable [tableIndex ].status == GLUS_VALID_AND_FREE && g_memoryTable [tableIndex ].lengthIndices >= lengthIndices )
180190 {
181- size_t otherTableIndex ;
182-
183- // Try to reuse an entry.
184- if (!glusMemoryFindTableEntry (& otherTableIndex ))
185- {
186- otherTableIndex = tableIndex + 1 ;
187- }
188-
189- // Assign the rest of the available memory to another table entry.
190- if (!glusMemoryInitTableEntry (otherTableIndex , g_memoryTable [tableIndex ].startIndex + lengthIndices , g_memoryTable [tableIndex ].lengthIndices - lengthIndices ))
191- {
192- // No empty entry could be found, so do not split and use all memory.
193- lengthIndices = g_memoryTable [tableIndex ].lengthIndices ;
194- }
191+ // Is a split needed?
192+ if (lengthIndices < g_memoryTable [tableIndex ].lengthIndices )
193+ {
194+ // Assign the rest of the available memory to another table entry.
195+ if (!glusMemoryInitTableEntry (g_memoryTable [tableIndex ].startIndex + lengthIndices , g_memoryTable [tableIndex ].lengthIndices - lengthIndices ))
196+ {
197+ // No empty entry could be found, so do not split and use all memory.
198+ lengthIndices = g_memoryTable [tableIndex ].lengthIndices ;
199+ }
200+ }
195201
196202 // Entry now manages the requested memory.
197203 g_memoryTable [tableIndex ].status = GLUS_VALID_AND_LOCKED ;
0 commit comments