-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscheduler.lisp
75 lines (69 loc) · 3.19 KB
/
scheduler.lisp
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
73
74
75
(defpackage #:psx-scheduler
(:nicknames #:scheduler)
(:use :cl)
(:export #:scheduler #:scheduler-components #:make-scheduler
#:register-sync-event #:scheduler-master-clock
#:component-epoch-of-next-sync
#:sync-components #:component-sync-callback))
(in-package :psx-scheduler)
(declaim (optimize (speed 3) (safety 1)))
(defstruct component
"Represents a syncable component."
; TODO(Samantha): It might finally be time to make this a class and have the
; syncable components inherit from it.
(epoch-of-next-sync 0 :type (unsigned-byte 62))
(sync-callback
(lambda (clock) (declare (ignore clock)))
:type (function ((unsigned-byte 62)))))
(defstruct scheduler
"Records all of the various syncable components and the system's master clock.
Responsible for handling sync event registration and component syncing
itself."
(master-clock 0 :type (unsigned-byte 62))
(components
(make-array '(4)
:element-type 'component
:initial-contents (vector (make-component)
(make-component)
(make-component)
(make-component)))
:type (simple-array component (4))))
(declaim (ftype (function (scheduler keyword (unsigned-byte 62)))))
(defun register-sync-event (scheduler component epoch-of-next-sync)
"Sets a definitive time for when a component knows it will _need_ to sync.
Pleast note that this is not the only way a component can sync, as is the
case that happens when the cpu attempts to read or write to a syncable
component."
(ecase component
(:gpu (setf (component-epoch-of-next-sync
(aref (scheduler-components scheduler)
0))
epoch-of-next-sync))
(:timers (setf (component-epoch-of-next-sync
(aref (scheduler-components scheduler)
1))
epoch-of-next-sync))
(:joypads (setf (component-epoch-of-next-sync
(aref (scheduler-components scheduler)
2))
epoch-of-next-sync))
(:cdrom (setf (component-epoch-of-next-sync
(aref (scheduler-components scheduler)
3))
epoch-of-next-sync))))
(declaim (ftype (function (scheduler (unsigned-byte 62)))
sync-components))
(defun sync-components (scheduler clocks)
"Loops through all registered syncable components and updates those that have
registered a predicted sync."
(let ((previous-clock (scheduler-master-clock scheduler)))
(setf (scheduler-master-clock scheduler)
(ldb (byte 62 0) (+ (scheduler-master-clock scheduler)
clocks)))
(loop for component across (scheduler-components scheduler)
do (when (<= (1+ previous-clock)
(component-epoch-of-next-sync component)
(scheduler-master-clock scheduler))
(funcall (component-sync-callback component)
(scheduler-master-clock scheduler))))
(values)))