? debug-interval-timings-os-1.patch
Index: debugtools.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/debugtools.c,v
retrieving revision 1.44
diff -u -r1.44 debugtools.c
--- debugtools.c	28 Sep 2005 18:34:00 -0000	1.44
+++ debugtools.c	19 Nov 2005 11:45:15 -0000
@@ -29,6 +29,7 @@
 # include <unistd.h>
 #endif
 #include <ctype.h>
+#include <sys/time.h>
 
 #include "wine/debug.h"
 #include "wine/exception.h"
@@ -41,7 +42,7 @@
 #include "ntdll_misc.h"
 
 WINE_DECLARE_DEBUG_CHANNEL(tid);
-
+WINE_DECLARE_DEBUG_CHANNEL(interval);
 static struct __wine_debug_functions default_funcs;
 
 /* ---------------------------------------------------------------------- */
@@ -161,6 +162,11 @@
     return ret;
 }
 
+DWORD NTDLL_GetTickCount(void) {
+    struct timeval t;
+    gettimeofday( &t, NULL );
+    return ((t.tv_sec - server_start_time) * 1000) + (t.tv_usec / 1000);
+}
 /***********************************************************************
  *		NTDLL_dbg_vlog
  */
@@ -170,12 +176,18 @@
     static const char * const classes[] = { "fixme", "err", "warn", "trace" };
     struct debug_info *info = get_info();
     int ret = 0;
+    static DWORD starttime = 0;
 
     /* only print header if we are at the beginning of the line */
     if (info->out_pos == info->output || info->out_pos[-1] == '\n')
     {
         if (TRACE_ON(tid))
             ret = wine_dbg_printf( "%04lx:", GetCurrentThreadId() );
+        if (TRACE_ON(interval)) {
+            DWORD ticks = NTDLL_GetTickCount();    
+            ret += wine_dbg_printf( "%ld:", ticks - starttime);
+            starttime = ticks;
+        }
         if (cls < sizeof(classes)/sizeof(classes[0]))
             ret += wine_dbg_printf( "%s:%s:%s ", classes[cls], channel->name, function );
     }
Index: heap.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/heap.c,v
retrieving revision 1.52
diff -u -r1.52 heap.c
--- heap.c	26 Sep 2005 10:58:42 -0000	1.52
+++ heap.c	19 Nov 2005 11:45:16 -0000
@@ -356,6 +356,7 @@
 }
 
 
+static SUBHEAP *subheaplast = NULL;
 /***********************************************************************
  *           HEAP_FindSubHeap
  * Find the sub-heap containing a given address.
@@ -368,11 +369,37 @@
                 const HEAP *heap, /* [in] Heap pointer */
                 LPCVOID ptr /* [in] Address */
 ) {
+#if 0 /* profiling code */
+	static DWORD hits = 0;
+	static DWORD misses = 0;
+	DWORD subheaps = 0;
+#endif
     const SUBHEAP *sub = &heap->subheap;
+    if (subheaplast) {
+        if (((const char *)ptr >= (const char *)subheaplast) &&
+            ((const char *)ptr < (const char *)subheaplast + subheaplast->size)) {
+#if 0 /* profiling code */
+		if (last != sub) hits++; /* Don't bother counting if sub == last because we're not saving anything */
+		if (hits % 1000 == 0) {
+			FIXME(" %ld hits %ld misses\n", hits, misses);
+		}
+#endif
+		return subheaplast;
+	}
+    }
+    /* TODO: Look at precalculating sub + sub->size, and using block allocation for the linked list, maybe even sort and cluster `the subheaps somewhere */
     while (sub)
     {
+#if 0 /* profiling code */
+	    subheaps++;
+#endif
         if (((const char *)ptr >= (const char *)sub) &&
-            ((const char *)ptr < (const char *)sub + sub->size)) return (SUBHEAP*)sub;
+            ((const char *)ptr < (const char *)sub + sub->size)) {
+#if 0 /* profiling code */
+		misses += subheaps;
+#endif
+		return subheaplast=(SUBHEAP*)sub;
+	}
         sub = sub->next;
     }
     return NULL;
@@ -529,6 +556,7 @@
         if (pPrev) pPrev->next = subheap->next;
         /* Free the memory */
         subheap->magic = 0;
+	if (subheap == subheaplast) subheaplast = NULL;
         NtFreeVirtualMemory( NtCurrentProcess(), (void **)&subheap, &size, MEM_RELEASE );
         return;
     }
@@ -1114,6 +1142,7 @@
     while (subheap)
     {
         SUBHEAP *next = subheap->next;
+	if (subheaplast == subheap) subheaplast = NULL;
         SIZE_T size = 0;
         void *addr = subheap;
         NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
@@ -1222,6 +1251,15 @@
 
     if (!ptr) return TRUE;  /* freeing a NULL ptr isn't an error in Win2k */
 
+       if (ptr == (void *)0x7caa12e8) {
+                   FIXME("Expect a crash\n");
+                           DbgBreakPoint();
+#if 0
+                                   int 3;
+#endif
+                                       }
+       
+    
     heapPtr = HEAP_GetPtr( heap );
     if (!heapPtr)
     {
