diff options
Diffstat (limited to 'e-util')
-rw-r--r-- | e-util/ChangeLog | 6 | ||||
-rw-r--r-- | e-util/e-memory.c | 67 |
2 files changed, 29 insertions, 44 deletions
diff --git a/e-util/ChangeLog b/e-util/ChangeLog index 480b2f7ace..797ea0a5ea 100644 --- a/e-util/ChangeLog +++ b/e-util/ChangeLog @@ -1,3 +1,9 @@ +2001-02-08 Not Zed <NotZed@Ximian.com> + + * e-memory.c (EMemChunk): Changed to allocate raw blocks for the + data, and keep track of them with an array, this is so the native + malloc alignment is not lost at the allocation stage. + 2001-01-30 Not Zed <NotZed@Ximian.com> * e-msgport.c (e_thread_destroy): Turn on joining of cancelled threads. diff --git a/e-util/e-memory.c b/e-util/e-memory.c index 21195edbb1..2e505785f6 100644 --- a/e-util/e-memory.c +++ b/e-util/e-memory.c @@ -64,15 +64,10 @@ typedef struct _MemChunkFreeNode { unsigned int atoms; } MemChunkFreeNode; -typedef struct _MemChunkNode { - struct _MemChunkNode *next; - char data[1]; -} MemChunkNode; - typedef struct _EMemChunk { unsigned int blocksize; /* number of atoms in a block */ unsigned int atomsize; /* size of each atom */ - struct _MemChunkNode *blocks; + GPtrArray *blocks; /* blocks of raw memory */ struct _MemChunkFreeNode *free; } MemChunk; @@ -95,7 +90,7 @@ MemChunk *e_memchunk_new(int atomcount, int atomsize) m->blocksize = atomcount; m->atomsize = MAX(atomsize, sizeof(MemChunkFreeNode)); - m->blocks = NULL; + m->blocks = g_ptr_array_new(); m->free = NULL; return m; @@ -109,7 +104,7 @@ MemChunk *e_memchunk_new(int atomcount, int atomsize) **/ void *e_memchunk_alloc(MemChunk *m) { - MemChunkNode *b; + char *b; MemChunkFreeNode *f; void *mem; @@ -124,14 +119,13 @@ void *e_memchunk_alloc(MemChunk *m) } return mem; } else { - b = g_malloc(m->blocksize * m->atomsize + sizeof(*b) - sizeof(char)); - b->next = m->blocks; - m->blocks = b; - f = (MemChunkFreeNode *)&b->data[m->atomsize]; + b = g_malloc(m->blocksize * m->atomsize); + g_ptr_array_add(m->blocks, b); + f = (MemChunkFreeNode *)&b[m->atomsize]; f->atoms = m->blocksize-1; f->next = NULL; m->free = f; - return &b->data; + return b; } } @@ -182,12 +176,11 @@ e_memchunk_free(MemChunk *m, void *mem) void e_memchunk_empty(MemChunk *m) { - MemChunkNode *b; + int i; MemChunkFreeNode *f, *h = NULL; - b = m->blocks; - while (b) { - f = (MemChunkFreeNode *)&b->data[0]; + for (i=0;i<m->blocks->len;i++) { + f = (MemChunkFreeNode *)m->blocks->pdata[i]; f->atoms = m->blocksize; f->next = h; h = f; @@ -197,7 +190,7 @@ e_memchunk_empty(MemChunk *m) struct _cleaninfo { struct _cleaninfo *next; - MemChunkNode *base; + char *base; int count; int size; /* just so tree_search has it, sigh */ }; @@ -213,8 +206,8 @@ static int tree_compare(struct _cleaninfo *a, struct _cleaninfo *b) static int tree_search(struct _cleaninfo *a, char *mem) { - if (a->base->data <= mem) { - if (mem < &a->base->data[a->size]) + if (a->base <= mem) { + if (mem < &a->base[a->size]) return 0; return 1; } @@ -236,26 +229,24 @@ void e_memchunk_clean(MemChunk *m) { GTree *tree; - MemChunkNode *b, *n; + int i; MemChunkFreeNode *f; struct _cleaninfo *ci, *hi = NULL; - b = m->blocks; f = m->free; - if (b == NULL || f == NULL) + if (m->blocks->len == 0 || f == NULL) return; /* first, setup the tree/list so we can map free block addresses to block addresses */ tree = g_tree_new((GCompareFunc)tree_compare); - while (b) { + for (i=0;i<m->blocks->len;i++) { ci = alloca(sizeof(*ci)); ci->count = 0; - ci->base = b; + ci->base = m->blocks->pdata[i]; ci->size = m->blocksize * m->atomsize; g_tree_insert(tree, ci, ci); ci->next = hi; hi = ci; - b = b->next; } /* now, scan all free nodes, and count them in their tree node */ @@ -273,17 +264,8 @@ e_memchunk_clean(MemChunk *m) ci = hi; while (ci) { if (ci->count == m->blocksize) { - b = (MemChunkNode *)&m->blocks; - n = b->next; - while (n) { - if (n == ci->base) { - b->next = n->next; - g_free(n); - break; - } - b = n; - n = b->next; - } + g_ptr_array_remove_fast(m->blocks, ci->base); + g_free(ci->base); } ci = ci->next; } @@ -300,17 +282,14 @@ e_memchunk_clean(MemChunk *m) void e_memchunk_destroy(MemChunk *m) { - MemChunkNode *b, *n; + int i; if (m == NULL) return; - b = m->blocks; - while (b) { - n = b->next; - g_free(b); - b = n; - } + for (i=0;i<m->blocks->len;i++) + g_free(m->blocks->pdata[i]); + g_ptr_array_free(m->blocks, TRUE); g_free(m); } |