summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2017-03-14 15:45:35 +0100
committerAraq <rumpf_a@web.de>2017-03-14 15:45:35 +0100
commit98c7bab8eaa3daf872b12984a07b269f548210e4 (patch)
treedee28d6557ad3d2e8ac15d0e9e58419b5d978515 /lib
parentced38f3fdb4a4eedd8c999c479b80d593dfe2600 (diff)
downloadNim-98c7bab8eaa3daf872b12984a07b269f548210e4.tar.gz
make memory tracker work without onThreadCreation
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/nimtracker.nim10
-rw-r--r--lib/system/alloc.nim17
-rw-r--r--lib/system/memtracker.nim12
3 files changed, 26 insertions, 13 deletions
diff --git a/lib/pure/nimtracker.nim b/lib/pure/nimtracker.nim
index acc242257..a66dfc2ea 100644
--- a/lib/pure/nimtracker.nim
+++ b/lib/pure/nimtracker.nim
@@ -23,12 +23,6 @@ var
 
 const insertQuery = "INSERT INTO tracking(op, address, size, file, line) values (?, ?, ?, ?, ?)"
 
-when compileOption("threads"):
-  onThreadCreation do():
-    if prepare_v2(dbHandle, insertQuery,
-        insertQuery.len, insertStmt, nil) != SQLITE_OK:
-      quit "could not bind query to insertStmt " & $sqlite3.errmsg(dbHandle)
-
 template sbind(x: int; value) =
   when value is cstring:
     let ret = insertStmt.bindText(x, value, value.len.int32, SQLITE_TRANSIENT)
@@ -41,6 +35,10 @@ template sbind(x: int; value) =
 
 when defined(memTracker):
   proc logEntries(log: TrackLog) {.nimcall, locks: 0, tags: [], gcsafe.} =
+    if insertStmt.isNil:
+      if prepare_v2(dbHandle, insertQuery,
+          insertQuery.len, insertStmt, nil) != SQLITE_OK:
+        quit "could not bind query to insertStmt " & $sqlite3.errmsg(dbHandle)
     for i in 0..log.count-1:
       var success = false
       let e = log.data[i]
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index f28a124d2..768ca92f3 100644
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -320,9 +320,13 @@ proc requestOsChunks(a: var MemRegion, size: int): PBigChunk =
   incCurrMem(a, size)
   inc(a.freeMem, size)
   result.heapLink = a.heapLink
-  when defined(debugHeapLinks):
-    cprintf("owner: %p; result: %p; next pointer %p\n", addr(a), result, result.heapLink)
   result.origSize = size
+  when defined(debugHeapLinks):
+    cprintf("owner: %p; result: %p; next pointer %p; size: %ld\n", addr(a),
+      result, result.heapLink, result.origSize)
+
+  when defined(memtracker):
+    trackLocation(addr result.origSize, sizeof(int)*2)
   a.heapLink = result
 
   sysAssert((cast[ByteAddress](result) and PageMask) == 0, "requestOsChunks 1")
@@ -435,6 +439,7 @@ proc freeBigChunk(a: var MemRegion, c: PBigChunk) =
   listAdd(a.freeChunksList, c)
   # set 'used' to false:
   c.origSize = c.origSize and not 1
+  track("setUsedToFalse", addr c.origSize, sizeof(int))
   #else:
   #  freeOsChunks(a, c, c.size)
 
@@ -443,6 +448,7 @@ proc splitChunk(a: var MemRegion, c: PBigChunk, size: int) =
   sysAssert(rest notin a.freeChunksList, "splitChunk")
   rest.size = c.size - size
   rest.origSize = 0 # not used and size irrelevant
+  track("rest.origSize", addr rest.origSize, sizeof(int))
   rest.next = nil
   rest.prev = nil
   rest.prevSize = size
@@ -479,6 +485,8 @@ proc getBigChunk(a: var MemRegion, size: int): PBigChunk =
   result.prevSize = 0 # XXX why is this needed?
   # set 'used' to to true:
   result.origSize = result.origSize or 1
+  track("setUsedToFalse", addr result.origSize, sizeof(int))
+
   incl(a, a.chunkStarts, pageIndex(result))
   dec(a.freeMem, size)
 
@@ -723,9 +731,10 @@ proc deallocOsPages(a: var MemRegion) =
   # we free every 'ordinarily' allocated page by iterating over the page bits:
   var it = a.heapLink
   while it != nil:
-    when defined(debugHeapLinks):
-      cprintf("owner %p; dealloc A: %p\n", addr(a), it)
     let next = it.heapLink
+    when defined(debugHeapLinks):
+      cprintf("owner %p; dealloc A: %p size: %ld; next: %p\n", addr(a),
+        it, it.origSize and not 1, next)
     sysAssert it.origSize >= PageSize, "origSize too small"
     # note:
     osDeallocPages(it, it.origSize and not 1)
diff --git a/lib/system/memtracker.nim b/lib/system/memtracker.nim
index 219956012..ae0297438 100644
--- a/lib/system/memtracker.nim
+++ b/lib/system/memtracker.nim
@@ -18,6 +18,11 @@ when defined(noSignalHandler):
 # We don't want to memtrack the tracking code ...
 {.push memtracker: off.}
 
+when declared(getThreadId):
+  template myThreadId(): untyped = getThreadId()
+else:
+  template myThreadId(): untyped = 0
+
 type
   LogEntry* = object
     op*: cstring
@@ -25,6 +30,7 @@ type
     size*: int
     file*: cstring
     line*: int
+    thread*: int
   TrackLog* = object
     count*: int
     disabled: bool
@@ -59,7 +65,7 @@ proc addEntry(entry: LogEntry) =
       let c = cast[int](entry.address)
       let d = c + entry.size-1
       if x <= d and c <= y:
-        interesting = true
+        interesting = myThreadId() != entry.thread # true
         break
     if interesting:
       gLog.disabled = true
@@ -76,12 +82,12 @@ proc addEntry(entry: LogEntry) =
 
 proc memTrackerWrite(address: pointer; size: int; file: cstring; line: int) {.compilerProc.} =
   addEntry LogEntry(op: "write", address: address,
-      size: size, file: file, line: line)
+      size: size, file: file, line: line, thread: myThreadId())
 
 proc memTrackerOp*(op: cstring; address: pointer; size: int) {.tags: [],
          locks: 0, gcsafe.} =
   addEntry LogEntry(op: op, address: address, size: size,
-      file: "", line: 0)
+      file: "", line: 0, thread: myThreadId())
 
 proc memTrackerDisable*() =
   gLog.disabled = true