Merge branch 'master' of git:plt
This commit is contained in:
commit
3f4f013a7b
|
@ -80,8 +80,8 @@ This file sets up the right lexical environment to invoke the tools that want to
|
||||||
|
|
||||||
;; these two definitions are a hack. They give bindings for the drracket: based names that
|
;; these two definitions are a hack. They give bindings for the drracket: based names that
|
||||||
;; appear in the source of language-object-contract.rkt.
|
;; appear in the source of language-object-contract.rkt.
|
||||||
(define drracket:language:capability-registered? drscheme:language:capability-registered?)
|
(define (drracket:language:capability-registered? . args) (apply drscheme:language:capability-registered? args))
|
||||||
(define drracket:language:get-capability-contract drscheme:language:get-capability-contract)
|
(define (drracket:language:get-capability-contract . args) (apply drscheme:language:get-capability-contract args))
|
||||||
|
|
||||||
;; invoke-drs-tool : unit/sig string -> (values (-> void) (-> void))
|
;; invoke-drs-tool : unit/sig string -> (values (-> void) (-> void))
|
||||||
;; invokes the tools and returns the two phase thunks.
|
;; invokes the tools and returns the two phase thunks.
|
||||||
|
|
|
@ -111,31 +111,26 @@ all of the names in the tools library, for use defining keybindings
|
||||||
|
|
||||||
Specifically, it sets these parameters:
|
Specifically, it sets these parameters:
|
||||||
@itemize[
|
@itemize[
|
||||||
@item{ @racket[current-namespace] has been set to a newly
|
@item{@racket[current-namespace] has been set to a newly
|
||||||
created empty namespace. This namespace has the following modules
|
created empty namespace. This namespace has the following modules
|
||||||
copied (with @racket[namespace-attach-module])
|
copied (with @racket[namespace-attach-module])
|
||||||
from DrRacket's original namespace:
|
from DrRacket's original namespace:
|
||||||
@itemize[@item{@racket['mzscheme]}@item{@racket['mred]}]
|
@itemize[@item{@racket['mzscheme]}@item{@racket['mred]}]
|
||||||
}@item{
|
}
|
||||||
@racket[read-curly-brace-as-paren]
|
@item{@racket[read-curly-brace-as-paren]
|
||||||
is @racket[#t],
|
is @racket[#t]; }
|
||||||
}@item{
|
@item{@racket[read-square-bracket-as-paren]
|
||||||
@racket[read-square-bracket-as-paren]
|
is @racket[#t];}
|
||||||
is @racket[#t],
|
@item{@racket[error-print-width] is set to 250;}
|
||||||
}@item{
|
@item{@racket[current-ps-setup]
|
||||||
@racket[error-print-width] is set to 250.
|
|
||||||
}@item{
|
|
||||||
@racket[current-ps-setup]
|
|
||||||
is set to a newly created
|
is set to a newly created
|
||||||
@racket[ps-setup%]
|
@racket[ps-setup%]
|
||||||
object.
|
object;}
|
||||||
}@item{ The @racket[exit-handler] is set to
|
@item{the @racket[exit-handler] is set to
|
||||||
a parameter that kills the user's custodian.
|
a parameter that kills the user's custodian; and}
|
||||||
}@item{ The snip-class-list, returned by
|
@item{the snip-class-list, returned by
|
||||||
@racket[get-the-snip-class-list]
|
@racket[get-the-snip-class-list]
|
||||||
is initialized with all of the snipclasses in DrRacket's eventspace's snip-class-list.
|
is initialized with all of the snipclasses in DrRacket's eventspace's snip-class-list.}]})
|
||||||
|
|
||||||
}]})
|
|
||||||
|
|
||||||
(proc-doc/names
|
(proc-doc/names
|
||||||
drracket:eval:get-snip-classes
|
drracket:eval:get-snip-classes
|
||||||
|
@ -577,11 +572,10 @@ all of the names in the tools library, for use defining keybindings
|
||||||
((or/c string? false/c) . -> . (is-a?/c drracket:unit:frame%)))
|
((or/c string? false/c) . -> . (is-a?/c drracket:unit:frame%)))
|
||||||
(() (filename))
|
(() (filename))
|
||||||
|
|
||||||
@{Opens a DrRacket frame that displays @racket[filename],
|
@{Opens a DrRacket frame that displays
|
||||||
|
@racket[filename],
|
||||||
or nothing if @racket[filename] is @racket[#f] or not supplied.})
|
or nothing if @racket[filename] is @racket[#f] or not supplied.})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
;
|
;
|
||||||
;
|
;
|
||||||
|
@ -1124,8 +1118,7 @@ all of the names in the tools library, for use defining keybindings
|
||||||
(item @racket['key : contract = default]
|
(item @racket['key : contract = default]
|
||||||
"--- " desc ...)])])
|
"--- " desc ...)])])
|
||||||
(itemize
|
(itemize
|
||||||
@cap[drracket:check-syntax-button boolean? #t]{
|
@cap[drracket:check-syntax-button boolean? #t]{controls the visiblity of the check syntax button}
|
||||||
controls the visiblity of the check syntax button}
|
|
||||||
@cap[drracket:language-menu-title
|
@cap[drracket:language-menu-title
|
||||||
string?
|
string?
|
||||||
(string-constant scheme-menu-name)]{
|
(string-constant scheme-menu-name)]{
|
||||||
|
|
|
@ -201,11 +201,11 @@
|
||||||
[(drscheme:language:simple-settings-insert-newlines settings)
|
[(drscheme:language:simple-settings-insert-newlines settings)
|
||||||
(if (number? width)
|
(if (number? width)
|
||||||
(parameterize ([pretty-print-columns width])
|
(parameterize ([pretty-print-columns width])
|
||||||
(pretty-print converted-value port))
|
(pretty-write converted-value port))
|
||||||
(pretty-print converted-value port))]
|
(pretty-write converted-value port))]
|
||||||
[else
|
[else
|
||||||
(parameterize ([pretty-print-columns 'infinity])
|
(parameterize ([pretty-print-columns 'infinity])
|
||||||
(pretty-print converted-value port))
|
(pretty-write converted-value port))
|
||||||
(newline port)])))))
|
(newline port)])))))
|
||||||
settings
|
settings
|
||||||
width))
|
width))
|
||||||
|
|
|
@ -9,6 +9,11 @@
|
||||||
"../posn.ss"
|
"../posn.ss"
|
||||||
(for-syntax scheme/base))
|
(for-syntax scheme/base))
|
||||||
|
|
||||||
|
(define pp
|
||||||
|
(let ([pretty-print (lambda (v)
|
||||||
|
(pretty-write v))])
|
||||||
|
pretty-print))
|
||||||
|
|
||||||
(provide-and-document
|
(provide-and-document
|
||||||
procedures
|
procedures
|
||||||
|
|
||||||
|
@ -35,7 +40,7 @@
|
||||||
"to print the argument to stdout (without quotes on symbols and strings, etc.)")
|
"to print the argument to stdout (without quotes on symbols and strings, etc.)")
|
||||||
(write (any -> void)
|
(write (any -> void)
|
||||||
"to print the argument to stdout (in a traditional style that is somewhere between print and display)")
|
"to print the argument to stdout (in a traditional style that is somewhere between print and display)")
|
||||||
(pretty-print (any -> void)
|
((pp pretty-print) (any -> void)
|
||||||
"like write, but with standard newlines and indentation")
|
"like write, but with standard newlines and indentation")
|
||||||
(printf (string any ... -> void)
|
(printf (string any ... -> void)
|
||||||
"to format the rest of the arguments according to the first argument and print it to stdout")
|
"to format the rest of the arguments according to the first argument and print it to stdout")
|
||||||
|
|
|
@ -636,6 +636,13 @@ path/s is either such a string or a list of them.
|
||||||
"collects/ffi/examples/tcl.rkt" drdr:command-line "mzc ~s"
|
"collects/ffi/examples/tcl.rkt" drdr:command-line "mzc ~s"
|
||||||
"collects/ffi/examples/xmmsctrl.rkt" drdr:command-line ""
|
"collects/ffi/examples/xmmsctrl.rkt" drdr:command-line ""
|
||||||
"collects/ffi/examples/xosd.rkt" drdr:command-line "mzc ~s"
|
"collects/ffi/examples/xosd.rkt" drdr:command-line "mzc ~s"
|
||||||
|
"collects/ffi/examples/use-c-printf.rkt" drdr:command-line "mzc -k ~s"
|
||||||
|
"collects/ffi/examples/use-esd.rkt" drdr:command-line "mzc ~s"
|
||||||
|
"collects/ffi/examples/use-magick.rkt" drdr:command-line "mzc ~s"
|
||||||
|
"collects/ffi/examples/use-sndfile.rkt" drdr:command-line "mzc ~s"
|
||||||
|
"collects/ffi/examples/use-tcl.rkt" drdr:command-line "mzc ~s"
|
||||||
|
"collects/ffi/examples/use-xmmsctrl.rkt" drdr:command-line ""
|
||||||
|
"collects/ffi/examples/use-xosd.rkt" drdr:command-line "mzc ~s"
|
||||||
"collects/ffi/magick.rkt" drdr:command-line "mzc ~s"
|
"collects/ffi/magick.rkt" drdr:command-line "mzc ~s"
|
||||||
"collects/ffi/unsafe/objc.rkt" drdr:command-line "mzc ~s"
|
"collects/ffi/unsafe/objc.rkt" drdr:command-line "mzc ~s"
|
||||||
"collects/ffi/private/objc-doc-unsafe.rkt" drdr:command-line "mzc ~s"
|
"collects/ffi/private/objc-doc-unsafe.rkt" drdr:command-line "mzc ~s"
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
[(_ name)
|
[(_ name)
|
||||||
(string? (syntax-e #'name))
|
(string? (syntax-e #'name))
|
||||||
(let ([name (syntax-e #'name)])
|
(let ([name (syntax-e #'name)])
|
||||||
(with-syntax ([rx (regexp (regexp-quote (format "^drracket:~a:" name)))])
|
(with-syntax ([rx (regexp (format "^~a" (regexp-quote (format "drracket:~a:" name))))])
|
||||||
#'(include-previously-extracted scribblings/tools/tool-lib-extracts rx)))]))
|
#'(include-previously-extracted scribblings/tools/tool-lib-extracts rx)))]))
|
||||||
|
|
||||||
(provide docs-get/extend)
|
(provide docs-get/extend)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
(load-relative "editor.ss")
|
(load-relative "editor.rkt")
|
||||||
(load-relative "paramz.ss")
|
(load-relative "paramz.rkt")
|
||||||
(load-relative "dc.ss")
|
(load-relative "dc.rkt")
|
||||||
(load-relative "windowing.ss")
|
(load-relative "windowing.rkt")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
(load-relative "loadtest.ss")
|
(load-relative "loadtest.rkt")
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; DC Tests ;;
|
;; DC Tests ;;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
(load-relative "loadtest.ss")
|
(load-relative "loadtest.rkt")
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Editor Tests ;;
|
;; Editor Tests ;;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
(let ([f (load-relative "gui-main.ss")])
|
(let ([f (load-relative "gui-main.rkt")])
|
||||||
(thread
|
(thread
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(f "New" "Save" mred:console-frame%))))
|
(f "New" "Save" mred:console-frame%))))
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
(unless (with-handlers ([exn:fail? (lambda (x) #f)])
|
(unless (with-handlers ([exn:fail? (lambda (x) #f)])
|
||||||
(namespace-variable-binding 'SECTION)
|
(namespace-variable-binding 'SECTION)
|
||||||
#t)
|
#t)
|
||||||
(load-relative "testing.ss"))
|
(load-relative "testing.rkt"))
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
(load-relative "loadtest.ss")
|
(load-relative "loadtest.rkt")
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Yield Tests ;;
|
;; Yield Tests ;;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
(load-relative "loadtest.ss")
|
(load-relative "loadtest.rkt")
|
||||||
|
|
||||||
(define shorter? #t)
|
(define shorter? #t)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
(require (lib "scheme-lexer.ss" "syntax-color") scheme/gui/base)
|
(require (lib "scheme-lexer.ss" "syntax-color") scheme/gui/base)
|
||||||
|
|
||||||
(define path (build-path (collection-path "framework" "private") "frame.ss"))
|
(define path (build-path (collection-path "framework" "private") "frame.rkt"))
|
||||||
|
|
||||||
(define content
|
(define content
|
||||||
(with-input-from-file path
|
(with-input-from-file path
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
(load-relative "loadtest.ss")
|
(load-relative "loadtest.rkt")
|
||||||
|
|
||||||
(require mrlib/cache-image-snip
|
(require mrlib/cache-image-snip
|
||||||
mzlib/unit)
|
mzlib/unit)
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#reader(lib "embed-me11-rd.ss" "tests" "mzscheme")
|
#reader(lib "embed-me11-rd.ss" "tests" "racket")
|
||||||
"It goes to ~a!\n"
|
"It goes to ~a!\n"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#lang scheme
|
#lang racket
|
||||||
(require scheme/system)
|
(require racket/system)
|
||||||
|
|
||||||
#|
|
#|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ the `x' binding is part of the deeper meta-continuation when `ak'
|
||||||
is captured, but it is delimited inside the binding, so `x'
|
is captured, but it is delimited inside the binding, so `x'
|
||||||
should not be reated in `ak'.
|
should not be reated in `ak'.
|
||||||
|
|
||||||
The test is implemented using `dump-memory-stats' in another mzscheme
|
The test is implemented using `dump-memory-stats' in another racket
|
||||||
process.
|
process.
|
||||||
|
|
||||||
|#
|
|#
|
||||||
|
@ -19,7 +19,7 @@ process.
|
||||||
(let ([f (find-executable-path (find-system-path 'exec-file) #f)])
|
(let ([f (find-executable-path (find-system-path 'exec-file) #f)])
|
||||||
(let ([p (open-output-bytes)])
|
(let ([p (open-output-bytes)])
|
||||||
(parameterize ([current-error-port p])
|
(parameterize ([current-error-port p])
|
||||||
(system* f "-l" "tests/mzscheme/prompt-sfs" "sub"))
|
(system* f "-l" "tests/racket/prompt-sfs" "sub"))
|
||||||
(unless (regexp-match? #rx"<will-executor>: +1 +" (get-output-bytes p))
|
(unless (regexp-match? #rx"<will-executor>: +1 +" (get-output-bytes p))
|
||||||
(error "wrong output")
|
(error "wrong output")
|
||||||
(exit 1))))
|
(exit 1))))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
(load-relative "../mzscheme/loadtest.ss")
|
(load-relative "../racket/loadtest.rkt")
|
||||||
(require mzlib/class
|
(require mzlib/class
|
||||||
syntax-color/paren-tree)
|
syntax-color/paren-tree)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
(load-relative "../mzscheme/loadtest.ss")
|
(load-relative "../racket/loadtest.rkt")
|
||||||
(require mzlib/class
|
(require mzlib/class
|
||||||
syntax-color/token-tree)
|
syntax-color/token-tree)
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
(load-relative "../mzscheme/loadtest.ss")
|
(load-relative "../racket/loadtest.rkt")
|
||||||
|
|
||||||
(Section 'srcloc)
|
(Section 'srcloc)
|
||||||
(require unstable/srcloc)
|
(require unstable/srcloc)
|
||||||
(require scheme/shared)
|
(require racket/shared)
|
||||||
|
|
||||||
(test #t source-location? #f)
|
(test #t source-location? #f)
|
||||||
(test #f source-location? #t)
|
(test #f source-location? #t)
|
||||||
|
|
|
@ -413,6 +413,11 @@ GC2_EXTERN void GC_construct_child_gc();
|
||||||
Creates a new place specific GC and links to the master GC.
|
Creates a new place specific GC and links to the master GC.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
GC2_EXTERN void GC_destruct_child_gc();
|
||||||
|
/*
|
||||||
|
Destroys a place specific GC once the place has finished.
|
||||||
|
*/
|
||||||
|
|
||||||
GC2_EXTERN void *GC_switch_to_master_gc();
|
GC2_EXTERN void *GC_switch_to_master_gc();
|
||||||
/*
|
/*
|
||||||
Switches to the master GC
|
Switches to the master GC
|
||||||
|
|
|
@ -146,11 +146,11 @@ static void GCVERBOSEprintf(const char *fmt, ...) {
|
||||||
static void GCVERBOSEPAGE(const char *msg, mpage* page) {
|
static void GCVERBOSEPAGE(const char *msg, mpage* page) {
|
||||||
NewGC *gc = GC_get_GC();
|
NewGC *gc = GC_get_GC();
|
||||||
if(postmaster_and_master_gc(gc)) {
|
if(postmaster_and_master_gc(gc)) {
|
||||||
GCVERBOSEprintf("%s %p %p %p\n", msg, page, page->addr, (void*)((long)page->addr + real_page_size(page)));
|
GCVERBOSEprintf("%s %p: %p %p %p\n", msg, gc, page, page->addr, (void*)((long)page->addr + real_page_size(page)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# ifdef KILLING_DEBUG
|
# ifdef KILLING_DEBUG
|
||||||
static void killing_debug(NewGC *gc, void *info);
|
static void killing_debug(NewGC *gc, mpage *page, objhead *info);
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# define GCVERBOSEPAGE(msg, page) /* EMPTY */
|
# define GCVERBOSEPAGE(msg, page) /* EMPTY */
|
||||||
|
@ -1876,82 +1876,66 @@ void GC_write_barrier(void *p)
|
||||||
|
|
||||||
#ifdef MZ_USE_PLACES
|
#ifdef MZ_USE_PLACES
|
||||||
static void NewGCMasterInfo_initialize() {
|
static void NewGCMasterInfo_initialize() {
|
||||||
|
int i;
|
||||||
MASTERGCINFO = ofm_malloc_zero(sizeof(NewGCMasterInfo));
|
MASTERGCINFO = ofm_malloc_zero(sizeof(NewGCMasterInfo));
|
||||||
|
MASTERGCINFO->size = 32;
|
||||||
|
MASTERGCINFO->alive = 0;
|
||||||
|
MASTERGCINFO->ready = 0;
|
||||||
|
MASTERGCINFO->signal_fds = realloc(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size);
|
||||||
|
for (i=0; i < 32; i++ ) {
|
||||||
|
MASTERGCINFO->signal_fds[i] = (void *)-2;
|
||||||
|
}
|
||||||
mzrt_rwlock_create(&MASTERGCINFO->cangc);
|
mzrt_rwlock_create(&MASTERGCINFO->cangc);
|
||||||
mzrt_sema_create(&MASTERGCINFO->wait_sema, 0);
|
mzrt_sema_create(&MASTERGCINFO->wait_sema, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NewGCMasterInfo_cleanup() {
|
static void NewGCMasterInfo_cleanup() {
|
||||||
mzrt_rwlock_destroy(MASTERGCINFO->cangc);
|
mzrt_rwlock_destroy(MASTERGCINFO->cangc);
|
||||||
|
free(MASTERGCINFO->signal_fds);
|
||||||
free(MASTERGCINFO);
|
free(MASTERGCINFO);
|
||||||
MASTERGCINFO = NULL;
|
MASTERGCINFO = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NewGCMasterInfo_set_have_collected(NewGC *gc) {
|
|
||||||
MASTERGCINFO->have_collected[gc->place_id] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* signals every place to do a full gc at then end of
|
/* signals every place to do a full gc at then end of
|
||||||
garbage_collect the places will call
|
garbage_collect the places will call
|
||||||
wait_if_master_in_progress and
|
wait_if_master_in_progress and
|
||||||
rendezvous for a master gc */
|
rendezvous for a master gc */
|
||||||
|
/* this is only called from the master so the cangc lock should already be held */
|
||||||
static void master_collect_initiate() {
|
static void master_collect_initiate() {
|
||||||
if (MASTERGC->major_places_gc == 0) {
|
if (MASTERGC->major_places_gc == 0) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int maxid = MASTERGCINFO->next_GC_id;
|
int size = MASTERGCINFO->size;
|
||||||
|
int count = 0;
|
||||||
MASTERGC->major_places_gc = 1;
|
MASTERGC->major_places_gc = 1;
|
||||||
|
MASTERGCINFO->ready = 0;
|
||||||
|
|
||||||
for (i=1; i < maxid; i++) {
|
for (i=1; i < size; i++) {
|
||||||
void *signal_fd = MASTERGCINFO->signal_fds[i];
|
void *signal_fd = MASTERGCINFO->signal_fds[i];
|
||||||
MASTERGCINFO->have_collected[i] = -1;
|
if (signal_fd < (void*) -2) {
|
||||||
if (signal_fd >= 0 ) {
|
|
||||||
scheme_signal_received_at(signal_fd);
|
scheme_signal_received_at(signal_fd);
|
||||||
}
|
|
||||||
#if defined(DEBUG_GC_PAGES)
|
#if defined(DEBUG_GC_PAGES)
|
||||||
printf("%i SIGNALED BUT NOT COLLECTED\n", i);
|
printf("%i SIGNALED BUT NOT COLLECTED\n", i);
|
||||||
GCVERBOSEprintf("%i SIGNALED BUT NOT COLLECTED\n", i);
|
GCVERBOSEprintf("%i SIGNALED BUT NOT COLLECTED\n", i);
|
||||||
#endif
|
#endif
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
if (count == (MASTERGCINFO->alive -1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count != (MASTERGCINFO->alive -1)) {
|
||||||
|
printf("GC2 count != MASTERGCINFO->alive %i %li\n", count, MASTERGCINFO->alive);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#if defined(DEBUG_GC_PAGES)
|
||||||
|
printf("Woke up %i places for MASTER GC\n", count);
|
||||||
|
GCVERBOSEprintf("Woke up %i places for MASTER GC\n", count);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void collect_master() {
|
||||||
static void wait_if_master_in_progress(NewGC *gc) {
|
|
||||||
if (MASTERGC->major_places_gc == 1) {
|
|
||||||
int last_one_here = 1;
|
|
||||||
|
|
||||||
mzrt_rwlock_wrlock(MASTERGCINFO->cangc);
|
|
||||||
GC_LOCK_DEBUG("MGCLOCK GC_switch_to_master_gc\n");
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
int maxid = MASTERGCINFO->next_GC_id;
|
|
||||||
|
|
||||||
NewGCMasterInfo_set_have_collected(gc);
|
|
||||||
for (i=1; i < maxid; i++) {
|
|
||||||
int have_collected = MASTERGCINFO->have_collected[i];
|
|
||||||
if (have_collected == 1) {
|
|
||||||
#if defined(DEBUG_GC_PAGES)
|
|
||||||
printf("%i READY\n", i);
|
|
||||||
GCVERBOSEprintf("%i READY\n", i);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#if defined(DEBUG_GC_PAGES)
|
|
||||||
printf("%i SIGNALED BUT NOT COLLECTED\n", i);
|
|
||||||
GCVERBOSEprintf("%i SIGNALED BUT NOT COLLECTED\n", i);
|
|
||||||
#endif
|
|
||||||
last_one_here = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (last_one_here) {
|
|
||||||
NewGC *saved_gc;
|
NewGC *saved_gc;
|
||||||
|
|
||||||
GC_LOCK_DEBUG("UNMGCLOCK GC_switch_to_master_gc\n");
|
|
||||||
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
|
||||||
|
|
||||||
|
|
||||||
saved_gc = GC_switch_to_master_gc();
|
saved_gc = GC_switch_to_master_gc();
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_GC_PAGES)
|
#if defined(DEBUG_GC_PAGES)
|
||||||
|
@ -1967,44 +1951,105 @@ static void wait_if_master_in_progress(NewGC *gc) {
|
||||||
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int maxid = MASTERGCINFO->next_GC_id;
|
int alive = MASTERGCINFO->alive;
|
||||||
/* wake everyone back up */
|
/* wake everyone back up, except MASTERGC and ourself */
|
||||||
for (i=2; i < maxid; i++) {
|
for (i=2; i < alive; i++) {
|
||||||
mzrt_sema_post(MASTERGCINFO->wait_sema);
|
mzrt_sema_post(MASTERGCINFO->wait_sema);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GC_switch_back_from_master(saved_gc);
|
GC_switch_back_from_master(saved_gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wait_if_master_in_progress(NewGC *gc) {
|
||||||
|
int last_one_here = -1;
|
||||||
|
mzrt_rwlock_wrlock(MASTERGCINFO->cangc);
|
||||||
|
GC_LOCK_DEBUG("MGCLOCK wait_if_master_in_progress\n");
|
||||||
|
{
|
||||||
|
if (MASTERGC->major_places_gc == 1) {
|
||||||
|
MASTERGCINFO->ready++;
|
||||||
|
#if defined(DEBUG_GC_PAGES)
|
||||||
|
printf("%i READY\n", gc->place_id);
|
||||||
|
GCVERBOSEprintf("%i READY\n", i);
|
||||||
|
#endif
|
||||||
|
/* don't count MASTERGC*/
|
||||||
|
if ((MASTERGCINFO->alive -1) == MASTERGCINFO->ready) {
|
||||||
|
last_one_here = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GC_LOCK_DEBUG("UNMGCLOCK GC_switch_to_master_gc\n");
|
last_one_here = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
last_one_here = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GC_LOCK_DEBUG("UNMGCLOCK wait_if_master_in_progress\n");
|
||||||
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
||||||
|
|
||||||
/* wait on semaphonre */
|
switch(last_one_here) {
|
||||||
|
case -1:
|
||||||
|
/* master doesn't want to collect */
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
/* wait on semaphore */
|
||||||
mzrt_sema_wait(MASTERGCINFO->wait_sema);
|
mzrt_sema_wait(MASTERGCINFO->wait_sema);
|
||||||
}
|
break;
|
||||||
|
case 1:
|
||||||
|
/* Your the last one here. */
|
||||||
|
collect_master();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("GC2 wait_if_master_in_progress invalid case, unreachable\n");
|
||||||
|
abort();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NewGCMasterInfo_get_next_id(NewGC *newgc) {
|
/* MUST CALL WITH cangc lock */
|
||||||
int newid;
|
static long NewGCMasterInfo_find_free_id() {
|
||||||
/* this could just be an atomic op if we had those */
|
GC_ASSERT(MASTERGCINFO->live <= MASTERGCINFO->size);
|
||||||
/* waiting for other threads to finish a possible concurrent GC is not optimal*/
|
if ((MASTERGCINFO->alive + 1) == MASTERGCINFO->size) {
|
||||||
|
MASTERGCINFO->size++;
|
||||||
|
MASTERGCINFO->alive++;
|
||||||
|
MASTERGCINFO->signal_fds = realloc(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size);
|
||||||
|
return MASTERGCINFO->size - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i;
|
||||||
|
int size = MASTERGCINFO->size;
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
if (MASTERGCINFO->signal_fds[i] == (void*)-2) {
|
||||||
|
MASTERGCINFO->alive++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Error in MASTERGCINFO table\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NewGCMasterInfo_register_gc(NewGC *newgc) {
|
||||||
mzrt_rwlock_wrlock(MASTERGCINFO->cangc);
|
mzrt_rwlock_wrlock(MASTERGCINFO->cangc);
|
||||||
newid = MASTERGCINFO->next_GC_id++;
|
GC_LOCK_DEBUG("MGCLOCK NewGCMasterInfo_register_gc\n");
|
||||||
|
{
|
||||||
|
long newid = NewGCMasterInfo_find_free_id();
|
||||||
newgc->place_id = newid;
|
newgc->place_id = newid;
|
||||||
/* printf("ALLOCATED GC OID %li\n", newgc->place_id); */
|
|
||||||
MASTERGCINFO->have_collected = realloc(MASTERGCINFO->have_collected, sizeof(char) * MASTERGCINFO->next_GC_id);
|
|
||||||
MASTERGCINFO->signal_fds = realloc(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->next_GC_id);
|
|
||||||
MASTERGCINFO->have_collected[newid] = 0;
|
|
||||||
MASTERGCINFO->signal_fds[newid] = (void *)-1;
|
MASTERGCINFO->signal_fds[newid] = (void *)-1;
|
||||||
|
}
|
||||||
|
GC_LOCK_DEBUG("UNMGCLOCK NewGCMasterInfo_register_gc\n");
|
||||||
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GC_set_put_external_event_fd(void *fd) {
|
void GC_set_put_external_event_fd(void *fd) {
|
||||||
NewGC *gc = GC_get_GC();
|
NewGC *gc = GC_get_GC();
|
||||||
mzrt_rwlock_wrlock(MASTERGCINFO->cangc);
|
mzrt_rwlock_wrlock(MASTERGCINFO->cangc);
|
||||||
|
GC_LOCK_DEBUG("MGCLOCK GC_set_put_external_event_fd\n");
|
||||||
|
{
|
||||||
MASTERGCINFO->signal_fds[gc->place_id] = fd;
|
MASTERGCINFO->signal_fds[gc->place_id] = fd;
|
||||||
|
}
|
||||||
|
GC_LOCK_DEBUG("UNMGCLOCK GC_set_put_external_event_fd\n");
|
||||||
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2027,7 +2072,7 @@ static void NewGC_initialize(NewGC *newgc, NewGC *parentgc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MZ_USE_PLACES
|
#ifdef MZ_USE_PLACES
|
||||||
NewGCMasterInfo_get_next_id(newgc);
|
NewGCMasterInfo_register_gc(newgc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mark_stack_initialize(newgc);
|
mark_stack_initialize(newgc);
|
||||||
|
@ -2110,6 +2155,31 @@ void GC_construct_child_gc() {
|
||||||
newgc->primoridal_gc = MASTERGC;
|
newgc->primoridal_gc = MASTERGC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GC_destruct_child_gc() {
|
||||||
|
NewGC *gc = GC_get_GC();
|
||||||
|
int waiting = 0;
|
||||||
|
do {
|
||||||
|
|
||||||
|
mzrt_rwlock_wrlock(MASTERGCINFO->cangc);
|
||||||
|
GC_LOCK_DEBUG("MGCLOCK GC_destruct_child_gc\n");
|
||||||
|
waiting = MASTERGC->major_places_gc;
|
||||||
|
if (!waiting) {
|
||||||
|
MASTERGCINFO->signal_fds[gc->place_id] = (void *)-2;
|
||||||
|
gc->place_id = -1;
|
||||||
|
MASTERGCINFO->alive--;
|
||||||
|
}
|
||||||
|
GC_LOCK_DEBUG("UNMGCLOCK GC_destruct_child_gc\n");
|
||||||
|
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
||||||
|
|
||||||
|
|
||||||
|
if (waiting) {
|
||||||
|
garbage_collect(gc, 1, 0);
|
||||||
|
waiting = 1;
|
||||||
|
}
|
||||||
|
} while (waiting == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void save_globals_to_gc(NewGC *gc) {
|
static inline void save_globals_to_gc(NewGC *gc) {
|
||||||
gc->saved_GC_variable_stack = GC_variable_stack;
|
gc->saved_GC_variable_stack = GC_variable_stack;
|
||||||
gc->saved_GC_gen0_alloc_page_ptr = GC_gen0_alloc_page_ptr;
|
gc->saved_GC_gen0_alloc_page_ptr = GC_gen0_alloc_page_ptr;
|
||||||
|
@ -2156,7 +2226,7 @@ void *GC_switch_to_master_gc() {
|
||||||
|
|
||||||
/*obtain exclusive access to MASTERGC*/
|
/*obtain exclusive access to MASTERGC*/
|
||||||
mzrt_rwlock_wrlock(MASTERGCINFO->cangc);
|
mzrt_rwlock_wrlock(MASTERGCINFO->cangc);
|
||||||
GC_LOCK_DEBUG("MGCLOCK GC_switch_to_master_gc\n");
|
//GC_LOCK_DEBUG("MGCLOCK GC_switch_to_master_gc\n");
|
||||||
|
|
||||||
GC_set_GC(MASTERGC);
|
GC_set_GC(MASTERGC);
|
||||||
restore_globals_from_gc(MASTERGC);
|
restore_globals_from_gc(MASTERGC);
|
||||||
|
@ -2169,7 +2239,7 @@ void GC_switch_back_from_master(void *gc) {
|
||||||
save_globals_to_gc(MASTERGC);
|
save_globals_to_gc(MASTERGC);
|
||||||
|
|
||||||
/*release exclusive access to MASTERGC*/
|
/*release exclusive access to MASTERGC*/
|
||||||
GC_LOCK_DEBUG("UNMGCLOCK GC_switch_to_master_gc\n");
|
//GC_LOCK_DEBUG("UNMGCLOCK GC_switch_to_master_gc\n");
|
||||||
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
||||||
|
|
||||||
GC_set_GC(gc);
|
GC_set_GC(gc);
|
||||||
|
@ -2345,8 +2415,10 @@ void GC_mark2(const void *const_p, struct NewGC *gc)
|
||||||
page->live_size += ohead->size;
|
page->live_size += ohead->size;
|
||||||
record_backtrace(page, p);
|
record_backtrace(page, p);
|
||||||
push_ptr(gc, p);
|
push_ptr(gc, p);
|
||||||
} else GCDEBUG((DEBUGOUTF, "Not marking %p (it's old; %p / %i)\n",
|
}
|
||||||
p, page, page->previous_size));
|
else {
|
||||||
|
GCDEBUG((DEBUGOUTF, "Not marking %p (it's old; %p / %i)\n", p, page, page->previous_size));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* this is a generation 0 object. This means that we do have
|
/* this is a generation 0 object. This means that we do have
|
||||||
to do all of the above. Fun, fun, fun. */
|
to do all of the above. Fun, fun, fun. */
|
||||||
|
@ -3073,10 +3145,10 @@ static void fprintf_buffer(FILE* file, char* buf, int l) {
|
||||||
fprintf(file, "\n");
|
fprintf(file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fprintf_debug(NewGC *gc, const char *msg, objhead *info, FILE* file, int isgc) {
|
static void fprintf_debug(NewGC *gc, mpage *page, const char *msg, objhead *info, FILE* file, int isgc) {
|
||||||
if (!isgc || postmaster_and_master_gc(gc)) {
|
if (!isgc || postmaster_and_master_gc(gc)) {
|
||||||
Scheme_Object *obj = OBJHEAD_TO_OBJPTR(info);
|
Scheme_Object *obj = OBJHEAD_TO_OBJPTR(info);
|
||||||
fprintf(file, "%s %p ot %i it %i im %i is %i is >> 3 %i\n", msg, obj, obj->type, info->type, info->mark, info->size, info->size >> 3);
|
fprintf(file, "%s %p ot %i it %i im %i is %i is >> 3 %i %p %i\n", msg, obj, obj->type, info->type, info->mark, info->size, info->size >> 3, page, page->marked_on);
|
||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
case scheme_unix_path_type:
|
case scheme_unix_path_type:
|
||||||
if (pagemap_find_page(gc->page_maps, SCHEME_PATH_VAL(obj))) {
|
if (pagemap_find_page(gc->page_maps, SCHEME_PATH_VAL(obj))) {
|
||||||
|
@ -3091,7 +3163,9 @@ static void fprintf_debug(NewGC *gc, const char *msg, objhead *info, FILE* file,
|
||||||
break;
|
break;
|
||||||
case scheme_resolved_module_path_type:
|
case scheme_resolved_module_path_type:
|
||||||
if (pagemap_find_page(gc->page_maps, SCHEME_PTR_VAL(obj))) {
|
if (pagemap_find_page(gc->page_maps, SCHEME_PTR_VAL(obj))) {
|
||||||
fprintf_debug(gc, "RMP ", OBJPTR_TO_OBJHEAD(SCHEME_PTR_VAL(obj)), file, isgc);
|
/*
|
||||||
|
fprintf_debug(gc, page, "RMP ", OBJPTR_TO_OBJHEAD(SCHEME_PTR_VAL(obj)), file, isgc);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(file, "RMP %p already freed and out of bounds\n", SCHEME_PATH_VAL(obj));
|
fprintf(file, "RMP %p already freed and out of bounds\n", SCHEME_PATH_VAL(obj));
|
||||||
|
@ -3102,11 +3176,8 @@ static void fprintf_debug(NewGC *gc, const char *msg, objhead *info, FILE* file,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void killing_debug(NewGC *gc, void *info) {
|
static void killing_debug(NewGC *gc, mpage *page, objhead *info) {
|
||||||
fprintf_debug(gc, "killing", (objhead *) info, gcdebugOUT(), 1);
|
fprintf_debug(gc, page, "killing", info, gcdebugOUT(), 1);
|
||||||
}
|
|
||||||
static void marking_rmp_debug(NewGC *gc, void *info) {
|
|
||||||
fprintf_debug(gc, "marking rmp", (objhead *) info, gcdebugOUT(), 0);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3279,6 +3350,10 @@ static void repair_heap(NewGC *gc)
|
||||||
break;
|
break;
|
||||||
case PAGE_ATOMIC:
|
case PAGE_ATOMIC:
|
||||||
start += info->size;
|
start += info->size;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unhandled info->type %i\n", info->type);
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
info->mark = 0;
|
info->mark = 0;
|
||||||
#ifdef MZ_USE_PLACES
|
#ifdef MZ_USE_PLACES
|
||||||
|
@ -3286,7 +3361,7 @@ static void repair_heap(NewGC *gc)
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef KILLING_DEBUG
|
#ifdef KILLING_DEBUG
|
||||||
killing_debug(gc, info);
|
killing_debug(gc, page, info);
|
||||||
#endif
|
#endif
|
||||||
info->dead = 1;
|
info->dead = 1;
|
||||||
start += info->size;
|
start += info->size;
|
||||||
|
@ -3520,13 +3595,6 @@ static void garbage_collect(NewGC *gc, int force_full, int switching_master)
|
||||||
|
|
||||||
int next_gc_full;
|
int next_gc_full;
|
||||||
|
|
||||||
#ifdef MZ_USE_PLACES
|
|
||||||
if (postmaster_and_place_gc(gc)) {
|
|
||||||
mzrt_rwlock_rdlock(MASTERGCINFO->cangc);
|
|
||||||
/* printf("RD MGCLOCK garbage_collect %i\n", gc->place_id); */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
old_mem_use = gc->memory_in_use;
|
old_mem_use = gc->memory_in_use;
|
||||||
old_gen0 = gc->gen0.current_size;
|
old_gen0 = gc->gen0.current_size;
|
||||||
|
|
||||||
|
@ -3780,8 +3848,6 @@ static void garbage_collect(NewGC *gc, int force_full, int switching_master)
|
||||||
|
|
||||||
#ifdef MZ_USE_PLACES
|
#ifdef MZ_USE_PLACES
|
||||||
if (postmaster_and_place_gc(gc)) {
|
if (postmaster_and_place_gc(gc)) {
|
||||||
/* printf("UN RD MGCLOCK garbage_collect %i\n", gc->place_id); */
|
|
||||||
mzrt_rwlock_unlock(MASTERGCINFO->cangc);
|
|
||||||
if (gc->gc_full) {
|
if (gc->gc_full) {
|
||||||
wait_if_master_in_progress(gc);
|
wait_if_master_in_progress(gc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,8 +87,9 @@ typedef struct Page_Range {
|
||||||
|
|
||||||
#ifdef MZ_USE_PLACES
|
#ifdef MZ_USE_PLACES
|
||||||
typedef struct NewGCMasterInfo {
|
typedef struct NewGCMasterInfo {
|
||||||
unsigned short next_GC_id;
|
unsigned long size;
|
||||||
unsigned char *have_collected;
|
unsigned long alive;
|
||||||
|
unsigned long ready;
|
||||||
void **signal_fds;
|
void **signal_fds;
|
||||||
mzrt_rwlock *cangc;
|
mzrt_rwlock *cangc;
|
||||||
mzrt_sema *wait_sema;
|
mzrt_sema *wait_sema;
|
||||||
|
|
|
@ -50,8 +50,16 @@ void fault_handler(int sn, struct siginfo *si, void *ctx)
|
||||||
if (c == SEGV_MAPERR) {
|
if (c == SEGV_MAPERR) {
|
||||||
printf("SIGSEGV MAPERR si_code %i fault on addr %p\n", c, p);
|
printf("SIGSEGV MAPERR si_code %i fault on addr %p\n", c, p);
|
||||||
}
|
}
|
||||||
else {
|
if (c == 0 ) {
|
||||||
printf("SIGSEGV ?????? SI_CODE %i fault on addr %p\n", c, p);
|
/* I have now idea why this happens on linux */
|
||||||
|
/* supposedly its coming from the user via kill */
|
||||||
|
/* so just ignore it. */
|
||||||
|
printf("SIGSEGV SI_USER SI_CODE %i fault on addr %p\n", c, p);
|
||||||
|
printf("pid %i uid %i\n", si->si_pid, si->si_uid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (c == 128 ) {
|
||||||
|
printf("SIGSEGV SI_KERNEL SI_CODE %i fault on addr %p sent by kernel\n", c, p);
|
||||||
}
|
}
|
||||||
#if WAIT_FOR_GDB
|
#if WAIT_FOR_GDB
|
||||||
launchgdb();
|
launchgdb();
|
||||||
|
@ -67,10 +75,10 @@ void fault_handler(int sn, struct siginfo *si, void *ctx)
|
||||||
printf("ADDR %p OWNED BY MASTER %i\n", p, m);
|
printf("ADDR %p OWNED BY MASTER %i\n", p, m);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
printf("mprotect fault on %p\n", p);
|
printf("SIGSEGV SEGV_ACCERR SI_CODE %i fault on %p\n", c, p);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("?? %i fault on %p\n", si->si_code, p);
|
printf("SIGSEGV ???? SI_CODE %i fault on %p\n", c, p);
|
||||||
}
|
}
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
|
@ -567,6 +567,9 @@ void scheme_place_instance_destroy() {
|
||||||
#if defined(MZ_USE_PLACES)
|
#if defined(MZ_USE_PLACES)
|
||||||
scheme_kill_green_thread_timer();
|
scheme_kill_green_thread_timer();
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(MZ_PRECISE_GC) && defined(MZ_USE_PLACES)
|
||||||
|
GC_destruct_child_gc();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_kernel_env(void)
|
static void make_kernel_env(void)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user