-
Notifications
You must be signed in to change notification settings - Fork 21
/
task.nim
72 lines (59 loc) · 1.79 KB
/
task.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import
# Internal
./primitives/c
# Task
# ----------------------------------------------------------------------------------
const
TaskDataSize* = 192 - 96
type
Task* = ptr TaskObj
TaskObj = object
# We save memory by using int32 instead of int
# We also keep the original "future" name
# It will be changed to FlowVar in the future for async compat
parent*: Task
prev*: Task
next*: Task
fn*: proc (param: pointer) {.nimcall.} # nimcall / closure?
batch*: int32
victim*: int32
start*: int
cur*: int
stop*: int
chunks*: int
sst*: int # splittable task granularity
is_loop*: bool
has_future*: bool
# List of futures required by the current task
futures: pointer
# User data
data*: array[TaskDataSize, byte]
static: assert sizeof(TaskObj) == 192,
"TaskObj is of size " & $sizeof(TaskObj) &
" instead of the expected 192 bytes."
func task_zero*(task: sink Task): Task {.inline.} =
zeroMem(task, sizeof(TaskObj))
return task
func task_new*(): Task {.inline.} =
# We consider that task_new has no side-effect
# i.e. it never fails
# and we don't care about pointer addresses
result = malloc(TaskObj)
if result.isNil:
{.noSideEffect.}:
# writeStackTrace()
write(stderr, "Warning: task_new failed\n")
return
result = task_zero(result)
func task_delete*(task: sink Task) {.inline.} =
free(task)
func task_data*(task: Task): ptr array[TaskDataSize, byte] {.inline.} =
task.data.addr
# Private memory (PRM) task queue
# Circular doubly-linked list
# ----------------------------------------------------------------------------------
# TODO: currently unused
# Smoke test
# --------------------------------------------------
when isMainModule:
let x = task_new()