summaryrefslogtreecommitdiff
path: root/libdtv/liblx/xMemMgt.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdtv/liblx/xMemMgt.c')
-rw-r--r--libdtv/liblx/xMemMgt.c621
1 files changed, 621 insertions, 0 deletions
diff --git a/libdtv/liblx/xMemMgt.c b/libdtv/liblx/xMemMgt.c
new file mode 100644
index 00000000..8f619bc8
--- /dev/null
+++ b/libdtv/liblx/xMemMgt.c
@@ -0,0 +1,621 @@
+//////////////////////////////////////////////////////////////
+/// ///
+/// xMemMgt.c: memory management functions of liblx ///
+/// ///
+//////////////////////////////////////////////////////////////
+
+// $Revision: 1.1 $
+// $Date: 2001/06/25 12:29:47 $
+// $Author: hakenes $
+//
+// (C) 1992-2001 Rolf Hakenes <hakenes@hippomi.de>, under the GNU GPL.
+//
+// liblx is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// liblx is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You may have received a copy of the GNU General Public License
+// along with liblx; see the file COPYING. If not, write to the
+// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#include <stdio.h>
+#include <malloc.h>
+
+#include "liblx.h"
+
+#ifdef DEBUG
+void logPrintf(int, char *, ...);
+#endif
+
+static struct MEM_CHUNK *xRememberKey = NULL;
+
+static struct MEM_CHUNK **xRememberPtr = &xRememberKey;
+
+unsigned long xAllocatedMemory = 0;
+
+/*************************************************************************
+ * *
+ * function : xMemAlloc *
+ * *
+ * parameter : Size - size of the requested memory area *
+ * *
+ * DataPointer - pointer to data pointer *
+ * *
+ * return : none *
+ * *
+ *-----------------------------------------------------------------------*
+ * *
+ * xMemAlloc() is a clustered, remembering memory management routine. *
+ * It uses its own tables for free and used memory blocks on private *
+ * memory area. With xMemFree(), you can free this memory likewise *
+ * the C free() routine, with xMemFreeAll() all memory at once. *
+ * By changing the current remember key with xSetRemember() you can *
+ * define a local memory area, which can be freed by only one call of *
+ * xMemFreeAll() (see xSetRemember() / xGetRemember()). *
+ * *
+ *************************************************************************/
+
+void xMemAllo (Size, DataPointer)
+
+unsigned long Size;
+unsigned char **DataPointer;
+{
+ struct MEM_CHUNK *MemChunk, *MemChunkPred;
+ struct MEM_ENTRY *MemEntry, *MemEntryPred;
+ long int NewSize;
+ unsigned short FoundFlag;
+#ifdef DEBUG
+ unsigned char *ptr;
+#endif
+
+ while (Size % 4) Size++;
+
+ if (Size > (MEM_CHUNK_SIZE - sizeof(struct MEM_CHUNK) -
+ sizeof(struct MEM_ENTRY)))
+ {
+ NewSize = Size + sizeof(struct MEM_CHUNK) + sizeof(struct MEM_ENTRY);
+
+ if (MemChunk = (*xRememberPtr))
+ {
+ do
+ {
+ MemChunkPred = MemChunk;
+ } while (MemChunk = MemChunk->Succ);
+ }
+ else MemChunkPred = (struct MEM_CHUNK *) &(*xRememberPtr);
+
+ MemChunk = MemChunkPred->Succ = (struct MEM_CHUNK *) malloc (NewSize);
+ xAllocatedMemory += NewSize;
+
+#ifdef DEBUG
+ for (ptr = (unsigned char *) MemChunk; ptr < (unsigned char *)
+ (MemChunk) + NewSize; ptr++)
+ *ptr = (((unsigned long)ptr)&1) ? 0x55 : 0xAA;
+#endif
+
+ if (!MemChunk)
+ {
+#ifdef DEBUG
+ logPrintf (0, "Not enough memory...\r\n");
+#endif
+ exit (1);
+ }
+
+ MemChunk->Size = NewSize;
+ MemChunk->Pred = MemChunkPred;
+ MemChunk->Succ = NULL;
+ MemChunk->FirstFreeMemEntry = NULL;
+ MemChunk->FirstUsedMemEntry =
+ MemEntry = (struct MEM_ENTRY *) ((unsigned char *)MemChunk +
+ sizeof(struct MEM_CHUNK));
+
+ MemEntry->Size = Size;
+ MemEntry->Pred = (struct MEM_ENTRY *) &MemChunk->FirstUsedMemEntry;
+ MemEntry->Succ = NULL;
+
+ *DataPointer = (unsigned char *) ((unsigned char *)MemEntry +
+ sizeof(struct MEM_ENTRY));
+#ifdef DEBUG_CALLS
+ logPrintf (0, "xMemAlloc: %x, %d bytes\r\n", *DataPointer, Size);
+#endif
+ return;
+ }
+
+ MemEntry = NULL;
+ FoundFlag = 0;
+
+ if (MemChunk = (*xRememberPtr))
+ {
+ do
+ {
+ if (MemEntry = MemChunk->FirstFreeMemEntry)
+ do
+ {
+ if (Size <= MemEntry->Size) FoundFlag = 1;
+ } while ((FoundFlag == 0) && (MemEntry = MemEntry->Succ));
+ MemChunkPred = MemChunk;
+ } while ((FoundFlag == 0) && (MemChunk = MemChunk->Succ));
+ }
+ else MemChunkPred = (struct MEM_CHUNK *) &(*xRememberPtr);
+
+ if (!MemEntry)
+ {
+ MemChunk = MemChunkPred->Succ =
+ (struct MEM_CHUNK *) malloc (MEM_CHUNK_SIZE);
+ xAllocatedMemory += MEM_CHUNK_SIZE;
+
+#ifdef DEBUG
+ for (ptr = (unsigned char *) MemChunk; ptr < (unsigned char *)
+ (MemChunk) + MEM_CHUNK_SIZE; ptr++)
+ *ptr = (((unsigned long)ptr)&1) ? 0x55 : 0xAA;
+#endif
+
+ if (!MemChunk)
+ {
+#ifdef DEBUG
+ logPrintf (0, "Not enough memory...\r\n");
+#endif
+ exit (1);
+ }
+
+ MemChunk->Size = MEM_CHUNK_SIZE;
+ MemChunk->Pred = MemChunkPred;
+ MemChunk->Succ = NULL;
+ MemChunk->FirstUsedMemEntry = NULL;
+ MemChunk->FirstFreeMemEntry =
+ MemEntry = (struct MEM_ENTRY *)
+ ((unsigned char *)MemChunk + sizeof(struct MEM_CHUNK));
+
+ MemEntry->Size = MEM_CHUNK_SIZE - sizeof(struct MEM_CHUNK) -
+ sizeof(struct MEM_ENTRY);
+ MemEntry->Pred = (struct MEM_ENTRY *) &MemChunk->FirstFreeMemEntry;
+ MemEntry->Succ = NULL;
+ }
+
+ NewSize = MemEntry->Size - sizeof(struct MEM_ENTRY) - Size;
+
+ MemEntry->Size = Size;
+ *DataPointer = (unsigned char *)
+ ((unsigned char *)MemEntry + sizeof(struct MEM_ENTRY));
+
+#ifdef DEBUG
+ for (ptr = *DataPointer; ptr < (unsigned char *)
+ (*DataPointer) + Size; ptr++)
+ {
+ if (((unsigned long )ptr)&1)
+ { if (*ptr != 0x55)
+ logPrintf (0, "freed memory was used\r\n"); }
+ else { if (*ptr != 0xAA)
+ logPrintf (0, "freed memory was used\r\n"); }
+ }
+#endif
+
+ if (MemEntry->Succ)
+ ((struct MEM_ENTRY *)MemEntry->Succ)->Pred = MemEntry->Pred;
+ ((struct MEM_ENTRY *)MemEntry->Pred)->Succ = MemEntry->Succ;
+
+ if (MemChunk->FirstUsedMemEntry)
+ MemChunk->FirstUsedMemEntry->Pred = MemEntry;
+ MemEntry->Succ = MemChunk->FirstUsedMemEntry;
+ MemChunk->FirstUsedMemEntry = MemEntry;
+ MemEntry->Pred = (struct MEM_ENTRY *) &MemChunk->FirstUsedMemEntry;
+
+ if (NewSize > 0)
+ {
+ MemEntry = (struct MEM_ENTRY *)
+ ((unsigned char *)MemEntry + sizeof(struct MEM_ENTRY) + Size);
+ MemEntry->Size = NewSize;
+
+ if (MemChunk->FirstFreeMemEntry)
+ MemChunk->FirstFreeMemEntry->Pred = MemEntry;
+ MemEntry->Succ = MemChunk->FirstFreeMemEntry;
+ MemChunk->FirstFreeMemEntry = MemEntry;
+ MemEntry->Pred = (struct MEM_ENTRY *) &MemChunk->FirstFreeMemEntry;
+ }
+#ifdef DEBUG_CALLS
+ logPrintf (0, "xMemAlloc: %x, %d bytes\r\n", *DataPointer, Size);
+#endif
+ return;
+}
+
+
+
+/*************************************************************************
+ * *
+ * function : xMemFree *
+ * *
+ * parameter : DataPointer - data pointer *
+ * *
+ * return : none *
+ * *
+ *-----------------------------------------------------------------------*
+ * *
+ * xMemFree() frees with xMemAlloc() allocated memory. *
+ * *
+ *************************************************************************/
+
+void xMemFre (DataPointer)
+
+unsigned char *DataPointer;
+{
+ struct MEM_CHUNK *MemChunk, *MemChunkPred;
+ struct MEM_ENTRY *MemEntry, *TempEntry, *PredEntry, *SuccEntry;
+ unsigned short FoundFlag;
+#ifdef DEBUG
+ unsigned char *ptr;
+#endif
+
+ if (!DataPointer)
+ {
+ return;
+ }
+ else
+ {
+ MemEntry = NULL;
+ FoundFlag = 0;
+
+ if (MemChunk = (*xRememberPtr))
+ do
+ {
+ if (MemEntry = MemChunk->FirstUsedMemEntry)
+ do
+ {
+ if (DataPointer == (unsigned char *) ((unsigned char *) MemEntry +
+ sizeof(struct MEM_ENTRY))) FoundFlag = 1;
+ } while ((FoundFlag == 0) && (MemEntry = MemEntry->Succ));
+ } while ((FoundFlag == 0) && (MemChunk = MemChunk->Succ));
+
+ if (FoundFlag == 1)
+ {
+#ifdef DEBUG_CALLS
+ logPrintf (0, "xMemFree: %x, %d bytes\r\n", DataPointer, MemEntry->Size);
+#endif
+ if (MemEntry->Succ)
+ ((struct MEM_ENTRY *)MemEntry->Succ)->Pred = MemEntry->Pred;
+ ((struct MEM_ENTRY *)MemEntry->Pred)->Succ = MemEntry->Succ;
+
+ if (!MemChunk->FirstUsedMemEntry)
+ {
+ if (MemChunk->Succ)
+ ((struct MEM_CHUNK *)MemChunk->Succ)->Pred = MemChunk->Pred;
+ ((struct MEM_CHUNK *)MemChunk->Pred)->Succ = MemChunk->Succ;
+ if (xAllocatedMemory > 0) xAllocatedMemory -= MemChunk->Size;
+ free (MemChunk);
+ return;
+ }
+
+ FoundFlag = 0;
+ PredEntry = NULL;
+ SuccEntry = NULL;
+ if (TempEntry = MemChunk->FirstFreeMemEntry)
+ do
+ {
+ if ((struct MEM_ENTRY *)((unsigned char *)TempEntry +
+ TempEntry->Size + sizeof(struct MEM_ENTRY)) == MemEntry)
+ {
+ FoundFlag ++;
+ PredEntry = TempEntry;
+ }
+ if ((struct MEM_ENTRY *)((unsigned char *)MemEntry +
+ MemEntry->Size + sizeof(struct MEM_ENTRY)) == TempEntry)
+ {
+ FoundFlag ++;
+ SuccEntry = TempEntry;
+ }
+ } while ((FoundFlag != 2) && (TempEntry = TempEntry->Succ));
+
+ if (PredEntry)
+ {
+ if (SuccEntry)
+ {
+ /* Vorgdnger + Nachfolger */
+
+ if (SuccEntry->Succ)
+ ((struct MEM_ENTRY *)SuccEntry->Succ)->Pred = SuccEntry->Pred;
+ ((struct MEM_ENTRY *)SuccEntry->Pred)->Succ = SuccEntry->Succ;
+
+ PredEntry->Size += MemEntry->Size + sizeof(struct MEM_ENTRY) +
+ SuccEntry->Size + sizeof(struct MEM_ENTRY);
+ }
+ else
+ {
+ /* nur Vorgaenger */
+
+ PredEntry->Size += MemEntry->Size + sizeof(struct MEM_ENTRY);
+ }
+#ifdef DEBUG
+ for (ptr = (unsigned char *) (PredEntry) + sizeof(struct MEM_ENTRY);
+ ptr < (unsigned char *) (PredEntry) + sizeof(struct MEM_ENTRY) +
+ PredEntry->Size; ptr++)
+ *ptr = (((unsigned long)ptr)&1) ? 0x55 : 0xAA;
+#endif
+ }
+ else
+ {
+ if (SuccEntry)
+ {
+ /* nur Nachfolger */
+
+ if (SuccEntry->Succ)
+ ((struct MEM_ENTRY *)SuccEntry->Succ)->Pred = SuccEntry->Pred;
+ ((struct MEM_ENTRY *)SuccEntry->Pred)->Succ = SuccEntry->Succ;
+
+ MemEntry->Size += SuccEntry->Size + sizeof(struct MEM_ENTRY);
+ }
+
+ if (MemChunk->FirstFreeMemEntry)
+ MemChunk->FirstFreeMemEntry->Pred = MemEntry;
+ MemEntry->Succ = MemChunk->FirstFreeMemEntry;
+ MemChunk->FirstFreeMemEntry = MemEntry;
+ MemEntry->Pred = (struct MEM_ENTRY *) &MemChunk->FirstFreeMemEntry;
+#ifdef DEBUG
+ for (ptr = (unsigned char *) (MemEntry) + sizeof(struct MEM_ENTRY);
+ ptr < (unsigned char *) (MemEntry) + sizeof(struct MEM_ENTRY) +
+ MemEntry->Size; ptr++)
+ *ptr = (((unsigned long)ptr)&1) ? 0x55 : 0xAA;
+#endif
+ }
+ }
+#ifdef DEBUG_CALLS
+ else
+ logPrintf (0, "xMemFree: tried to free unallocated data %x\r\n", DataPointer);
+#endif
+ }
+ return;
+}
+
+
+
+/*************************************************************************
+ * *
+ * function : xMemFreeAll *
+ * *
+ * parameter : RememberPtr *
+ * *
+ * return : none *
+ * *
+ *-----------------------------------------------------------------------*
+ * *
+ * xMemFreeAll() frees all with xMemAlloc() allocated memory. If Re- *
+ * memberPtr is not NULL, the MEM_CHUNK structure from the specified *
+ * Address is freed, otherwise the natural MEM_CHUNK will be done. *
+ * *
+ *************************************************************************/
+
+
+void xMemFreeAll (RememberPtr)
+
+struct MEM_CHUNK **RememberPtr;
+{
+ struct MEM_CHUNK *MemChunk, *MemChunkPred;
+
+ if (RememberPtr)
+ {
+ if (MemChunkPred = (*RememberPtr))
+ do
+ {
+ MemChunk = MemChunkPred->Succ;
+ if (xAllocatedMemory > 0) xAllocatedMemory -= MemChunkPred->Size;
+ free (MemChunkPred);
+ } while (MemChunkPred = MemChunk);
+ *RememberPtr = NULL;
+ }
+ else
+ {
+ if (MemChunkPred = (*xRememberPtr))
+ do
+ {
+ MemChunk = MemChunkPred->Succ;
+ if (xAllocatedMemory > 0) xAllocatedMemory -= MemChunkPred->Size;
+ free (MemChunkPred);
+ } while (MemChunkPred = MemChunk);
+ *xRememberPtr = NULL;
+ }
+}
+
+
+/*************************************************************************
+ * *
+ * function : xMemMerge *
+ * *
+ * parameter : RememberPtr *
+ * *
+ * return : none *
+ * *
+ *-----------------------------------------------------------------------*
+ * *
+ * xMemMerge() merges the memory area pointed to by RememberKey with *
+ * the currently used in xRememberPtr. *
+ * *
+ *************************************************************************/
+
+void xMemMerge (RememberPtr)
+
+struct MEM_CHUNK **RememberPtr;
+{
+ struct MEM_CHUNK *MemChunk, *MemChunkPred;
+
+ if (RememberPtr)
+ {
+ if (MemChunk = (*xRememberPtr))
+ {
+ while (MemChunk->Succ) MemChunk = MemChunk->Succ;
+ MemChunk->Succ = (*RememberPtr);
+ *RememberPtr = NULL;
+ }
+ else (*xRememberPtr = *RememberPtr);
+ }
+ return;
+}
+
+/*************************************************************************
+ * *
+ * function : xGetRemember *
+ * *
+ * parameter : none *
+ * *
+ * return : pointer to a MEM_CHUNK tree *
+ * *
+ *-----------------------------------------------------------------------*
+ * *
+ * xGetRemember() returns the currently used MEM_CHUNK tree. *
+ * *
+ *************************************************************************/
+
+
+struct MEM_CHUNK **xGetRemember ()
+{
+ return (xRememberPtr);
+}
+
+
+/*************************************************************************
+ * *
+ * function : xSetRemember *
+ * *
+ * parameter : pointer to a MEM_CHUNK tree *
+ * *
+ * return : none *
+ * *
+ *-----------------------------------------------------------------------*
+ * *
+ * xSetRemember() redefines the currently used MEM_CHUNK pointer. If *
+ * RememberPtr is NULL, the natural MEM_CHUNK is reloaded. *
+ * *
+ *************************************************************************/
+
+
+void xSetRemember (RememberPtr)
+
+struct MEM_CHUNK **RememberPtr;
+{
+ if (RememberPtr)
+ xRememberPtr = RememberPtr;
+ else
+ xRememberPtr = &xRememberKey;
+}
+
+/*************************************************************************
+ * *
+ * function : xPrintMemList *
+ * *
+ * parameter : pointer to a MEM_CHUNK tree *
+ * *
+ * return : none *
+ * *
+ *-----------------------------------------------------------------------*
+ * *
+ * xPrintMemList() prints the currently allocated memory blocks of *
+ * the specified RememberPtr. *
+ * *
+ *************************************************************************/
+
+
+void xPrintMemList (Remember)
+
+struct MEM_CHUNK **Remember;
+{
+ struct MEM_CHUNK *MemChunk;
+ struct MEM_ENTRY *MemEntry;
+
+ fprintf (stderr, "MemChunkPtr = %x\n", (int) Remember);
+
+ if (MemChunk = *Remember)
+ do
+ {
+ fprintf (stderr, "\tMemChunk at %x with Size %d\n", (int) MemChunk,
+ (int) MemChunk->Size);
+
+ if (MemEntry = MemChunk->FirstFreeMemEntry)
+ do
+ {
+ fprintf (stderr, "\t\tFree MemEntry at %x (%x) with Size %d\n",
+ (int) MemEntry, (int)((unsigned char *)MemEntry +
+ sizeof(struct MEM_ENTRY)), (int) MemEntry->Size);
+
+ } while (MemEntry = MemEntry->Succ);
+
+ if (MemEntry = MemChunk->FirstUsedMemEntry)
+ do
+ {
+ fprintf (stderr, "\t\tUsed MemEntry at %x (%x) with Size %d\n",
+ (int) MemEntry, (int)((unsigned char *)MemEntry +
+ sizeof(struct MEM_ENTRY)), (int) MemEntry->Size);
+
+ } while (MemEntry = MemEntry->Succ);
+
+ } while (MemChunk = MemChunk->Succ);
+ else fprintf (stderr, "\tNo current MemChunk\n");
+}
+
+
+/*************************************************************************
+ * *
+ * function : xGetMemSize *
+ * *
+ * parameter : pointer to a MEM_CHUNK tree *
+ * *
+ * return : none *
+ * *
+ *-----------------------------------------------------------------------*
+ * *
+ * xGetMemSize() gets the size of the currently allocated memory *
+ * blocks of the specified (or natural if NULL) RememberPtr *
+ * *
+ *************************************************************************/
+
+
+unsigned long xGetMemSize (RememberPtr)
+
+struct MEM_CHUNK **RememberPtr;
+{
+ struct MEM_CHUNK *MemChunk;
+ struct MEM_ENTRY *MemEntry;
+ unsigned long Result = 0;
+
+ if (RememberPtr) MemChunk = *RememberPtr;
+ else MemChunk = xRememberKey;
+
+ if (MemChunk)
+ do { Result += (unsigned long) MemChunk->Size; }
+ while (MemChunk = MemChunk->Succ);
+
+ return (Result);
+}
+
+
+/*************************************************************************
+ * *
+ * function : xSetText *
+ * *
+ * arguments : xText - pointer to a string *
+ * *
+ * return : pointer to an new allocated string *
+ * *
+ *-----------------------------------------------------------------------*
+ * *
+ * xSetText() allocates memory for the string pointed to by 'xText' *
+ * and duplicates it. *
+ * *
+ *************************************************************************/
+
+char *xSetText (xText)
+
+char *xText;
+{
+ char *NewText;
+
+ if (!xText) return (NULL);
+
+ xMemAlloc (strlen(xText) + 1, &NewText);
+ strcpy (NewText, xText);
+
+ return (NewText);
+}