blob: 86244460cf0454df8dcf29a5b7bf384bef45fd2b (
plain)
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
|
SCHEDULER
- worker thread pool executes read to be run fibers
- thread pool executes fibers from FIFO queues (one per each priority)
- possible to make main thread separate scheduler so we can bind some
fibers to run in main thread only (not needed?)
THE BIG SCHEDULING QUEUE (shared queue with all worker threads)
--- works also between machines, in which case we just always queue
work items to remote vmach (need to send wakeups too)
- steal first item from the local cache if any
- mutex lock
- if stuff to push
- while idle_vcpu not empty
- pop idle_vcpu from list
- push item to idle_vcpu
- push rest of items to global lists accordingly
- mutex unlock
- call futex_wake for all idle_cpu's we stuffed
- return stolen item
- if stuff on list
- pop item from list
- mutex unlock
- return popped_item
- insert self to idle_vcpu list
- mutex unlock
- futex_wait on local_pointer
- return local_pointer
- mutex unlock
WAKEUP
- as minimum keep wakeup bitfield for most common types, and use
prepare sleep, and sleep primitives with acceptable wakeup reasons
- might add so that wakupper calls wakeupee to execute their wakeup
condition check once ask rescheduling based or that or not; this way
empty spin does not require pushing to scheduler queue and thread
pool wakeup
IO SLEEPING/DISPATCHING
- epoll in edge-triggered monitoring for file i/o
- epoll_wait done in separate thread (or possibly as regular fiber)
which sole purpose is to wakeup threads for thread pool
- signalfd for signal handling
- timerfd for timeout handling
INTER FIBRE CALLS (IFC)
- sends a callback to be execute under some other fibre
- executed at tf_ifc_process() points, or at tf_exit() time
- might need tfc_ifc_wait() for synchronizing with ifc completion
- sending uses atomic LIFO (single atomic cmpxchg)
- receive does LIFO flush (single atomic xchg) and reverses order(?)
- need way to check if IFC is queued or not (so it's safe to reuse it)
TIMEOUTS
- one (or more) fibers serving as alarm generators
- 4-heap with mremappable heap array
- receives IFC calls from other threads
- receives io wakeups from timerfd
- sends async signal to fiber after timeout
FIBERS
- fd, signal, pid wait struct on stack of wait function
- fiber_kill can interrupt wait
FIBRE WAKE UP QUEUES
- mostly not needed (alarms, io uses async signal wakeups)
- for mutex, semaphores, possibly send io
- use thread mutexes for list access
- wait on single queue only(?)
FIBRE MUTEX
- simple wakeup queue, sleep on queue, uninterruptible?
|