source: project/wiki/eggref/4/synch @ 35565

Last change on this file since 35565 was 35565, checked in by Kon Lovett, 17 months ago

ns pollution acknowledged

File size: 10.6 KB
Line 
1[[tags: egg]]
2
3== synch
4
5Simple critical region helpers.
6
7[[toc:]]
8
9
10== Documentation
11
12Where {{MUTEX-FORM}} below the following forms are accepted:
13
14; {{MUTEX-OBJECT}} : mutex
15; {{(MUTEX-OBJECT [(LOCK-ARG...) [(UNLOCK-ARG...)]])}} : mutex w/ optional lock and unlock arguments
16
17=== Synchronized Invocation - Continuation Safe
18
19These forms have the mutex lock/unlock wrapped in '''{{dynamic-wind}}'''.
20
21==== synch
22
23<macro>(synch MUTEX-FORM [BODY ...]) -> *</macro>
24
25Execute {{BODY ...}} while {{MUTEX}} locked.
26
27Returns the result of {{BODY ...}}.
28
29==== synch-with
30
31<macro>(synch-with MUTEX-FORM VARIABLE [BODY ...]) -> *</macro>
32
33Execute {{BODY ...}} while {{MUTEX}} locked and the mutex-specific of {{MUTEX}}
34bound to {{VARIABLE}}.
35
36Returns the result of {{BODY ...}}.
37
38==== call-synch
39
40<macro>(call-synch MUTEX-FORM PROCEDURE [ARGUMENTS ...]) -> *</macro>
41
42Invoke {{PROCEDURE}} on the argument list {{ARGUMENTS ...}} while {{MUTEX}}
43locked.
44
45Returns the result of the {{PROCEDURE}} invocation.
46
47==== call-synch-with
48
49<macro>(call-synch-with MUTEX-FORM PROCEDURE [ARGUMENTS ...]) -> *</macro>
50
51Invoke {{PROCEDURE}} on the mutex-specific of {{MUTEX}}
52and the {{ARGUMENTS ...}} while {{MUTEX}} locked.
53
54Returns the result of the {{PROCEDURE}} invocation.
55
56==== apply-synch
57
58<macro>(apply-synch MUTEX-FORM PROCEDURE [ARGUMENTS ...]) -> *</macro>
59
60Apply {{PROCEDURE}} to the argument list {{ARGUMENTS ...}} while {{MUTEX}}
61locked.
62
63Returns the result of the {{PROCEDURE}} application.
64
65==== apply-synch-with
66
67<macro>(apply-synch-with MUTEX-FORM PROCEDURE [ARGUMENTS ...]) -> *</macro>
68
69Apply {{PROCEDURE}} to the mutex-specific of {{MUTEX}}) and the {{ARGUMENTS ...}}
70while {{MUTEX}} locked.
71
72Returns the result of the {{PROCEDURE}} application.
73
74==== synch-lock
75
76<macro>(synch-lock MUTEX-FORM [BODY ...]) -> *</macro>
77
78Execute {{BODY ...}} while {{MUTEX}} locked, and leave mutex locked.
79
80Returns the result of {{BODY ...}}.
81
82==== synch-unlock
83
84<macro>(synch-unlock MUTEX-FORM [BODY ...]) -> *</macro>
85
86Execute {{BODY ...}} while {{MUTEX}} locked, and leave mutex unlocked.
87
88Returns the result of {{BODY ...}}.
89
90Should the mutex be unlocked a warning is issued and the mutex is locked before
91executing the {{BODY}}.
92
93==== let-synch-with
94
95<macro>(let-synch-with BINDINGS [BODY ...]) -> *</macro>
96
97{{BINDINGS}} is a list of {{(VARIABLE MUTEX-FORM)}}.
98
99Expands into a nested {{(synch-with MUTEX-FORM VARIABLE ...}} form, a '''{{synch-with}}'''
100for each binding pair in {{BINDINGS}}. The leftmost binding pair is the
101outermost.
102
103Returns the result of {{BODY ...}}.
104
105==== set!-synch-with
106
107<macro>(set!-synch-with MUTEX-FORM VARIABLE [BODY ...]) -> *</macro>
108
109While the {{MUTEX}} is locked, evaluates {{BODY ...}} with the {{VARIABLE}}
110bound to the mutex-specific of {{MUTEX}}. Sets the mutex-specific of {{MUTEX}}
111to the result of the evaluation.
112
113Returns the new mutex-specific of {{MUTEX}}.
114
115==== object-synch-cut-with
116
117<macro>(object-synch-cut-with MUTEX-FORM [BODY ...]) -> *<-macro>
118
119Execute {{BODY ...}} while {{MUTEX}} locked.
120
121The top-level forms of {{BODY ...}} are parsed for occurrences of {{><}}. All
122such occurrences are replaced by the mutex-specific of {{MUTEX}}.
123
124Returns the result of {{BODY ...}}.
125
126==== record-synch
127
128<macro>(record-synch RECORD-OBJECT RECORD-SYMBOL [BODY ...]) -> *</macro>
129
130Execute {{BODY ...}} while the {{RECORD-OBJECT}} mutex is locked. The mutex is
131a field of the record named {{RECORD-SYMBOL-mutex}}.
132
133Returns the result of {{BODY ...}}.
134
135<enscript language=scheme>
136(define-record-type foo
137  (make-foo a b mtx)
138  foo?
139  (a foo-a)
140  (b foo-b)
141  (mtx foo-mutex) )
142
143(define f1 (make-foo 1 2 (make-mutex 'foo)))
144
145(record-synch foo f1 (+ (foo-a f1) (foo-b f1)))
146</enscript>
147
148==== record-synch-lock
149
150<macro>(record-synch-lock RECORD-OBJECT RECORD-SYMBOL [BODY ...]) -> *</macro>
151
152Execute {{BODY ...}} while the {{RECORD-OBJECT}} mutex is locked, and leave the
153mutex locked.
154
155Returns the result of {{BODY ...}}.
156
157{{RECORD-SYMBOL}} and {{RECORD-OBJECT}} are per '''{{record-synch}}'''.
158
159==== record-synch-unlock
160
161<macro>(record-synch-unlock RECORD-OBJECT RECORD-SYMBOL [BODY ...]) -> *</macro>
162
163Execute {{BODY ...}} while the {{RECORD-OBJECT}} mutex is locked, and leave the
164mutex unlocked.
165
166Returns the result of {{BODY ...}}.
167
168{{RECORD-SYMBOL}} and {{RECORD-OBJECT}} are per '''{{record-synch}}'''.
169
170Should the mutex be unlocked a warning is issued and the mutex is locked before
171executing the {{BODY}}.
172
173=== Synchronized Invocation - Continuation Unsafe
174
175These forms do not have the mutex lock/unlock wrapped in '''{{dynamic-wind}}''',
176otherwise the same behavior.
177
178==== %call-synch
179
180<macro>(%call-synch MUTEX-FORM PROCEDURE [ARGUMENTS ...]) -> *</macro>
181
182==== %call-synch-with
183
184<macro>(%call-synch-with MUTEX-FORM PROCEDURE [ARGUMENTS ...]) -> *</macro>
185
186==== %apply-synch
187
188<macro>(%apply-synch MUTEX-FORM PROCEDURE [ARGUMENTS ...]) -> *</macro>
189
190==== %apply-synch-with
191
192<macro>(%apply-synch-with MUTEX-FORM PROCEDURE [ARGUMENTS ...]) -> *</macro>
193
194==== %synch
195
196<macro>(%synch MUTEX-FORM [BODY ...]) -> *</macro>
197
198==== %synch-with
199
200<macro>(%synch-with MUTEX-FORM VARIABLE [BODY ...]) -> *</macro>
201
202==== %synch-lock
203
204<macro>(%synch-lock MUTEX-FORM [BODY ...]) -> *</macro>
205
206==== %synch-unlock
207
208<macro>(%synch-unlock MUTEX-FORM [BODY ...]) -> *</macro>
209
210==== %let-synch
211
212<macro>(%let-synch BINDINGS [BODY ...]) -> *</macro>
213
214==== %set!-synch-with
215
216<macro>(%set!-synch-with MUTEX-FORM VARIABLE [BODY ...]) -> *</macro>
217
218==== %object-synch-cut-with
219
220<macro>(%object-synch-cut-with MUTEX-FORM [BODY ...]) -> *</macro>
221
222==== %record-synch
223
224<macro>(%record-synch RECORD-OBJECT RECORD-SYMBOL [BODY ...]) -> *</macro>
225
226==== %record-synch-lock
227
228<macro>(%record-synch-lock RECORD-OBJECT RECORD-SYMBOL [BODY ...]) -> *</macro>
229
230==== %record-synch-unlock
231
232<macro>(%record-synch-unlock RECORD-OBJECT RECORD-SYMBOL [BODY ...]) -> *</macro>
233
234=== Object Synchronization
235
236==== make-synch-with-object
237
238<procedure>(make-synch-with-object OBJECT [NAME]) -> mutex</procedure>
239
240Returns a mutex with a mutex-specific value of {{OBJECT}}, and optional mutex
241{{NAME}}.
242
243{{NAME}} is either a symbol or a one element list of symbol. When a list the
244first element is used as the basis for a generated symbol. When a symbol it is
245used literally as the mutex name.
246
247When {{NAME}} is missing a generated symbol with the prefix '''{{synchobj}}''' is
248provided.
249
250==== synch-with-object?
251
252<procedure>(synch-with-object? OBJECT [PREDICATE]) -> bool</procedure>
253
254Is the {{OBJECT}} a synchronized object - a mutex with a non-void mutex
255specific?
256
257The optional {{PREDICATE}} is used to verify the type of the mutex-specific
258binding. Otherwise any object is accepted.
259
260==== define-constructor-synch
261
262<macro>(define-constructor-synch CTORNAME [ID])</macro>
263
264<enscript language=scheme>
265(define-constructor-synch make-hash-table hash-table-synch)
266;=> similar
267(define (make-hash-table-sync . args)
268  (make-synch-with-object (apply make-hash-table args) '(hash-table-synch)) )
269</enscript>
270
271==== define-predicate-synch
272
273<macro>(define-predicate-synch PREDNAME)</macro>
274
275<enscript language=scheme>
276(define-predicate-synch hash-table?)
277;=> similar
278(define (hash-table?-sync obj) (synch-with-object? obj hash-table?))
279</enscript>
280
281==== define-operation-synch
282
283<macro>(define-operation-synch OPERNAME)</macro>
284
285Note that the operand must be the first argument of {{OPERNAME}}.
286
287<enscript language=scheme>
288(define-operation-synch hash-table-set!)
289;=> similar
290(define (hash-table-set!-sync mtx+obj . args)
291  (let ((mtx (if (pair? mtx+obj) (car mtx+obj) mtx+obj)))
292    (check-mutex+object 'hash-table-set!-synch mtx 'object-synch)
293    (synch-with mtx+obj obj (apply hash-table-set! obj args)) ) )
294</enscript>
295
296==== define-operation-%synch
297
298<macro>(define-operation-%synch OPERNAME)</macro>
299
300Note that the operand must be the first argument of {{OPERNAME}}.
301
302==== synchronized-procedure
303
304<procedure>(synchronized-procedure PROC) -> procedure</procedure>
305
306Returns a synchronized version of {{PROC}}
307
308=== Critical Regions
309
310==== Usage
311
312<enscript language=scheme>
313(require-extension critical-region)
314</enscript>
315
316Evaluated under {{(disable-interrupts)}}.
317
318==== critical-region
319
320<syntax>(critical-region EXPR ...)</syntax>
321
322Executes {{EXPR ...}}.
323
324==== critical-region-apply
325
326<procedure>(critical-region-apply PROC ...) -> *</procedure>
327
328Executes {{(apply PROC ...)}}.
329
330==== critical-region-call
331
332<syntax>(critical-region-call THUNK)</syntax>
333
334Executes {{(THUNK)}}.
335
336
337== Usage
338
339<enscript language=scheme>
340(require-extension synch)
341</enscript>
342
343or
344
345<enscript language=scheme>
346(require-library synch)
347...
348(import synch)
349</enscript>
350
351
352== Notes
353
354* Inspired by Thomas Chust.
355
356
357== Bugs & Limitations
358
359* {{define-*-synch}} is obtuse.
360
361
362== Author
363
364[[/users/kon-lovett|Kon Lovett]]
365
366
367== Requirements
368
369[[/man/4/Unit srfi-18|Unit srfi-18]]
370[[/man/4/check-errors|check-errors]]
371
372[[setup-helper|setup-helper]]
373
374
375== Version history
376
377; 2.3.0 : Add {{critical-region}}, {{synchronized-procedure}}, {{record-synch}}, {{record-synch-lock}}, {{record-synch-unlock}}, {{call-synch}}, {{call-synch-with}}, {{apply-synch}}, {{apply-synch-with}}, {{let-synch-with}}, {{set!-synch-with}}, {{synch-lock}}, {{synch-unlock}}, {{object-synch-cut-with}}, {{make-synch-with-object}}, {{synch-with-object?}}, {{define-constructor-synch}}, {{define-predicate-synch}}, {{define-operation-synch}}.
378; 2.2.2 :
379; 2.2.1 : Do not build {{format-synch}}.
380; 2.2.0 : Deprecate {{../synch}} bindings. Add 'format-synch.scm'.
381; 2.1.4 : .
382; 2.1.3 : .
383; 2.1.2 : Ensure all local vars in operation macros hygenic.
384; 2.1.1 : Fix {{%record/synch}} body expansion. Fix {{make-object/synch}} default name.
385; 2.1.0 : Support for mutex lock/unlock arguments. Operation wrapper macros.
386; 2.0.0 : Port to hygienic Chicken. Removed 'set-object!/synch'.
387
388
389== License
390
391Copyright (C) 2009-2018 Kon Lovett.  All rights reserved.
392
393Permission is hereby granted, free of charge, to any person obtaining a
394copy of this software and associated documentation files (the Software),
395to deal in the Software without restriction, including without limitation
396the rights to use, copy, modify, merge, publish, distribute, sublicense,
397and/or sell copies of the Software, and to permit persons to whom the
398Software is furnished to do so, subject to the following conditions:
399
400The above copyright notice and this permission notice shall be included
401in all copies or substantial portions of the Software.
402
403THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
404IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
405FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
406THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
407OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
408ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
409OTHER DEALINGS IN THE SOFTWARE.
Note: See TracBrowser for help on using the repository browser.