summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authortreectrl <treectrl>2005-09-07 22:25:29 (GMT)
committertreectrl <treectrl>2005-09-07 22:25:29 (GMT)
commit1683902839a418218e9fa5a6e4e0248ff2160493 (patch)
treea294be81d9d1ea1ef6ebb70953b194e8674b9fec /generic
parent29614aa230863e6c3a8bed03f48d4f2f5f75cdbd (diff)
downloadtktreectrl-1683902839a418218e9fa5a6e4e0248ff2160493.zip
tktreectrl-1683902839a418218e9fa5a6e4e0248ff2160493.tar.gz
tktreectrl-1683902839a418218e9fa5a6e4e0248ff2160493.tar.bz2
Commented AllocHax stuff. Changed how AllocHax_Free calculates the address of the AllocElem using Tcl_DbCkfree() as a guide.
Diffstat (limited to 'generic')
-rw-r--r--generic/tkTreeUtils.c72
1 files changed, 59 insertions, 13 deletions
diff --git a/generic/tkTreeUtils.c b/generic/tkTreeUtils.c
index 13f3761..5696eff 100644
--- a/generic/tkTreeUtils.c
+++ b/generic/tkTreeUtils.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2005 Tim Baker
*
- * RCS: @(#) $Id: tkTreeUtils.c,v 1.32 2005/09/07 20:35:30 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeUtils.c,v 1.33 2005/09/07 22:25:29 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -2410,32 +2410,65 @@ void PSTRestore(
#ifdef ALLOC_HAX
+/*
+ * The following AllocHax_xxx calls implement a mini memory allocator that
+ * allocates blocks of same-sized chunks, and hold on to those chunks when
+ * they are freed so they can be reused quickly. If you don't want to use it
+ * just comment out #define ALLOC_HAX in tkTreeCtrl.h.
+ */
+
typedef struct AllocElem AllocElem;
typedef struct AllocList AllocList;
typedef struct AllocData AllocData;
+/*
+ * One of the following structures exists for each client block of memory.
+ */
+
struct AllocElem
{
AllocElem *next;
int free;
- char d[1];
+ char body[1]; /* First byte of client's space. Actual
+ * size of this field will be larger than
+ * one. */
};
+/*
+ * One of the following structures maintains a list of blocks of AllocElems
+ * of the same size.
+ */
+
struct AllocList
{
- int size;
+ int size; /* Size of every AllocElem.body[] */
AllocElem *head;
- AllocList *next;
- AllocElem **blocks;
- int blockCount;
- int blockSize;
+ AllocList *next; /* Points to an AllocList with a different .size */
+ AllocElem **blocks; /* Array of pointers to allocated blocks. The blocks
+ * may contain a different number of elements. */
+ int blockCount; /* Number of array elements in .blocks */
+ int blockSize; /* The number of AllocElems per block to allocate.
+ * Starts at 16 and gets double up to 1024. */
};
+/*
+ * A pointer to one of the following structures is stored in each TreeCtrl.
+ */
+
struct AllocData
{
AllocList *freeLists;
};
+/*
+ * The following macro computes the offset of the "body" field within
+ * AllocElem. It is used to get back to the header pointer from the
+ * body pointer that's used by clients.
+ */
+
+#define BODY_OFFSET \
+ ((unsigned long) (&((AllocElem *) 0)->body))
+
char *AllocHax_Alloc(ClientData data, int size)
{
AllocList *freeLists = ((AllocData *) data)->freeLists;
@@ -2465,15 +2498,18 @@ char *AllocHax_Alloc(ClientData data, int size)
} else {
AllocElem *block;
freeList->blockCount += 1;
- freeList->blocks = (AllocElem **) ckrealloc((char *) freeList->blocks, sizeof(AllocElem *) * freeList->blockCount);
- block = (AllocElem *) ckalloc((sizeof(AllocElem) - 1 + size) * freeList->blockSize);
+ freeList->blocks = (AllocElem **) ckrealloc((char *) freeList->blocks,
+ sizeof(AllocElem *) * freeList->blockCount);
+ block = (AllocElem *) ckalloc((sizeof(AllocElem) - 1 + size) *
+ freeList->blockSize);
freeList->blocks[freeList->blockCount - 1] = block;
/* dbwin("AllocHax_Alloc alloc %d of size %d\n", freeList->blockSize, size); */
freeList->head = block;
elem = freeList->head;
for (i = 1; i < freeList->blockSize - 1; i++) {
elem->free = 1;
- elem->next = (AllocElem *) (((char *) freeList->head) + (sizeof(AllocElem) - 1 + size) * i);
+ elem->next = (AllocElem *) (((char *) freeList->head) +
+ (sizeof(AllocElem) - 1 + size) * i);
elem = elem->next;
}
elem->next = NULL;
@@ -2488,21 +2524,31 @@ char *AllocHax_Alloc(ClientData data, int size)
panic("AllocHax_Alloc: element not marked free");
result->free = 0;
- return result->d;
+ return result->body;
}
void AllocHax_Free(ClientData data, char *ptr, int size)
{
AllocList *freeLists = ((AllocData *) data)->freeLists;
AllocList *freeList = freeLists;
- AllocElem *elem = (AllocElem *) (ptr - sizeof(AllocElem) + sizeof(int));
+ AllocElem *elem;
+
+ /*
+ * See comment from Tcl_DbCkfree before you change the following
+ * line.
+ */
+
+ elem = (AllocElem *) (((unsigned long) ptr) - BODY_OFFSET);
if (elem->free)
panic("AllocHax_Free: element already marked free");
while (freeList != NULL && freeList->size != size)
freeList = freeList->next;
- WIPE(ptr, size);
+ if (freeList == NULL)
+ panic("AllocHax_Free: can't find free list for size %d", size);
+
+ WIPE(elem->body, size);
elem->next = freeList->head;
elem->free = 1;
freeList->head = elem;