add ffi/unsafe/collect-callback
The `ffi/unsafe/collect-callback` library exposes functionality formerly only available via Racket's C interface, but implement it for both Racket and RacketCs.
This commit is contained in:
parent
f8297f9c00
commit
d9ec0705cf
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
(define collection 'multi)
|
(define collection 'multi)
|
||||||
|
|
||||||
(define version "7.0.0.8")
|
(define version "7.0.0.9")
|
||||||
|
|
||||||
(define deps `("racket-lib"
|
(define deps `("racket-lib"
|
||||||
["racket" #:version ,version]))
|
["racket" #:version ,version]))
|
||||||
|
|
94
pkgs/racket-doc/scribblings/foreign/collect-callback.scrbl
Normal file
94
pkgs/racket-doc/scribblings/foreign/collect-callback.scrbl
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "utils.rkt"
|
||||||
|
(for-label ffi/unsafe/collect-callback))
|
||||||
|
|
||||||
|
@title{Garbage Collection Callbacks}
|
||||||
|
|
||||||
|
@defmodule[ffi/unsafe/collect-callback]{The
|
||||||
|
@racketmodname[ffi/unsafe/collect-callback] library provides functions
|
||||||
|
to register constrained callbacks that are run just before and after a
|
||||||
|
garbage collection.}
|
||||||
|
|
||||||
|
@history[#:added "7.0.0.9"]
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(unsafe-add-collect-callbacks [pre (vectorof vector?)]
|
||||||
|
[post (vectorof vector?)])
|
||||||
|
any/c]{
|
||||||
|
|
||||||
|
Registers descriptions of foreign functions to be called just before
|
||||||
|
and just after a garbage collection. The foreign functions must not
|
||||||
|
allocate garbage-collected memory, and they are called in a way that
|
||||||
|
does not allocate, which is why @var{pre_desc} and @var{post_desc} are
|
||||||
|
function descriptions instead of thunks.
|
||||||
|
|
||||||
|
A description is a vector of vectors, where each of the inner vectors
|
||||||
|
describes a single call, and the calls are performed in sequence. Each
|
||||||
|
call vector starts with a symbol that indicates the protocol of the
|
||||||
|
foreign function to be called. The following protocols are supported:
|
||||||
|
@margin-note*{The apparently arbitrary and whimsical set of supported
|
||||||
|
protocols is enough to allow DrRacket to show a garbage-collection
|
||||||
|
icon.}
|
||||||
|
|
||||||
|
@itemlist[
|
||||||
|
|
||||||
|
@item{@racket['int->void] corresponds to @cpp{void (*)(int)}.}
|
||||||
|
|
||||||
|
@item{@racket['ptr_ptr_ptr->void] corresponds to @cpp{void
|
||||||
|
(*)(void*, void*, void*)}.}
|
||||||
|
|
||||||
|
@item{@racket['ptr_ptr->save] corresponds to @cpp{void* (*)(void*,
|
||||||
|
void*, void*)}, but the result is recored as the current ``save''
|
||||||
|
value. The current ``save'' value starts as @cpp{NULL}.}
|
||||||
|
|
||||||
|
@item{@racket['save!_ptr->void] corresponds to @cpp{void (*)(void*,
|
||||||
|
void*)}, but only if the current ``save'' value is not a @cpp{NULL}
|
||||||
|
pointer, and passing that pointer as the function's first argument
|
||||||
|
(so that only one additional argument is us from the description
|
||||||
|
vector).}
|
||||||
|
|
||||||
|
@item{@racket['ptr_ptr_ptr_int->void] corresponds to @cpp{void
|
||||||
|
(*)(void*, void*, void*, int)}.}
|
||||||
|
|
||||||
|
@item{@racket['ptr_ptr_float->void] corresponds to @cpp{void
|
||||||
|
(*)(void*, void*, float)}.}
|
||||||
|
|
||||||
|
@item{@racket['ptr_ptr_double->void] corresponds to @cpp{void
|
||||||
|
(*)(void*, void*, double)}.}
|
||||||
|
|
||||||
|
@item{@racket['ptr_ptr_ptr_int_int_int_int_int_int_int_int_int->void]
|
||||||
|
corresponds to @cpp{void (*)(void*, void*, void*, int, int, int, int,
|
||||||
|
int, int, int, int, int)}.}
|
||||||
|
|
||||||
|
@item{@racket['osapi_ptr_int->void] corresponds to @cpp{void
|
||||||
|
(*)(void*, int)}, but using the stdcall calling convention
|
||||||
|
on Windows.}
|
||||||
|
|
||||||
|
@item{@racket['osapi_ptr_ptr->void] corresponds to @cpp{void
|
||||||
|
(*)(void*, void*)}, but using the stdcall calling convention
|
||||||
|
on Windows.}
|
||||||
|
|
||||||
|
@item{@racket['osapi_ptr_int_int_int_int_ptr_int_int_long->void]
|
||||||
|
corresponds to @cpp{void (*)(void*, int, int, int, int, void*,
|
||||||
|
int, int, long)}, but using the stdcall calling convention
|
||||||
|
on Windows.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
After the protocol symbol, the vector should contain a pointer to a
|
||||||
|
foreign function and then an element for each of the function's
|
||||||
|
arguments. Pointer values are represented as for the @racket[_pointer]
|
||||||
|
representation defined by @racketmodname[ffi/unsafe].
|
||||||
|
|
||||||
|
The result is a key for use with @cpp{scheme_remove_gc_callback}. If
|
||||||
|
the key becomes inaccessible, then the callback will be removed
|
||||||
|
automatically (but beware that the pre-callback will have executed and
|
||||||
|
the post-callback will not have executed)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@defproc[(unsafe-remove-collect-callbacks [key any/c]) void?]{
|
||||||
|
|
||||||
|
Unregisters pre- and post-collection callbacks that were previously
|
||||||
|
registered by a call to @racket[unsafe-add-collect-callbacks] that
|
||||||
|
returned @racket[v].}
|
|
@ -18,6 +18,7 @@
|
||||||
@include-section["port.scrbl"]
|
@include-section["port.scrbl"]
|
||||||
@include-section["global.scrbl"]
|
@include-section["global.scrbl"]
|
||||||
@include-section["os-thread.scrbl"]
|
@include-section["os-thread.scrbl"]
|
||||||
|
@include-section["collect-callback.scrbl"]
|
||||||
@include-section["objc.scrbl"]
|
@include-section["objc.scrbl"]
|
||||||
@include-section["ns.scrbl"]
|
@include-section["ns.scrbl"]
|
||||||
@include-section["com.scrbl"]
|
@include-section["com.scrbl"]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#lang scribble/doc
|
#lang scribble/doc
|
||||||
@(require "utils.rkt" (for-label ffi/unsafe))
|
@(require "utils.rkt" (for-label ffi/unsafe
|
||||||
|
ffi/unsafe/collect-callback))
|
||||||
|
|
||||||
@title[#:tag "im:memoryalloc"]{Memory Allocation}
|
@title[#:tag "im:memoryalloc"]{Memory Allocation}
|
||||||
|
|
||||||
|
@ -1176,60 +1177,11 @@ array @var{shape}, so the array need not be retained.
|
||||||
@function[(Scheme_Object* scheme_add_gc_callback [Scheme_Object* pre_desc]
|
@function[(Scheme_Object* scheme_add_gc_callback [Scheme_Object* pre_desc]
|
||||||
[Scheme_Object* post_desc])]{
|
[Scheme_Object* post_desc])]{
|
||||||
|
|
||||||
Registers descriptions of foreign functions to be called just before
|
The same as @racket[unsafe-add-collect-callbacks] from
|
||||||
and just after a garbage collection. The foreign functions must not
|
@racketmodname[ffi/unsafe/collect-callback].}
|
||||||
allocate garbage-collected memory, and they are called in a way that
|
|
||||||
does not allocate, which is why @var{pre_desc} and @var{post_desc} are
|
|
||||||
function descriptions instead of thunks.
|
|
||||||
|
|
||||||
A description is a vector of vectors, where each of the inner vectors
|
|
||||||
describes a single call, and the calls are performed in sequence. Each
|
|
||||||
call vector starts with a symbol that indicates the protocol of the
|
|
||||||
foreign function to be called. The following protocols are supported:
|
|
||||||
|
|
||||||
@itemlist[
|
|
||||||
|
|
||||||
@item{@racket['ptr_ptr_ptr->void] corresponds to @cpp{void
|
|
||||||
(*)(void*, void*, void*)}.}
|
|
||||||
|
|
||||||
@item{@racket['ptr_ptr_ptr_int->void] corresponds to @cpp{void
|
|
||||||
(*)(void*, void*, void*, int)}.}
|
|
||||||
|
|
||||||
@item{@racket['ptr_ptr_float->void] corresponds to @cpp{void
|
|
||||||
(*)(void*, void*, float)}.}
|
|
||||||
|
|
||||||
@item{@racket['ptr_ptr_double->void] corresponds to @cpp{void
|
|
||||||
(*)(void*, void*, double)}.}
|
|
||||||
|
|
||||||
@item{@racket['ptr_ptr_ptr_int_int_int_int_int_int_int_int_int->void]
|
|
||||||
corresponds to @cpp{void (*)(void*, void*, void*, int, int, int, int,
|
|
||||||
int, int, int, int, int)}.}
|
|
||||||
|
|
||||||
@item{@racket['osapi_ptr_int->void] corresponds to @cpp{void
|
|
||||||
(*)(void*, int)}, but using the stdcall calling convention
|
|
||||||
on Windows.}
|
|
||||||
|
|
||||||
@item{@racket['osapi_ptr_ptr->void] corresponds to @cpp{void
|
|
||||||
(*)(void*, void*)}, but using the stdcall calling convention
|
|
||||||
on Windows.}
|
|
||||||
|
|
||||||
@item{@racket['osapi_ptr_int_int_int_int_ptr_int_int_long->void]
|
|
||||||
corresponds to @cpp{void (*)(void*, int, int, int, int, void*,
|
|
||||||
int, int, long)}, but using the stdcall calling convention
|
|
||||||
on Windows.}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
After the protocol symbol, the vector should contain a pointer to a
|
|
||||||
foreign function and then an element for each of the function's
|
|
||||||
arguments. Pointer values are represented as for the @racket[_pointer]
|
|
||||||
representation defined by @racketmodname[ffi/unsafe].
|
|
||||||
|
|
||||||
The result is a key for use with @cpp{scheme_remove_gc_callback}. If
|
|
||||||
the key becomes inaccessible, then the callback will be removed
|
|
||||||
automatically (but beware that the pre-callback will have executed and
|
|
||||||
the post-callback will not have executed).}
|
|
||||||
|
|
||||||
@function[(void scheme_remove_gc_callback [Scheme_Object* key])]{
|
@function[(void scheme_remove_gc_callback [Scheme_Object* key])]{
|
||||||
|
|
||||||
Removes a garbage-collection callback installed with @cpp{scheme_add_gc_callback}.}
|
The same as @racket[unsafe-remove-collect-callbacks], removes
|
||||||
|
garbage-collection callbacks installed with
|
||||||
|
@cpp{scheme_add_gc_callback}.}
|
||||||
|
|
5
racket/collects/ffi/unsafe/collect-callback.rkt
Normal file
5
racket/collects/ffi/unsafe/collect-callback.rkt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#lang racket/base
|
||||||
|
(require '#%unsafe)
|
||||||
|
|
||||||
|
(provide unsafe-add-collect-callbacks
|
||||||
|
unsafe-remove-collect-callbacks)
|
|
@ -41,7 +41,9 @@
|
||||||
unsafe-call-in-os-thread
|
unsafe-call-in-os-thread
|
||||||
unsafe-make-os-semaphore
|
unsafe-make-os-semaphore
|
||||||
unsafe-os-semaphore-post
|
unsafe-os-semaphore-post
|
||||||
unsafe-os-semaphore-wait)
|
unsafe-os-semaphore-wait
|
||||||
|
unsafe-add-collect-callbacks
|
||||||
|
unsafe-remove-collect-callbacks)
|
||||||
(rename-out [new:unsafe-impersonate-procedure unsafe-impersonate-procedure]
|
(rename-out [new:unsafe-impersonate-procedure unsafe-impersonate-procedure]
|
||||||
[new:unsafe-chaperone-procedure unsafe-chaperone-procedure])
|
[new:unsafe-chaperone-procedure unsafe-chaperone-procedure])
|
||||||
(prefix-out unsafe-
|
(prefix-out unsafe-
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
[prop:chaperone-unsafe-undefined (known-constant)]
|
[prop:chaperone-unsafe-undefined (known-constant)]
|
||||||
[unsafe-abort-current-continuation/no-wind (known-procedure 4)]
|
[unsafe-abort-current-continuation/no-wind (known-procedure 4)]
|
||||||
[unsafe-add-post-custodian-shutdown (known-procedure 2)]
|
[unsafe-add-post-custodian-shutdown (known-procedure 2)]
|
||||||
|
[unsafe-add-collect-callbacks (known-procedure 4)]
|
||||||
[unsafe-box*-cas! (known-procedure 8)]
|
[unsafe-box*-cas! (known-procedure 8)]
|
||||||
[unsafe-bytes-length (known-procedure/succeeds 2)]
|
[unsafe-bytes-length (known-procedure/succeeds 2)]
|
||||||
[unsafe-bytes-ref (known-procedure 4)]
|
[unsafe-bytes-ref (known-procedure 4)]
|
||||||
|
@ -123,6 +124,7 @@
|
||||||
[unsafe-port->file-descriptor (known-procedure 2)]
|
[unsafe-port->file-descriptor (known-procedure 2)]
|
||||||
[unsafe-port->socket (known-procedure 2)]
|
[unsafe-port->socket (known-procedure 2)]
|
||||||
[unsafe-register-process-global (known-procedure 4)]
|
[unsafe-register-process-global (known-procedure 4)]
|
||||||
|
[unsafe-remove-collect-callbacks (known-procedure 2)]
|
||||||
[unsafe-s16vector-ref (known-procedure 4)]
|
[unsafe-s16vector-ref (known-procedure 4)]
|
||||||
[unsafe-s16vector-set! (known-procedure 8)]
|
[unsafe-s16vector-set! (known-procedure 8)]
|
||||||
[unsafe-set-box! (known-procedure 4)]
|
[unsafe-set-box! (known-procedure 4)]
|
||||||
|
|
|
@ -453,6 +453,8 @@
|
||||||
make-phantom-bytes
|
make-phantom-bytes
|
||||||
set-phantom-bytes!
|
set-phantom-bytes!
|
||||||
set-garbage-collect-notify! ; not exported to Racket
|
set-garbage-collect-notify! ; not exported to Racket
|
||||||
|
unsafe-add-collect-callbacks
|
||||||
|
unsafe-remove-collect-callbacks
|
||||||
|
|
||||||
;; not the same as Racket will executors:
|
;; not the same as Racket will executors:
|
||||||
(rename
|
(rename
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
[(zero? (bitwise-and c collect-generation-radix-mask))
|
[(zero? (bitwise-and c collect-generation-radix-mask))
|
||||||
(loop (bitwise-arithmetic-shift-right c log-collect-generation-radix) (add1 gen))]
|
(loop (bitwise-arithmetic-shift-right c log-collect-generation-radix) (add1 gen))]
|
||||||
[else gen]))])])
|
[else gen]))])])
|
||||||
|
(run-collect-callbacks car)
|
||||||
(collect gen)
|
(collect gen)
|
||||||
(let ([post-allocated (bytes-allocated)])
|
(let ([post-allocated (bytes-allocated)])
|
||||||
(when (= gen (collect-maximum-generation))
|
(when (= gen (collect-maximum-generation))
|
||||||
|
@ -59,7 +60,8 @@
|
||||||
(garbage-collect-notify gen
|
(garbage-collect-notify gen
|
||||||
pre-allocated pre-allocated+overhead pre-time pre-cpu-time
|
pre-allocated pre-allocated+overhead pre-time pre-cpu-time
|
||||||
post-allocated (current-memory-bytes) (real-time) (cpu-time)))
|
post-allocated (current-memory-bytes) (real-time) (cpu-time)))
|
||||||
(poll-foreign-guardian))))
|
(poll-foreign-guardian)
|
||||||
|
(run-collect-callbacks cdr))))
|
||||||
|
|
||||||
(define collect-garbage
|
(define collect-garbage
|
||||||
(case-lambda
|
(case-lambda
|
||||||
|
@ -295,3 +297,90 @@
|
||||||
(check who phantom-bytes? phantom-bstr)
|
(check who phantom-bytes? phantom-bstr)
|
||||||
(check who exact-nonnegative-integer? k)
|
(check who exact-nonnegative-integer? k)
|
||||||
(phantom-bytes-size-set! phantom-bstr k))
|
(phantom-bytes-size-set! phantom-bstr k))
|
||||||
|
|
||||||
|
;; ----------------------------------------
|
||||||
|
|
||||||
|
;; List of (cons <pre> <post>)
|
||||||
|
(define collect-callbacks '())
|
||||||
|
|
||||||
|
(define (unsafe-add-collect-callbacks pre post)
|
||||||
|
(let ([p (cons pre post)])
|
||||||
|
(with-interrupts-disabled
|
||||||
|
(set! collect-callbacks (cons p collect-callbacks)))
|
||||||
|
p))
|
||||||
|
|
||||||
|
(define (unsafe-remove-collect-callbacks p)
|
||||||
|
(with-interrupts-disabled
|
||||||
|
(set! collect-callbacks (#%remq p collect-callbacks))))
|
||||||
|
|
||||||
|
(define (run-collect-callbacks sel)
|
||||||
|
(let loop ([l collect-callbacks])
|
||||||
|
(unless (null? l)
|
||||||
|
(let ([v (sel (car l))])
|
||||||
|
(let loop ([i 0] [save #f])
|
||||||
|
(unless (fx= i (#%vector-length v))
|
||||||
|
(loop (fx+ i 1)
|
||||||
|
(run-one-collect-callback (#%vector-ref v i) save sel))))
|
||||||
|
(loop (cdr l))))))
|
||||||
|
|
||||||
|
(define-syntax (osapi-foreign-procedure stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(_ s ...)
|
||||||
|
(case (machine-type)
|
||||||
|
[(a6nt ta6nt i3nt ti3nt) #'(foreign-procedure _stdcall s ...)]
|
||||||
|
[else #'(foreign-procedure s ...)])]))
|
||||||
|
|
||||||
|
;; This is an inconvenient callback interface, certainly, but it
|
||||||
|
;; accomodates a limitatuon of the traditional Racket implementation
|
||||||
|
(define (run-one-collect-callback v save sel)
|
||||||
|
(let ([protocol (#%vector-ref v 0)]
|
||||||
|
[proc (cpointer-address (#%vector-ref v 1))]
|
||||||
|
[ptr (lambda (i)
|
||||||
|
(cpointer*-address (#%vector-ref v (fx+ 2 i))))]
|
||||||
|
[val (lambda (i)
|
||||||
|
(#%vector-ref v (fx+ 2 i)))])
|
||||||
|
(case protocol
|
||||||
|
[(int->void)
|
||||||
|
((foreign-procedure proc (int) void) (val 0))
|
||||||
|
save]
|
||||||
|
[(ptr_ptr_ptr_int->void)
|
||||||
|
((foreign-procedure proc (void* void* void* int) void) (ptr 0) (ptr 1) (ptr 2) (val 3))
|
||||||
|
save]
|
||||||
|
[(ptr_ptr->save)
|
||||||
|
((foreign-procedure proc (void* void*) void*) (ptr 0) (ptr 1))]
|
||||||
|
[(save!_ptr->void)
|
||||||
|
(and save (not (eqv? save 0))
|
||||||
|
((foreign-procedure proc (void* void*) void*) save (ptr 0))
|
||||||
|
save)]
|
||||||
|
[(ptr_ptr_ptr->void)
|
||||||
|
((foreign-procedure proc (void* void* void*) void) (ptr 0) (ptr 1) (ptr 2))
|
||||||
|
save]
|
||||||
|
[(ptr_ptr_float->void)
|
||||||
|
((foreign-procedure proc (void* void* float) void) (ptr 0) (ptr 1) (val 2))
|
||||||
|
save]
|
||||||
|
[(ptr_ptr_double->void)
|
||||||
|
((foreign-procedure proc (void* void* double) void) (ptr 0) (ptr 1) (val 2))
|
||||||
|
save]
|
||||||
|
[(float_float_float_float->void)
|
||||||
|
((foreign-procedure proc (float float float float) void) (val 0) (val 1) (val 2) (val 3))
|
||||||
|
save]
|
||||||
|
[(ptr_ptr_ptr_int_int_int_int_int_int_int_int_int->void)
|
||||||
|
((foreign-procedure proc (void* void* void* int int int int int int int int int) void)
|
||||||
|
(ptr 0) (ptr 2) (ptr 2)
|
||||||
|
(val 3) (val 4) (val 5) (val 6)
|
||||||
|
(val 7) (val 8) (val 9) (val 10) (val 11))
|
||||||
|
save]
|
||||||
|
[(osapi_ptr_ptr->void)
|
||||||
|
((osapi-foreign-procedure proc (void* void*) void) (ptr 0) (ptr 1))
|
||||||
|
save]
|
||||||
|
[(osapi_ptr_int->void)
|
||||||
|
((osapi-foreign-procedure proc (void* int) void) (ptr 0) (val 1))
|
||||||
|
save]
|
||||||
|
[(osapi_ptr_int_int_int_int_ptr_int_int_long->void)
|
||||||
|
((osapi-foreign-procedure proc (void* int int int int void* int int long) void)
|
||||||
|
(ptr 0) (val 1) (val 2) (val 3) (val 4)
|
||||||
|
(ptr 5) (val 6) (val 7) (val 8))
|
||||||
|
save]
|
||||||
|
[else
|
||||||
|
(eprintf "unrecognized collect-callback protocol: ~s\n" protocol)
|
||||||
|
save])))
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#define USE_COMPILED_STARTUP 1
|
#define USE_COMPILED_STARTUP 1
|
||||||
|
|
||||||
#define EXPECTED_PRIM_COUNT 1435
|
#define EXPECTED_PRIM_COUNT 1437
|
||||||
|
|
||||||
#ifdef MZSCHEME_SOMETHING_OMITTED
|
#ifdef MZSCHEME_SOMETHING_OMITTED
|
||||||
# undef USE_COMPILED_STARTUP
|
# undef USE_COMPILED_STARTUP
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
consistently.)
|
consistently.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MZSCHEME_VERSION "7.0.0.8"
|
#define MZSCHEME_VERSION "7.0.0.9"
|
||||||
|
|
||||||
#define MZSCHEME_VERSION_X 7
|
#define MZSCHEME_VERSION_X 7
|
||||||
#define MZSCHEME_VERSION_Y 0
|
#define MZSCHEME_VERSION_Y 0
|
||||||
#define MZSCHEME_VERSION_Z 0
|
#define MZSCHEME_VERSION_Z 0
|
||||||
#define MZSCHEME_VERSION_W 8
|
#define MZSCHEME_VERSION_W 9
|
||||||
|
|
||||||
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
||||||
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
||||||
|
|
|
@ -347,6 +347,9 @@ static Scheme_Object *unsafe_make_os_semaphore(int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *unsafe_os_semaphore_wait(int argc, Scheme_Object *argv[]);
|
static Scheme_Object *unsafe_os_semaphore_wait(int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *unsafe_os_semaphore_post(int argc, Scheme_Object *argv[]);
|
static Scheme_Object *unsafe_os_semaphore_post(int argc, Scheme_Object *argv[]);
|
||||||
|
|
||||||
|
static Scheme_Object *unsafe_add_collect_callbacks(int argc, Scheme_Object *argv[]);
|
||||||
|
static Scheme_Object *unsafe_remove_collect_callbacks(int argc, Scheme_Object *argv[]);
|
||||||
|
|
||||||
static Scheme_Object *make_plumber(int argc, Scheme_Object *argv[]);
|
static Scheme_Object *make_plumber(int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *plumber_p(int argc, Scheme_Object *argv[]);
|
static Scheme_Object *plumber_p(int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *plumber_flush_all(int argc, Scheme_Object *argv[]);
|
static Scheme_Object *plumber_flush_all(int argc, Scheme_Object *argv[]);
|
||||||
|
@ -675,6 +678,9 @@ scheme_init_unsafe_thread (Scheme_Startup_Env *env)
|
||||||
ADD_PRIM_W_ARITY("unsafe-make-os-semaphore", unsafe_make_os_semaphore, 0, 0, env);
|
ADD_PRIM_W_ARITY("unsafe-make-os-semaphore", unsafe_make_os_semaphore, 0, 0, env);
|
||||||
ADD_PRIM_W_ARITY("unsafe-os-semaphore-wait", unsafe_os_semaphore_wait, 1, 1, env);
|
ADD_PRIM_W_ARITY("unsafe-os-semaphore-wait", unsafe_os_semaphore_wait, 1, 1, env);
|
||||||
ADD_PRIM_W_ARITY("unsafe-os-semaphore-post", unsafe_os_semaphore_post, 1, 1, env);
|
ADD_PRIM_W_ARITY("unsafe-os-semaphore-post", unsafe_os_semaphore_post, 1, 1, env);
|
||||||
|
|
||||||
|
ADD_PRIM_W_ARITY("unsafe-add-collect-callbacks", unsafe_add_collect_callbacks, 2, 2, env);
|
||||||
|
ADD_PRIM_W_ARITY("unsafe-remove-collect-callbacks", unsafe_remove_collect_callbacks, 1, 1, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scheme_init_thread_places(void) {
|
void scheme_init_thread_places(void) {
|
||||||
|
@ -8747,6 +8753,18 @@ void scheme_remove_gc_callback(Scheme_Object *key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *unsafe_add_collect_callbacks(int argc, Scheme_Object *argv[])
|
||||||
|
{
|
||||||
|
return scheme_add_gc_callback(argv[0], argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *unsafe_remove_collect_callbacks(int argc, Scheme_Object *argv[])
|
||||||
|
{
|
||||||
|
scheme_remove_gc_callback(argv[0]);
|
||||||
|
return scheme_void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
# define mzOSAPI WINAPI
|
# define mzOSAPI WINAPI
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in New Issue
Block a user