summaryrefslogtreecommitdiffstats
path: root/generic/tkTreeUtils.c
diff options
context:
space:
mode:
authortreectrl <treectrl>2006-10-18 22:18:47 (GMT)
committertreectrl <treectrl>2006-10-18 22:18:47 (GMT)
commit48b5dede130f986694ce38dbadc4a08f1c4c6f98 (patch)
treead939fb4b9f8970eb57878e74e313c40a304b98b /generic/tkTreeUtils.c
parent0ac279aba65c5ca2d39a8ef7452ced2b566ce545 (diff)
downloadtktreectrl-48b5dede130f986694ce38dbadc4a08f1c4c6f98.zip
tktreectrl-48b5dede130f986694ce38dbadc4a08f1c4c6f98.tar.gz
tktreectrl-48b5dede130f986694ce38dbadc4a08f1c4c6f98.tar.bz2
Per-state images call Tree_FreeImage to decrement the reference count on an image. Previously the image instance was not freed until the tree was destroyed.
Fiddled with AllocHax code. AllocHax_Stats dumps the result to the interpreter directly, instead of returning an malloc'd string.
Diffstat (limited to 'generic/tkTreeUtils.c')
-rw-r--r--generic/tkTreeUtils.c73
1 files changed, 37 insertions, 36 deletions
diff --git a/generic/tkTreeUtils.c b/generic/tkTreeUtils.c
index f703fec..3fb1046 100644
--- a/generic/tkTreeUtils.c
+++ b/generic/tkTreeUtils.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 2002-2006 Tim Baker
*
- * RCS: @(#) $Id: tkTreeUtils.c,v 1.43 2006/10/18 03:49:18 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeUtils.c,v 1.44 2006/10/18 22:18:47 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -2785,7 +2785,8 @@ static void PSDImageFree(TreeCtrl *tree, PerStateDataImage *pImage)
{
if (pImage->string != NULL)
ckfree(pImage->string);
- /* don't free image */
+ if (pImage->image != NULL)
+ Tree_FreeImage(tree, pImage->image);
}
PerStateType pstImage =
@@ -2916,6 +2917,7 @@ void PSTRestore(
*/
typedef struct AllocElem AllocElem;
+typedef struct AllocBlock AllocBlock;
typedef struct AllocList AllocList;
typedef struct AllocData AllocData;
@@ -2931,7 +2933,6 @@ typedef struct AllocStats AllocStats;
* One of the following structures exists for each client piece of memory.
* These structures are allocated in arrays (blocks).
*/
-
struct AllocElem
{
AllocElem *next;
@@ -2944,18 +2945,23 @@ struct AllocElem
* one. */
};
+struct AllocBlock
+{
+ int count; /* Size of .elem[] */
+ AllocBlock *next; /* Next block with same-sized elems. */
+ AllocElem elem[1]; /* Actual size will be larger than one. */
+};
+
/*
* One of the following structures maintains an array of blocks of AllocElems
* of the same size.
*/
-
struct AllocList
{
int size; /* Size of every AllocElem.body[] */
AllocElem *head; /* Top of stack of unused pieces of memory. */
- AllocElem **blocks; /* Array of pointers to allocated blocks. The blocks
+ AllocBlock *blocks; /* Linked list of 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 doubled up to 1024. */
AllocList *next; /* Points to an AllocList with a different .size */
@@ -2964,7 +2970,6 @@ struct AllocList
/*
* A pointer to one of the following structures is stored in each TreeCtrl.
*/
-
struct AllocData
{
AllocList *freeLists; /* Linked list. */
@@ -3018,14 +3023,15 @@ AllocStats_Get(
return stats;
}
-char *
+void
AllocHax_Stats(
+ Tcl_Interp *interp,
ClientData _data
)
{
AllocData *data = (AllocData *) _data;
AllocStats *stats = data->stats;
- char *result, buf[128];
+ char buf[128];
Tcl_DString dString;
Tcl_DStringInit(&dString);
@@ -3036,10 +3042,7 @@ AllocHax_Stats(
Tcl_DStringAppend(&dString, buf, -1);
stats = stats->next;
}
- result = ckalloc(Tcl_DStringLength(&dString) + 1);
- strcpy(result, Tcl_DStringValue(&dString));
- Tcl_DStringFree(&dString);
- return result;
+ Tcl_DStringResult(interp, &dString);
}
#endif /* ALLOC_STATS */
@@ -3071,6 +3074,7 @@ AllocHax_Alloc(
AllocData *data = (AllocData *) _data;
AllocList *freeLists = data->freeLists;
AllocList *freeList = freeLists;
+ AllocBlock *block;
AllocElem *elem, *result;
#ifdef ALLOC_STATS
AllocStats *stats = AllocStats_Get(_data, id);
@@ -3091,28 +3095,27 @@ AllocHax_Alloc(
freeList->head = NULL;
freeList->next = freeLists;
freeList->blocks = NULL;
- freeList->blockCount = 0;
freeList->blockSize = 16;
freeLists = freeList;
((AllocData *) data)->freeLists = freeLists;
}
- if (freeList->head != NULL) {
- elem = freeList->head;
- freeList->head = elem->next;
- result = elem;
- } else {
- AllocElem *block;
+ if (freeList->head == NULL) {
unsigned elemSize = TCL_ALIGN(BODY_OFFSET + size);
- freeList->blockCount += 1;
- freeList->blocks = (AllocElem **) ckrealloc((char *) freeList->blocks,
- sizeof(AllocElem *) * freeList->blockCount);
- block = (AllocElem *) ckalloc(elemSize * freeList->blockSize);
- freeList->blocks[freeList->blockCount - 1] = block;
+
+ block = (AllocBlock *) ckalloc(Tk_Offset(AllocBlock, elem) +
+ elemSize * freeList->blockSize);
+ block->count = freeList->blockSize;
+ block->next = freeList->blocks;
+
/* dbwin("AllocHax_Alloc alloc %d of size %d\n", freeList->blockSize, size); */
- freeList->head = block;
+ freeList->blocks = block;
+ if (freeList->blockSize < 1024)
+ freeList->blockSize *= 2;
+
+ freeList->head = block->elem;
elem = freeList->head;
- for (i = 1; i < freeList->blockSize - 1; i++) {
+ for (i = 1; i < block->count - 1; i++) {
#ifdef TREECTRL_DEBUG
elem->free = 1;
elem->size = size;
@@ -3126,12 +3129,10 @@ AllocHax_Alloc(
elem->free = 1;
elem->size = size;
#endif
- result = freeList->head;
- freeList->head = result->next;
- if (freeList->blockSize < 1024)
- freeList->blockSize *= 2;
}
+ result = freeList->head;
+ freeList->head = result->next;
#ifdef TREECTRL_DEBUG
if (!result->free)
panic("AllocHax_Alloc: element not marked free");
@@ -3372,15 +3373,15 @@ AllocHax_Finalize(
#ifdef ALLOC_STATS
AllocStats *stats = data->stats;
#endif
- int i;
while (freeList != NULL) {
AllocList *nextList = freeList->next;
- for (i = 0; i < freeList->blockCount; i++) {
- AllocElem *block = freeList->blocks[i];
+ AllocBlock *block = freeList->blocks;
+ while (block != NULL) {
+ AllocBlock *nextBlock = block->next;
ckfree((char *) block);
+ block = nextBlock;
}
- ckfree((char *) freeList->blocks);
ckfree((char *) freeList);
freeList = nextList;
}
@@ -3564,7 +3565,7 @@ TreePtrList_Free(
}
#define TAG_INFO_SIZE(tagSpace) \
- (sizeof(TagInfo) + (((tagSpace) - TREE_TAG_SPACE) * sizeof(Tk_Uid)))
+ (Tk_Offset(TagInfo, tagPtr) + ((tagSpace) * sizeof(Tk_Uid)))
static CONST char *TagInfoUid = "TagInfo";