switch to smartptrs

This commit is contained in:
Jaremy Creechley 2023-08-25 15:08:19 -07:00 committed by Dmitriy Ryajov
parent 727f8b6c2a
commit 0d4e6f203a
No known key found for this signature in database
GPG Key ID: DA8C680CE7C657A4

View File

@ -1,93 +1,52 @@
import std/os
import std/locks
import std/atomics
# import std/atomics
import threading/smartptrs
import events
type
DataBuffer* = object
cnt: ptr int
DataBufferHolder* = object
buf: ptr UncheckedArray[byte]
size: int
DataBuffer* = SharedPtr[DataBufferHolder]
KeyBuffer* = DataBuffer
ValueBuffer* = DataBuffer
StringBuffer* = DataBuffer
CatchableErrorBuffer* = object
msg: StringBuffer
proc `$`*(data: DataBuffer): string =
if data.buf.isNil:
result = "nil"
else:
let sz = min(16, data.size)
result = newString(sz + 2)
copyMem(addr result[1], data.buf, sz)
result[0] = '<'
result[^1] = '>'
proc `=destroy`*(x: var DataBuffer) =
proc `=destroy`*(x: var DataBufferHolder) =
## copy pointer implementation
if x.buf != nil and x.cnt != nil:
let res = atomicSubFetch(x.cnt, 1, ATOMIC_ACQUIRE)
if res == 0:
when isMainModule or true:
echo "buffer: FREE: ", repr x.buf.pointer, " ", x.cnt[]
deallocShared(x.buf)
deallocShared(x.cnt)
else:
when isMainModule:
echo "buffer: decr: ", repr x.buf.pointer, " ", x.cnt[]
if x.buf != nil:
when isMainModule or true:
echo "buffer: FREE: ", repr x.buf.pointer
deallocShared(x.buf)
proc `=copy`*(a: var DataBuffer; b: DataBuffer) =
## copy pointer implementation
# do nothing for self-assignments:
if a.buf == b.buf: return
`=destroy`(a)
discard atomicAddFetch(b.cnt, 1, ATOMIC_RELAXED)
a.size = b.size
a.buf = b.buf
a.cnt = b.cnt
when isMainModule:
echo "buffer: Copy: repr: ", b.cnt[],
" ", repr a.buf.pointer,
" ", repr b.buf.pointer
proc incrAtomicCount*(a: DataBuffer) =
let res = atomicAddFetch(a.cnt, 1, ATOMIC_RELAXED)
proc unsafeGetAtomicCount*(a: DataBuffer): int =
atomicLoad(a.cnt, addr result, ATOMIC_RELAXED)
proc len*(a: DataBuffer): int = a.size
proc len*(a: DataBuffer): int = a[].size
proc new*(tp: typedesc[DataBuffer], size: int = 0): DataBuffer =
let cnt = cast[ptr int](allocShared0(sizeof(result.cnt)))
cnt[] = 1
DataBuffer(
cnt: cnt,
buf: cast[typeof(result.buf)](allocShared0(size)),
newSharedPtr(DataBufferHolder(
buf: cast[typeof(result[].buf)](allocShared0(size)),
size: size,
)
))
proc new*[T: byte | char](tp: typedesc[DataBuffer], data: openArray[T]): DataBuffer =
## allocate new buffer and copies indata from openArray
##
result = DataBuffer.new(data.len)
if data.len() > 0:
copyMem(result.buf, unsafeAddr data[0], data.len)
copyMem(result[].buf, unsafeAddr data[0], data.len)
proc toSeq*[T: byte | char](a: DataBuffer, tp: typedesc[T]): seq[T] =
result = newSeq[T](a.len)
copyMem(addr result[0], unsafeAddr a.buf[0], a.len)
copyMem(addr result[0], unsafeAddr a[].buf[0], a.len)
proc toString*(data: DataBuffer): string =
result = newString(data.len())
if data.len() > 0:
copyMem(addr result[0], unsafeAddr data.buf[0], data.len)
copyMem(addr result[0], unsafeAddr data[].buf[0], data.len)
proc toCatchable*(data: CatchableErrorBuffer): ref CatchableError =
result = (ref CatchableError)(msg: data.msg.toString())