summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2019-09-20 17:46:03 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-09-21 06:43:37 +0200
commit05e80e1cda2b5c955027eff5b41f22f6c17ada08 (patch)
tree837e01d592f20cee0096e6d6a05a5b8c81b124a8 /lib/pure
parent78396583234d0902d9cad095f81c44c8e32e2db7 (diff)
downloadNim-05e80e1cda2b5c955027eff5b41f22f6c17ada08.tar.gz
lib\pure\htmlgen.nim
avoid callsite for htmlgen
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/collections/LockFreeHash.nim609
-rw-r--r--lib/pure/collections/sharedstrings.nim152
-rw-r--r--lib/pure/events.nim102
3 files changed, 0 insertions, 863 deletions
diff --git a/lib/pure/collections/LockFreeHash.nim b/lib/pure/collections/LockFreeHash.nim
deleted file mode 100644
index a9e68477a..000000000
--- a/lib/pure/collections/LockFreeHash.nim
+++ /dev/null
@@ -1,609 +0,0 @@
-#nim c -t:-march=i686 --cpu:amd64 --threads:on -d:release lockfreehash.nim
-
-import math, hashes
-
-#------------------------------------------------------------------------------
-## Memory Utility Functions
-
-proc newHeap*[T](): ptr T =
-  result = cast[ptr T](alloc0(sizeof(T)))
-
-proc copyNew*[T](x: var T): ptr T =
-  var
-    size = sizeof(T)
-    mem = alloc(size)
-  copyMem(mem, x.addr, size)
-  return cast[ptr T](mem)
-
-proc copyTo*[T](val: var T, dest: int) =
-  copyMem(pointer(dest), val.addr, sizeof(T))
-
-proc allocType*[T](): pointer = alloc(sizeof(T))
-
-proc newShared*[T](): ptr T =
-  result = cast[ptr T](allocShared0(sizeof(T)))
-
-proc copyShared*[T](x: var T): ptr T =
-  var
-    size = sizeof(T)
-    mem = allocShared(size)
-  copyMem(mem, x.addr, size)
-  return cast[ptr T](mem)
-
-#------------------------------------------------------------------------------
-## Pointer arithmetic
-
-proc `+`*(p: pointer, i: int): pointer {.inline.} =
-  cast[pointer](cast[int](p) + i)
-
-const
-  minTableSize = 8
-  reProbeLimit = 12
-  minCopyWork = 4096
-  intSize = sizeof(int)
-
-
-
-when sizeof(int) == 4: # 32bit
-  type
-    Raw = range[0..1073741823]
-    ## The range of uint values that can be stored directly in a value slot
-    ## when on a 32 bit platform
-elif sizeof(int) == 8: # 64bit
-  type
-    Raw = range[0'i64..4611686018427387903'i64]
-    ## The range of uint values that can be stored directly in a value slot
-    ## when on a 64 bit platform
-else:
-  {.error: "unsupported platform".}
-
-type
-  Entry = tuple
-    key: int
-    value: int
-
-  EntryArr = ptr array[0..10_000_000, Entry]
-
-  PConcTable[K, V] = ptr object {.pure.}
-    len: int
-    used: int
-    active: int
-    copyIdx: int
-    copyDone: int
-    next: PConcTable[K, V]
-    data: EntryArr
-
-proc setVal[K, V](table: var PConcTable[K, V], key: int, val: int,
-  expVal: int, match: bool): int
-
-#------------------------------------------------------------------------------
-
-# Create a new table
-proc newLFTable*[K, V](size: int = minTableSize): PConcTable[K, V] =
-  let
-    dataLen = max(nextPowerOfTwo(size), minTableSize)
-    dataSize = dataLen*sizeof(Entry)
-    dataMem = allocShared0(dataSize)
-    tableSize = 7 * intSize
-    tableMem = allocShared0(tableSize)
-    table = cast[PConcTable[K, V]](tableMem)
-  table.len = dataLen
-  table.used = 0
-  table.active = 0
-  table.copyIdx = 0
-  table.copyDone = 0
-  table.next = nil
-  table.data = cast[EntryArr](dataMem)
-  result = table
-
-#------------------------------------------------------------------------------
-
-# Delete a table
-proc deleteConcTable[K, V](tbl: PConcTable[K, V]) =
-  deallocShared(tbl.data)
-  deallocShared(tbl)
-
-#------------------------------------------------------------------------------
-
-proc `[]`[K, V](table: var PConcTable[K, V], i: int): var Entry {.inline.} =
-  table.data[i]
-
-#------------------------------------------------------------------------------
-# State flags stored in ptr
-
-
-proc pack[T](x: T): int {.inline.} =
-  result = (cast[int](x) shl 2)
-  #echo("packKey ",cast[int](x) , " -> ", result)
-
-# Pop the flags off returning a 4 byte aligned ptr to our Key or Val
-proc pop(x: int): int {.inline.} =
-  result = x and 0xFFFFFFFC'i32
-
-# Pop the raw value off of our Key or Val
-proc popRaw(x: int): int {.inline.} =
-  result = x shr 2
-
-# Pop the flags off returning a 4 byte aligned ptr to our Key or Val
-proc popPtr[V](x: int): ptr V {.inline.} =
-  result = cast[ptr V](pop(x))
-  #echo("popPtr " & $x & " -> " & $cast[int](result))
-
-# Ghost (sentinel)
-# K or V is no longer valid use new table
-const Ghost = 0xFFFFFFFC
-proc isGhost(x: int): bool {.inline.} =
-  result = x == 0xFFFFFFFC
-
-# Tombstone
-# applied to V = K is dead
-proc isTomb(x: int): bool {.inline.} =
-  result = (x and 0x00000002) != 0
-
-proc setTomb(x: int): int {.inline.} =
-  result = x or 0x00000002
-
-# Prime
-# K or V is in new table copied from old
-proc isPrime(x: int): bool {.inline.} =
-  result = (x and 0x00000001) != 0
-
-proc setPrime(x: int): int {.inline.} =
-  result = x or 0x00000001
-
-#------------------------------------------------------------------------------
-
-##This is for i32 only need to override for i64
-proc hashInt(x: int): int {.inline.} =
-  var h = uint32(x) #shr 2'u32
-  h = h xor (h shr 16'u32)
-  h *= 0x85ebca6b'u32
-  h = h xor (h shr 13'u32)
-  h *= 0xc2b2ae35'u32
-  h = h xor (h shr 16'u32)
-  result = int(h)
-
-#------------------------------------------------------------------------------
-
-proc resize[K, V](self: PConcTable[K, V]): PConcTable[K, V] =
-  var next = atomic_load_n(self.next.addr, ATOMIC_RELAXED)
-  #echo("next = " & $cast[int](next))
-  if next != nil:
-    #echo("A new table already exists, copy in progress")
-    return next
-  var
-    oldLen = atomic_load_n(self.len.addr, ATOMIC_RELAXED)
-    newTable = newLFTable[K, V](oldLen*2)
-    success = atomic_compare_exchange_n(self.next.addr, next.addr, newTable,
-                  false, ATOMIC_RELAXED, ATOMIC_RELAXED)
-  if not success:
-    echo("someone beat us to it! delete table we just created and return his " &
-        $cast[int](next))
-    deleteConcTable(newTable)
-    return next
-  else:
-    echo("Created New Table! " & $cast[int](newTable) & " Size = " & $newTable.len)
-    return newTable
-
-
-#------------------------------------------------------------------------------
-#proc keyEQ[K](key1: ptr K, key2: ptr K): bool {.inline.} =
-proc keyEQ[K](key1: int, key2: int): bool {.inline.} =
-  result = false
-  when K is Raw:
-    if key1 == key2:
-      result = true
-  else:
-    var
-      p1 = popPtr[K](key1)
-      p2 = popPtr[K](key2)
-    if p1 != nil and p2 != nil:
-      if cast[int](p1) == cast[int](p2):
-        return true
-      if p1[] == p2[]:
-        return true
-
-#------------------------------------------------------------------------------
-
-#proc tableFull(self: var PConcTable[K,V]) : bool {.inline.} =
-
-
-#------------------------------------------------------------------------------
-
-proc copySlot[K, V](idx: int, oldTbl: var PConcTable[K, V],
-    newTbl: var PConcTable[K, V]): bool =
-  #echo("Copy idx " & $idx)
-  var
-    oldVal = 0
-    oldkey = 0
-    ok = false
-  result = false
-  #Block the key so no other threads waste time here
-  while not ok:
-    ok = atomic_compare_exchange_n(oldTbl[idx].key.addr, oldKey.addr,
-      setTomb(oldKey), false, ATOMIC_RELAXED, ATOMIC_RELAXED)
-  #echo("oldKey was = " & $oldKey & "  set it to tomb " & $setTomb(oldKey))
-  #Prevent new values from appearing in the old table by priming
-  oldVal = atomic_load_n(oldTbl[idx].value.addr, ATOMIC_RELAXED)
-  while not isPrime(oldVal):
-    var box = if oldVal == 0 or isTomb(oldVal): oldVal.setTomb.setPrime
-      else: oldVal.setPrime
-    if atomic_compare_exchange_n(oldTbl[idx].value.addr, oldVal.addr,
-      box, false, ATOMIC_RELAXED, ATOMIC_RELAXED):
-      if isPrime(box) and isTomb(box):
-        return true
-      oldVal = box
-      break
-  #echo("oldVal was = ", oldVal, "  set it to prime ", box)
-  if isPrime(oldVal) and isTomb(oldVal):
-    #when not (K is Raw):
-    #  deallocShared(popPtr[K](oldKey))
-    return false
-  if isTomb(oldVal):
-    echo("oldVal is Tomb!!!, should not happen")
-  if pop(oldVal) != 0:
-    result = setVal(newTbl, pop(oldKey), pop(oldVal), 0, true) == 0
-  #if result:
-    #echo("Copied a Slot! idx= " & $idx & " key= " & $oldKey & " val= " & $oldVal)
-  #else:
-    #echo("copy slot failed")
-  # Our copy is done so we disable the old slot
-  while not ok:
-    ok = atomic_compare_exchange_n(oldTbl[idx].value.addr, oldVal.addr,
-      oldVal.setTomb.setPrime, false, ATOMIC_RELAXED, ATOMIC_RELAXED)
-  #echo("disabled old slot")
-  #echo"---------------------"
-
-#------------------------------------------------------------------------------
-
-proc promote[K, V](table: var PConcTable[K, V]) =
-  var
-    newData = atomic_load_n(table.next.data.addr, ATOMIC_RELAXED)
-    newLen = atomic_load_n(table.next.len.addr, ATOMIC_RELAXED)
-    newUsed = atomic_load_n(table.next.used.addr, ATOMIC_RELAXED)
-
-  deallocShared(table.data)
-  atomic_store_n(table.data.addr, newData, ATOMIC_RELAXED)
-  atomic_store_n(table.len.addr, newLen, ATOMIC_RELAXED)
-  atomic_store_n(table.used.addr, newUsed, ATOMIC_RELAXED)
-  atomic_store_n(table.copyIdx.addr, 0, ATOMIC_RELAXED)
-  atomic_store_n(table.copyDone.addr, 0, ATOMIC_RELAXED)
-  deallocShared(table.next)
-  atomic_store_n(table.next.addr, nil, ATOMIC_RELAXED)
-  echo("new table swapped!")
-
-#------------------------------------------------------------------------------
-
-proc checkAndPromote[K, V](table: var PConcTable[K, V], workDone: int): bool =
-  var
-    oldLen = atomic_load_n(table.len.addr, ATOMIC_RELAXED)
-    copyDone = atomic_load_n(table.copyDone.addr, ATOMIC_RELAXED)
-    ok: bool
-  result = false
-  if workDone > 0:
-    #echo("len to copy =" & $oldLen)
-    #echo("copyDone + workDone = " & $copyDone & " + " & $workDone)
-    while not ok:
-      ok = atomic_compare_exchange_n(table.copyDone.addr, copyDone.addr,
-        copyDone + workDone, false, ATOMIC_RELAXED, ATOMIC_RELAXED)
-    #if ok: echo("set copyDone")
-    # If the copy is done we can promote this table
-    if copyDone + workDone >= oldLen:
-      # Swap new data
-      #echo("work is done!")
-      table.promote
-      result = true
-
-#------------------------------------------------------------------------------
-
-proc copySlotAndCheck[K, V](table: var PConcTable[K, V], idx: int):
-  PConcTable[K, V] =
-  var
-    newTable = cast[PConcTable[K, V]](atomic_load_n(table.next.addr,
-        ATOMIC_RELAXED))
-  result = newTable
-  if newTable != nil and copySlot(idx, table, newTable):
-    #echo("copied a single slot, idx = " & $idx)
-    if checkAndPromote(table, 1): return table
-
-
-#------------------------------------------------------------------------------
-
-proc helpCopy[K, V](table: var PConcTable[K, V]): PConcTable[K, V] =
-  var
-    newTable = cast[PConcTable[K, V]](atomic_load_n(table.next.addr,
-        ATOMIC_RELAXED))
-  result = newTable
-  if newTable != nil:
-    var
-      oldLen = atomic_load_n(table.len.addr, ATOMIC_RELAXED)
-      copyDone = atomic_load_n(table.copyDone.addr, ATOMIC_RELAXED)
-      copyIdx = 0
-      work = min(oldLen, minCopyWork)
-      #panicStart = -1
-      workDone = 0
-    if copyDone < oldLen:
-      var ok: bool
-      while not ok:
-        ok = atomic_compare_exchange_n(table.copyIdx.addr, copyIdx.addr,
-          copyIdx + work, false, ATOMIC_RELAXED, ATOMIC_RELAXED)
-      #echo("copy idx = ", copyIdx)
-      for i in 0..work-1:
-        var idx = (copyIdx + i) and (oldLen - 1)
-        if copySlot(idx, table, newTable):
-          workDone += 1
-      if workDone > 0:
-        #echo("did work ", workDone, " on thread ", cast[int](myThreadID[pointer]()))
-        if checkAndPromote(table, workDone): return table
-    # In case a thread finished all the work then got stalled before promotion
-    if checkAndPromote(table, 0): return table
-
-
-
-#------------------------------------------------------------------------------
-
-proc setVal[K, V](table: var PConcTable[K, V], key: int, val: int,
-  expVal: int, match: bool): int =
-  #echo("-try set- in table ", " key = ", (popPtr[K](key)[]), " val = ", val)
-  when K is Raw:
-    var idx = hashInt(key)
-  else:
-    var idx = popPtr[K](key)[].hash
-  var
-    nextTable: PConcTable[K, V]
-    probes = 1
-  # spin until we find a key slot or build and jump to next table
-  while true:
-    idx = idx and (table.len - 1)
-    #echo("try set idx = " & $idx & "for" & $key)
-    var
-      probedKey = 0
-      openKey = atomic_compare_exchange_n(table[idx].key.addr, probedKey.addr,
-        key, false, ATOMIC_RELAXED, ATOMIC_RELAXED)
-    if openKey:
-      if val.isTomb:
-        #echo("val was tomb, bail, no reason to set an open slot to tomb")
-        return val
-      #increment used slots
-      #echo("found an open slot, total used = " &
-      #$atomic_add_fetch(table.used.addr, 1, ATOMIC_RELAXED))
-      discard atomic_add_fetch(table.used.addr, 1, ATOMIC_RELAXED)
-      break # We found an open slot
-    #echo("set idx ", idx, " key = ", key, " probed = ", probedKey)
-    if keyEQ[K](probedKey, key):
-      #echo("we found the matching slot")
-      break # We found a matching slot
-    if (not(expVal != 0 and match)) and (probes >= reProbeLimit or key.isTomb):
-      if key.isTomb: echo("Key is Tombstone")
-      #if probes >= reProbeLimit: echo("Too much probing " & $probes)
-      #echo("try to resize")
-      #create next bigger table
-      nextTable = resize(table)
-      #help do some copying
-      #echo("help copy old table to new")
-      nextTable = helpCopy(table)
-      #now setVal in the new table instead
-      #echo("jumping to next table to set val")
-      return setVal(nextTable, key, val, expVal, match)
-    else:
-      idx += 1
-      probes += 1
-  # Done spinning for a new slot
-  var oldVal = atomic_load_n(table[idx].value.addr, ATOMIC_RELAXED)
-  if val == oldVal:
-    #echo("this val is alredy in the slot")
-    return oldVal
-  nextTable = atomic_load_n(table.next.addr, ATOMIC_SEQ_CST)
-  if nextTable == nil and
-    ((oldVal == 0 and
-    (probes >= reProbeLimit or table.used / table.len > 0.8)) or
-    (isPrime(oldVal))):
-    if table.used / table.len > 0.8: echo("resize because usage ratio = " &
-      $(table.used / table.len))
-    if isPrime(oldVal): echo("old val isPrime, should be a rare mem ordering event")
-    nextTable = resize(table)
-  if nextTable != nil:
-    #echo("tomb old slot then set in new table")
-    nextTable = copySlotAndCheck(table, idx)
-    return setVal(nextTable, key, val, expVal, match)
-  # Finally ready to add new val to table
-  while true:
-    if match and oldVal != expVal:
-      #echo("set failed, no match  oldVal= " & $oldVal & " expVal= " & $expVal)
-      return oldVal
-    if atomic_compare_exchange_n(table[idx].value.addr, oldVal.addr,
-        val, false, ATOMIC_RELEASE, ATOMIC_RELAXED):
-      #echo("val set at table " & $cast[int](table))
-      if expVal != 0:
-        if (oldVal == 0 or isTomb(oldVal)) and not isTomb(val):
-          discard atomic_add_fetch(table.active.addr, 1, ATOMIC_RELAXED)
-        elif not (oldVal == 0 or isTomb(oldVal)) and isTomb(val):
-          discard atomic_add_fetch(table.active.addr, -1, ATOMIC_RELAXED)
-      if oldVal == 0 and expVal != 0:
-        return setTomb(oldVal)
-      else: return oldVal
-    if isPrime(oldVal):
-      nextTable = copySlotAndCheck(table, idx)
-      return setVal(nextTable, key, val, expVal, match)
-
-#------------------------------------------------------------------------------
-
-proc getVal[K, V](table: var PConcTable[K, V], key: int): int =
-  #echo("-try get-  key = " & $key)
-  when K is Raw:
-    var idx = hashInt(key)
-  else:
-    var idx = popPtr[K](key)[].hash
-    #echo("get idx ", idx)
-  var
-    probes = 0
-    val: int
-  while true:
-    idx = idx and (table.len - 1)
-    var
-      newTable: PConcTable[K, V] # = atomic_load_n(table.next.addr, ATOMIC_ACQUIRE)
-      probedKey = atomic_load_n(table[idx].key.addr, ATOMIC_SEQ_CST)
-    if keyEQ[K](probedKey, key):
-      #echo("found key after ", probes+1)
-      val = atomic_load_n(table[idx].value.addr, ATOMIC_ACQUIRE)
-      if not isPrime(val):
-        if isTomb(val):
-          #echo("val was tomb but not prime")
-          return 0
-        else:
-          #echo("-GotIt- idx = ", idx, " key = ", key, " val ", val )
-          return val
-      else:
-        newTable = copySlotAndCheck(table, idx)
-        return getVal(newTable, key)
-    else:
-      #echo("probe ", probes, " idx = ", idx, " key = ", key, " found ", probedKey )
-      if probes >= reProbeLimit*4 or key.isTomb:
-        if newTable == nil:
-          #echo("too many probes and no new table ", key, "  ", idx )
-          return 0
-        else:
-          newTable = helpCopy(table)
-          return getVal(newTable, key)
-      idx += 1
-      probes += 1
-
-#------------------------------------------------------------------------------
-
-#proc set*(table: var PConcTable[Raw,Raw], key: Raw, val: Raw) =
-#  discard setVal(table, pack(key), pack(key), 0, false)
-
-#proc set*[V](table: var PConcTable[Raw,V], key: Raw, val: ptr V) =
-#  discard setVal(table, pack(key), cast[int](val), 0, false)
-
-proc set*[K, V](table: var PConcTable[K, V], key: var K, val: var V) =
-  when not (K is Raw):
-    var newKey = cast[int](copyShared(key))
-  else:
-    var newKey = pack(key)
-  when not (V is Raw):
-    var newVal = cast[int](copyShared(val))
-  else:
-    var newVal = pack(val)
-  var oldPtr = pop(setVal(table, newKey, newVal, 0, false))
-    #echo("oldPtr = ", cast[int](oldPtr), " newPtr = ", cast[int](newPtr))
-  when not (V is Raw):
-    if newVal != oldPtr and oldPtr != 0:
-      deallocShared(cast[ptr V](oldPtr))
-
-
-
-proc get*[K, V](table: var PConcTable[K, V], key: var K): V =
-  when not (V is Raw):
-    when not (K is Raw):
-      return popPtr[V](getVal(table, cast[int](key.addr)))[]
-    else:
-      return popPtr[V](getVal(table, pack(key)))[]
-  else:
-    when not (K is Raw):
-      return popRaw(getVal(table, cast[int](key.addr)))
-    else:
-      return popRaw(getVal(table, pack(key)))
-
-
-
-
-
-
-
-
-
-
-
-#proc `[]`[K,V](table: var PConcTable[K,V], key: K): PEntry[K,V] {.inline.} =
-#  getVal(table, key)
-
-#proc `[]=`[K,V](table: var PConcTable[K,V], key: K, val: V): PEntry[K,V] {.inline.} =
-#  setVal(table, key, val)
-
-
-
-
-
-
-#Tests ----------------------------
-when not defined(testing) and isMainModule:
-  import locks, times, mersenne
-
-  const
-    numTests = 100000
-    numThreads = 10
-
-
-
-  type
-    TestObj = tuple
-      thr: int
-      f0: int
-      f1: int
-
-    Data = tuple[k: string, v: TestObj]
-    PDataArr = array[0..numTests-1, Data]
-    Dict = PConcTable[string, TestObj]
-
-  var
-    thr: array[0..numThreads-1, Thread[Dict]]
-
-    table = newLFTable[string, TestObj](8)
-    rand = newMersenneTwister(2525)
-
-  proc createSampleData(len: int): PDataArr =
-    #result = cast[PDataArr](allocShared0(sizeof(Data)*numTests))
-    for i in 0..len-1:
-      result[i].k = "mark" & $(i+1)
-      #echo("mark" & $(i+1), " ", hash("mark" & $(i+1)))
-      result[i].v.thr = 0
-      result[i].v.f0 = i+1
-      result[i].v.f1 = 0
-      #echo("key = " & $(i+1) & " Val ptr = " & $cast[int](result[i].v.addr))
-
-
-
-  proc threadProc(tp: Dict) {.thread.} =
-    var t = cpuTime();
-    for i in 1..numTests:
-      var key = "mark" & $(i)
-      var got = table.get(key)
-      got.thr = cast[int](myThreadID[pointer]())
-      got.f1 = got.f1 + 1
-      table.set(key, got)
-    t = cpuTime() - t
-    echo t
-
-
-  var testData = createSampleData(numTests)
-
-  for i in 0..numTests-1:
-    table.set(testData[i].k, testData[i].v)
-
-  var i = 0
-  while i < numThreads:
-    createThread(thr[i], threadProc, table)
-    i += 1
-
-  joinThreads(thr)
-
-
-
-
-
-  var fails = 0
-
-  for i in 0..numTests-1:
-    var got = table.get(testData[i].k)
-    if got.f0 != i+1 or got.f1 != numThreads:
-      fails += 1
-      echo(got)
-
-  echo("Failed read or write = ", fails)
-
-
-  #for i in 1..numTests:
-  #  echo(i, " = ", hashInt(i) and 8191)
-
-  deleteConcTable(table)
diff --git a/lib/pure/collections/sharedstrings.nim b/lib/pure/collections/sharedstrings.nim
deleted file mode 100644
index 17e2e5888..000000000
--- a/lib/pure/collections/sharedstrings.nim
+++ /dev/null
@@ -1,152 +0,0 @@
-#
-#
-#            Nim's Runtime Library
-#        (c) Copyright 2015 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-## Shared string support for Nim.
-
-type
-  UncheckedCharArray = UncheckedArray[char]
-
-type
-  Buffer = ptr object
-    refcount: int
-    capacity, realLen: int
-    data: UncheckedCharArray
-
-  SharedString* = object ## A string that can be shared. Slicing is O(1).
-    buffer: Buffer
-    first, len: int
-
-proc decRef(b: Buffer) {.inline.} =
-  if atomicDec(b.refcount) <= 0:
-    deallocShared(b)
-
-proc incRef(b: Buffer) {.inline.} =
-  atomicInc(b.refcount)
-
-{.experimental.}
-
-proc `=destroy`*(s: SharedString) =
-  #echo "destroyed"
-  if not s.buffer.isNil:
-    decRef(s.buffer)
-
-when false:
-  proc `=`*(dest: var SharedString; src: SharedString) =
-    incRef(src.buffer)
-    if not dest.buffer.isNil:
-      decRef(dest.buffer)
-    dest.buffer = src.buffer
-    dest.first = src.first
-    dest.len = src.len
-
-proc len*(s: SharedString): int = s.len
-
-proc `[]`*(s: SharedString; i: Natural): char =
-  if i < s.len: result = s.buffer.data[i+s.first]
-  else: raise newException(IndexError, formatErrorIndexBound(i, s.len-1))
-
-proc `[]=`*(s: var SharedString; i: Natural; value: char) =
-  if i < s.len: s.buffer.data[i+s.first] = value
-  else: raise newException(IndexError, formatErrorIndexBound(i, s.len-1))
-
-proc `[]`*(s: SharedString; ab: HSlice[int, int]): SharedString =
-  #incRef(src.buffer)
-  if ab.a < s.len:
-    result.buffer = s.buffer
-    result.first = ab.a
-    result.len = min(s.len, ab.b - ab.a + 1)
-  # else: produce empty string ;-)
-
-proc newBuffer(cap, len: int): Buffer =
-  assert cap >= len
-  result = cast[Buffer](allocShared0(sizeof(int)*3 + cap))
-  result.refcount = 0
-  result.capacity = cap
-  result.realLen = len
-
-proc newSharedString*(len: Natural): SharedString =
-  if len != 0:
-    # optimization: Don't have an underlying buffer when 'len == 0'
-    result.buffer = newBuffer(len, len)
-  result.first = 0
-  result.len = len
-
-proc newSharedString*(s: string): SharedString =
-  let len = s.len
-  if len != 0:
-    # optimization: Don't have an underlying buffer when 'len == 0'
-    result.buffer = newBuffer(len, len)
-    copyMem(addr result.buffer.data[0], cstring(s), s.len)
-  result.first = 0
-  result.len = len
-
-when declared(atomicLoadN):
-  template load(x): untyped = atomicLoadN(addr x, ATOMIC_SEQ_CST)
-else:
-  # XXX Fixme
-  template load(x): untyped = x
-
-proc add*(s: var SharedString; t: cstring; len: Natural) =
-  if len == 0: return
-  let newLen = s.len + len
-  if s.buffer.isNil:
-    s.buffer = newBuffer(len, len)
-    copyMem(addr s.buffer.data[0], t, len)
-    s.len = len
-  elif newLen >= s.buffer.capacity or s.first != 0 or
-      s.len != s.buffer.realLen or load(s.buffer.refcount) > 1:
-    let oldBuf = s.buffer
-    s.buffer = newBuffer(max(s.buffer.capacity * 3 div 2, newLen), newLen)
-    copyMem(addr s.buffer.data[0], addr oldBuf.data[s.first], s.len)
-    copyMem(addr s.buffer.data[s.len], t, len)
-    decRef(oldBuf)
-  else:
-    copyMem(addr s.buffer.data[s.len], t, len)
-    s.buffer.realLen += len
-    s.len += len
-
-proc add*(s: var SharedString; t: string) =
-  s.add(t.cstring, t.len)
-
-proc rawData*(s: var SharedString): pointer =
-  if s.buffer.isNil: result = nil
-  else: result = addr s.buffer.data[s.first]
-
-proc add*(s: var SharedString; t: SharedString) =
-  if t.buffer.isNil: return
-  s.add(cast[cstring](addr s.buffer.data[s.first]), t.len)
-
-proc `$`*(s: SharedString): string =
-  result = newString(s.len)
-  if s.len > 0:
-    copyMem(addr result[0], addr s.buffer.data[s.first], s.len)
-
-proc `==`*(s: SharedString; t: string): bool =
-  if s.buffer.isNil: result = t.len == 0
-  else: result = t.len == s.len and equalMem(addr s.buffer.data[s.first],
-                                             cstring(t), t.len)
-
-proc `==`*(s, t: SharedString): bool =
-  if s.buffer.isNil: result = t.len == 0
-  else: result = t.len == s.len and equalMem(addr s.buffer.data[s.first],
-                                             addr t.buffer.data[t.first], t.len)
-
-iterator items*(s: SharedString): char =
-  let buf = s.buffer.data
-  let x = s.first
-  if buf != nil:
-    for i in 0..<s.len:
-      yield buf[i+x]
-
-import hashes
-
-proc hash*(s: SharedString): THash =
-  var h: THash = 0
-  for x in s: h = h !& x.hash
-  result = !$h
diff --git a/lib/pure/events.nim b/lib/pure/events.nim
deleted file mode 100644
index 35be7409f..000000000
--- a/lib/pure/events.nim
+++ /dev/null
@@ -1,102 +0,0 @@
-#
-#
-#            Nim's Runtime Library
-#        (c) Copyright 2011 Alexander Mitchell-Robinson
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-## :Author: Alexander Mitchell-Robinson (Amrykid)
-##
-## Unstable API.
-##
-## This module implements an event system that is not dependent on external
-## graphical toolkits. It was originally called ``NimEE`` because
-## it was inspired by Python's PyEE module. There are two ways you can use
-## events: one is a python-inspired way; the other is more of a C-style way.
-##
-## .. code-block:: Nim
-##    var ee = initEventEmitter()
-##    var genericargs: EventArgs
-##    proc handleevent(e: EventArgs) =
-##        echo("Handled!")
-##
-##    # Python way
-##    ee.on("EventName", handleevent)
-##    ee.emit("EventName", genericargs)
-##
-##    # C/Java way
-##    # Declare a type
-##    type
-##        SomeObject = object of RootObj
-##            SomeEvent: EventHandler
-##    var myobj: SomeObject
-##    myobj.SomeEvent = initEventHandler("SomeEvent")
-##    myobj.SomeEvent.addHandler(handleevent)
-##    ee.emit(myobj.SomeEvent, genericargs)
-
-type
-  EventArgs* = object of RootObj ## Base object for event arguments that are passed to callback functions.
-  EventHandler* = tuple[name: string, handlers: seq[proc(e: EventArgs) {.closure.}]] ## An eventhandler for an event.
-
-type
-  EventEmitter* = object ## An object that fires events and holds event handlers for an object.
-    s: seq[EventHandler]
-  EventError* = object of ValueError
-
-proc initEventHandler*(name: string): EventHandler =
-  ## Initializes an EventHandler with the specified name and returns it.
-  result.handlers = @[]
-  result.name = name
-
-proc addHandler*(handler: var EventHandler, fn: proc(e: EventArgs) {.closure.}) =
-  ## Adds the callback to the specified event handler.
-  handler.handlers.add(fn)
-
-proc removeHandler*(handler: var EventHandler, fn: proc(e: EventArgs) {.closure.}) =
-  ## Removes the callback from the specified event handler.
-  for i in countup(0, len(handler.handlers)-1):
-    if fn == handler.handlers[i]:
-      handler.handlers.del(i)
-      break
-
-proc containsHandler*(handler: var EventHandler, fn: proc(e: EventArgs) {.closure.}): bool =
-  ## Checks if a callback is registered to this event handler.
-  return handler.handlers.contains(fn)
-
-
-proc clearHandlers*(handler: var EventHandler) =
-  ## Clears all of the callbacks from the event handler.
-  setLen(handler.handlers, 0)
-
-proc getEventHandler(emitter: var EventEmitter, event: string): int =
-  for k in 0..high(emitter.s):
-    if emitter.s[k].name == event: return k
-  return -1
-
-proc on*(emitter: var EventEmitter, event: string, fn: proc(e: EventArgs) {.closure.}) =
-  ## Assigns a event handler with the specified callback. If the event
-  ## doesn't exist, it will be created.
-  var i = getEventHandler(emitter, event)
-  if i < 0:
-    var eh = initEventHandler(event)
-    addHandler(eh, fn)
-    emitter.s.add(eh)
-  else:
-    addHandler(emitter.s[i], fn)
-
-proc emit*(emitter: var EventEmitter, eventhandler: var EventHandler,
-           args: EventArgs) =
-  ## Fires an event handler with specified event arguments.
-  for fn in items(eventhandler.handlers): fn(args)
-
-proc emit*(emitter: var EventEmitter, event: string, args: EventArgs) =
-  ## Fires an event handler with specified event arguments.
-  var i = getEventHandler(emitter, event)
-  if i >= 0:
-    emit(emitter, emitter.s[i], args)
-
-proc initEventEmitter*(): EventEmitter =
-  ## Creates and returns a new EventEmitter.
-  result.s = @[]