-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparallel.scm
130 lines (107 loc) · 2.44 KB
/
parallel.scm
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
;;; To allow parallel execution of any number of thunks, for
;;; effect. The values are discarded.
(define disallow-preempt-current-thread
(access disallow-preempt-current-thread
(->environment '(runtime thread))))
(define allow-preempt-current-thread
(access allow-preempt-current-thread
(->environment '(runtime thread))))
(define (kill-thread thread)
(let ((event
(lambda ()
(exit-current-thread 'RIP))))
(without-interrupts
(lambda ()
(case (thread-execution-state thread)
((STOPPED) (restart-thread thread #t event))
((DEAD) unspecific)
(else (signal-thread-event thread event)))))))
(define (parallel-execute . thunks)
(let ((my-threads '()))
(define (terminator)
(without-interrupts
(lambda ()
(for-each kill-thread my-threads)
(set! my-threads '())
unspecific)))
(without-interrupts
(lambda ()
(set! my-threads
(map (lambda (thunk)
(let ((thread (create-thread #f thunk)))
(detach-thread thread)
thread))
thunks))
unspecific))
terminator))
#|
;;; IO system is not completely interlocked, so...
(define (try n)
(parallel-execute
(lambda ()
(write-line 'hi)
(let lp ((i 0))
(if (< i 10000)
(lp (1+ i))))
(write-line 'gjs))
(lambda ()
(write-line 'there)
(let lp ((i 0))
(if (< i n)
(lp (1+ i))))
(write-line 'foo))))
(define foo (try 9188))
;Value foo
hi
there
foo
foo
gjs
(foo)
;No value
|#
(define (make-serializer)
(let ((mutex (make-thread-mutex)))
(define (serialized f)
(define (serialized-f . args)
(with-thread-mutex-locked mutex
(lambda ()
(apply f args))))
serialized-f)
serialized))
(define output-serialized (make-serializer))
(define write-line
(output-serialized write-line))
(define display
(output-serialized display))
(define write
(output-serialized write))
#|
;;; This solves the IO interlock problem
(define (try n)
(parallel-execute
(lambda ()
(write-line 'hi)
(let lp ((i 0))
(if (< i 10000)
(lp (1+ i))))
(write-line 'gjs))
(lambda ()
(write-line 'there)
(let lp ((i 0))
(if (< i n)
(lp (1+ i))))
(write-line 'foo))))
(define foo (try 9197))
;Value: foo
hi
there
gjs
foo
(define foo (try 9196))
;Value: foo
hi
there
foo
gjs
|#