/* -*-c-*-
*
- * $Id: utils.c,v 1.2 1997/08/04 10:24:26 mdw Exp $
+ * $Id: utils.c,v 1.4 1997/09/08 13:43:54 mdw Exp $
*
* Miscellaneous useful bits of code.
*
/*----- Revision history --------------------------------------------------*
*
* $Log: utils.c,v $
+ * Revision 1.4 1997/09/08 13:43:54 mdw
+ * Flush tracedump file after each `interesting' write.
+ *
+ * Revision 1.3 1997/08/20 16:25:37 mdw
+ * Add some simple `malloc' tracking.
+ *
* Revision 1.2 1997/08/04 10:24:26 mdw
* Sources placed under CVS control.
*
vfprintf(tracefp, f, ap);
va_end(ap);
putc('\n', tracefp);
+ fflush(tracefp);
}
/* --- @traceblk@ --- *
c = (sz >= 8) ? 8 : sz;
sz -= c, p += c, o += c;
}
+ fflush(tracefp);
}
-
/* --- @traceon@ --- *
*
* Arguments: @FILE *fp@ = a file to trace on
return (p);
}
+/*----- Simple memory use tracking ----------------------------------------*/
+
+#ifdef TRACK_MALLOC
+
+/*#define TRACK_VERBOSE*/
+
+/* --- A type to record a size and have a nice alignment --- */
+
+typedef union szblock {
+ struct {
+ union szblock *next;
+ union szblock *prev;
+ size_t sz;
+ } x;
+ long double _ld;
+ void *_p;
+} szblock;
+
+/* --- Static data --- */
+
+static unsigned int memused = 0;
+static szblock *memlist;
+
+/* --- @track_malloc@ --- *
+ *
+ * Arguments: @size_t sz@ = size requested
+ *
+ * Returns: Pointer to allocated space, or null
+ *
+ * Use: Allocates memory, and tracks how much is allocated.
+ */
+
+void *track_malloc(size_t sz)
+{
+ szblock *q = (malloc)(sz + sizeof(szblock));
+ if (q) {
+ memused += sz;
+#ifdef TRACK_VERBOSE
+ printf("[%p] allocated %lu\n", (void *)(q + 1), (unsigned long)sz);
+#endif
+ q->x.sz = sz;
+ q->x.next = memlist;
+ q->x.prev = 0;
+ if (q->x.next)
+ q->x.next->x.prev = q;
+ memlist = q;
+ return (q + 1);
+ }
+ return (0);
+}
+
+/* --- @track_free@ --- *
+ *
+ * Arguments: @void *p@ = pointer to an allocated block
+ *
+ * Returns: ---
+ *
+ * Use: Frees memory, and tracks how much is still allocated.
+ */
+
+void track_free(void *p)
+{
+ szblock *q;
+
+ if (!p)
+ return;
+ q = (szblock *)p - 1;
+#ifdef TRACK_VERBOSE
+ printf("[%p] freed %lu\n", (void *)(q + 1), (unsigned long)q->x.sz);
+#endif
+ if (q->x.next)
+ q->x.next->x.prev = q->x.prev;
+ if (q->x.prev)
+ q->x.prev->x.next = q->x.next;
+ else
+ memlist = q->x.next;
+ memused -= q->x.sz;
+ (free)(q);
+}
+
+/* --- @track_realloc@ --- *
+ *
+ * Arguments: @void *p@ = pointer to an allocated block
+ * @size_t sz@ = how big it wants to be
+ *
+ * Returns: Pointer to the new block.
+ *
+ * Use: Reallocates a block, tracking how much memory is still
+ * available.
+ */
+
+void *track_realloc(void *p, size_t sz)
+{
+ size_t osz;
+ szblock *q, *qq;
+ if (p) {
+ q = (szblock *)p - 1;
+ osz = q->x.sz;
+ if (q->x.next)
+ q->x.next->x.prev = q->x.prev;
+ if (q->x.prev)
+ q->x.prev->x.next = q->x.next;
+ else
+ memlist = q->x.next;
+ } else {
+ q = 0;
+ osz = 0;
+ }
+ qq = (realloc)(q, sz + sizeof(szblock));
+ if (qq) {
+#ifdef TRACK_VERBOSE
+ printf("[%p->%p] reallocated %lu -> %lu\n",
+ (void *)(q + 1), (void *)(qq + 1),
+ (unsigned long)osz, (unsigned long)sz);
+#endif
+ qq->x.sz = sz;
+ qq->x.next = memlist;
+ qq->x.prev = 0;
+ if (qq->x.next)
+ qq->x.next->x.prev = qq;
+ memlist = qq;
+ memused += sz - osz;
+ qq->x.sz = sz;
+ return (qq + 1);
+ }
+ return (0);
+}
+
+/* --- @track_memused@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: A count of how much memory is used currently.
+ *
+ * Use: Returns the amount of memory which the @track_@-functions
+ * above have counted as being currently allocated.
+ */
+
+unsigned long track_memused(void)
+{
+ return (memused);
+}
+
+/* --- @track_memlist@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Dumps a list of allocated blocks to standard output.
+ */
+
+void track_memlist(void)
+{
+ szblock *q = memlist;
+ printf("listing blocks:\n");
+ while (q) {
+ printf("... [%p] %lu\n", (void *)(q + 1), (unsigned long)q->x.sz);
+ q = q->x.next;
+ }
+ printf("done\n");
+}
+
+#endif
+
/*----- That's all, folks -------------------------------------------------*/