level-2 finalization from ffi/unsafe and late-weak references
This commit is contained in:
parent
40a65a46d2
commit
d2275f4179
|
@ -16,7 +16,8 @@
|
||||||
_float _double _double*
|
_float _double _double*
|
||||||
_bool _pointer _gcpointer _scheme (rename-out [_scheme _racket]) _fpointer function-ptr
|
_bool _pointer _gcpointer _scheme (rename-out [_scheme _racket]) _fpointer function-ptr
|
||||||
memcpy memmove memset
|
memcpy memmove memset
|
||||||
malloc-immobile-cell free-immobile-cell)
|
malloc-immobile-cell free-immobile-cell
|
||||||
|
make-late-weak-box make-late-weak-hasheq)
|
||||||
|
|
||||||
(define-syntax define*
|
(define-syntax define*
|
||||||
(syntax-rules ()
|
(syntax-rules ()
|
||||||
|
@ -1477,6 +1478,8 @@
|
||||||
;; of will executor is provided by '#%foreign, and it doesn't get GC'ed if
|
;; of will executor is provided by '#%foreign, and it doesn't get GC'ed if
|
||||||
;; any finalizers are attached to it (while the normal kind can get GCed
|
;; any finalizers are attached to it (while the normal kind can get GCed
|
||||||
;; even if a thread that is otherwise inaccessible is blocked on the executor).
|
;; even if a thread that is otherwise inaccessible is blocked on the executor).
|
||||||
|
;; Also it registers level-2 finalizers (which are run after non-late weak
|
||||||
|
;; boxes are cleared).
|
||||||
(define killer-executor (make-stubborn-will-executor))
|
(define killer-executor (make-stubborn-will-executor))
|
||||||
(define killer-thread #f)
|
(define killer-thread #f)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
(provide allocator deallocator retainer
|
(provide allocator deallocator retainer
|
||||||
(rename-out [deallocator releaser]))
|
(rename-out [deallocator releaser]))
|
||||||
|
|
||||||
(define allocated (make-weak-hasheq))
|
(define allocated (make-late-weak-hasheq))
|
||||||
|
|
||||||
(define (deallocate v)
|
(define (deallocate v)
|
||||||
;; Called as a finalizer, we we assume that the
|
;; Called as a finalizer, we we assume that the
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
(tell
|
(tell
|
||||||
(let ([c (tell (tell NSCell alloc) initTextCell: #:type _NSString
|
(let ([c (tell (tell NSCell alloc) initTextCell: #:type _NSString
|
||||||
(if wx (send wx get-row row) "???"))]
|
(if wx (send wx get-row row) "???"))]
|
||||||
[font (send wx get-cell-font)])
|
[font (and wx (send wx get-cell-font))])
|
||||||
(when font
|
(when font
|
||||||
(tellv c setFont: font))
|
(tellv c setFont: font))
|
||||||
c)
|
c)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
(define source-dir (current-load-relative-directory))
|
(define source-dir (current-load-relative-directory))
|
||||||
|
|
||||||
(define num-times 8)
|
(define num-times 80)
|
||||||
(define num-threads 3)
|
(define num-threads 3)
|
||||||
|
|
||||||
(define dump-stats? #f)
|
(define dump-stats? #f)
|
||||||
|
@ -152,6 +152,7 @@
|
||||||
|
|
||||||
(when (and edit? insert?)
|
(when (and edit? insert?)
|
||||||
(let ([e edit])
|
(let ([e edit])
|
||||||
|
(send e begin-edit-sequence)
|
||||||
(when load-file?
|
(when load-file?
|
||||||
(send e load-file (build-path source-dir "mem.ss")))
|
(send e load-file (build-path source-dir "mem.ss")))
|
||||||
(let loop ([i 20])
|
(let loop ([i 20])
|
||||||
|
@ -163,7 +164,8 @@
|
||||||
(send e insert s))
|
(send e insert s))
|
||||||
(send e insert #\newline)
|
(send e insert #\newline)
|
||||||
(send e insert "done")
|
(send e insert "done")
|
||||||
(send e set-modified #f)))
|
(send e set-modified #f)
|
||||||
|
(send e end-edit-sequence)))
|
||||||
|
|
||||||
(when menus?
|
(when menus?
|
||||||
(let ([f (remember tag (make-object frame% "MB Frame 0"))])
|
(let ([f (remember tag (make-object frame% "MB Frame 0"))])
|
||||||
|
|
|
@ -3031,6 +3031,22 @@ static Scheme_Object *foreign_make_stubborn_will_executor(int argc, Scheme_Objec
|
||||||
}
|
}
|
||||||
#undef MYNAME
|
#undef MYNAME
|
||||||
|
|
||||||
|
/* (make-late-weak-box val) -> #<weak-box> */
|
||||||
|
#define MYNAME "make-late-weak-box"
|
||||||
|
static Scheme_Object *foreign_make_late_weak_box(int argc, Scheme_Object *argv[])
|
||||||
|
{
|
||||||
|
return scheme_make_late_weak_box(argv[0]);
|
||||||
|
}
|
||||||
|
#undef MYNAME
|
||||||
|
|
||||||
|
/* (make-late-weak-hasheq) -> #<hash> */
|
||||||
|
#define MYNAME "make-late-weak-hasheq"
|
||||||
|
static Scheme_Object *foreign_make_late_weak_hasheq(int argc, Scheme_Object *argv[])
|
||||||
|
{
|
||||||
|
return (Scheme_Object *)scheme_make_bucket_table(20, SCHEME_hash_late_weak_ptr);
|
||||||
|
}
|
||||||
|
#undef MYNAME
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void ctype_printer(Scheme_Object *ctype, int dis, Scheme_Print_Params *pp)
|
void ctype_printer(Scheme_Object *ctype, int dis, Scheme_Print_Params *pp)
|
||||||
|
@ -3201,6 +3217,10 @@ void scheme_init_foreign(Scheme_Env *env)
|
||||||
scheme_make_prim_w_arity(foreign_lookup_errno, "lookup-errno", 1, 1), menv);
|
scheme_make_prim_w_arity(foreign_lookup_errno, "lookup-errno", 1, 1), menv);
|
||||||
scheme_add_global("make-stubborn-will-executor",
|
scheme_add_global("make-stubborn-will-executor",
|
||||||
scheme_make_prim_w_arity(foreign_make_stubborn_will_executor, "make-stubborn-will-executor", 0, 0), menv);
|
scheme_make_prim_w_arity(foreign_make_stubborn_will_executor, "make-stubborn-will-executor", 0, 0), menv);
|
||||||
|
scheme_add_global("make-late-weak-box",
|
||||||
|
scheme_make_prim_w_arity(foreign_make_late_weak_box, "make-late-weak-box", 1, 1), menv);
|
||||||
|
scheme_add_global("make-late-weak-hasheq",
|
||||||
|
scheme_make_prim_w_arity(foreign_make_late_weak_hasheq, "make-late-weak-hasheq", 0, 0), menv);
|
||||||
s = scheme_intern_symbol("void");
|
s = scheme_intern_symbol("void");
|
||||||
t = (ctype_struct*)scheme_malloc_tagged(sizeof(ctype_struct));
|
t = (ctype_struct*)scheme_malloc_tagged(sizeof(ctype_struct));
|
||||||
t->so.type = ctype_tag;
|
t->so.type = ctype_tag;
|
||||||
|
@ -3501,6 +3521,10 @@ void scheme_init_foreign(Scheme_Env *env)
|
||||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "lookup-errno", 1, 1), menv);
|
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "lookup-errno", 1, 1), menv);
|
||||||
scheme_add_global("make-stubborn-will-executor",
|
scheme_add_global("make-stubborn-will-executor",
|
||||||
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "make-stubborn-will-executor", 0, 0), menv);
|
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "make-stubborn-will-executor", 0, 0), menv);
|
||||||
|
scheme_add_global("make-late-weak-box",
|
||||||
|
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "make-late-weak-box", 1, 1), menv);
|
||||||
|
scheme_add_global("make-late-weak-hasheq",
|
||||||
|
scheme_make_prim_w_arity((Scheme_Prim *)unimplemented, "make-late-weak-hasheq", 0, 0), menv);
|
||||||
scheme_add_global("_void", scheme_false, menv);
|
scheme_add_global("_void", scheme_false, menv);
|
||||||
scheme_add_global("_int8", scheme_false, menv);
|
scheme_add_global("_int8", scheme_false, menv);
|
||||||
scheme_add_global("_uint8", scheme_false, menv);
|
scheme_add_global("_uint8", scheme_false, menv);
|
||||||
|
|
|
@ -2387,6 +2387,16 @@ static void save_errno_values(int kind)
|
||||||
return scheme_make_stubborn_will_executor();
|
return scheme_make_stubborn_will_executor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (make-late-weak-box val) -> #<weak-box> */
|
||||||
|
@cdefine[make-late-weak-box 1]{
|
||||||
|
return scheme_make_late_weak_box(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (make-late-weak-hasheq) -> #<hash> */
|
||||||
|
@cdefine[make-late-weak-hasheq 0]{
|
||||||
|
return (Scheme_Object *)scheme_make_bucket_table(20, SCHEME_hash_late_weak_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void ctype_printer(Scheme_Object *ctype, int dis, Scheme_Print_Params *pp)
|
void ctype_printer(Scheme_Object *ctype, int dis, Scheme_Print_Params *pp)
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
["libglib-2.0-0.dll" 1110713]
|
["libglib-2.0-0.dll" 1110713]
|
||||||
["libgobject-2.0-0.dll" 316586]
|
["libgobject-2.0-0.dll" 316586]
|
||||||
["libgmodule-2.0-0.dll" 31692]
|
["libgmodule-2.0-0.dll" 31692]
|
||||||
["libpangocairo-1.0-0.dll" 95189]
|
["libpangocairo-1.0-0.dll" 94625]
|
||||||
["libpangowin32-1.0-0.dll" 102210]
|
["libpangowin32-1.0-0.dll" 102210]
|
||||||
["libpangoft2-1.0-0.dll" 679322])])
|
["libpangoft2-1.0-0.dll" 679322])])
|
||||||
(if (getenv "PLT_WIN_GTK")
|
(if (getenv "PLT_WIN_GTK")
|
||||||
|
|
|
@ -824,7 +824,8 @@ typedef struct Scheme_Bucket_Table
|
||||||
int size; /* power of 2 */
|
int size; /* power of 2 */
|
||||||
int count;
|
int count;
|
||||||
Scheme_Bucket **buckets;
|
Scheme_Bucket **buckets;
|
||||||
char weak, with_home;
|
char weak; /* 1 => normal weak, 2 => late weak */
|
||||||
|
char with_home;
|
||||||
void (*make_hash_indices)(void *v, long *h1, long *h2);
|
void (*make_hash_indices)(void *v, long *h1, long *h2);
|
||||||
int (*compare)(void *v1, void *v2);
|
int (*compare)(void *v1, void *v2);
|
||||||
Scheme_Object *mutex;
|
Scheme_Object *mutex;
|
||||||
|
@ -835,7 +836,8 @@ enum {
|
||||||
SCHEME_hash_string,
|
SCHEME_hash_string,
|
||||||
SCHEME_hash_ptr,
|
SCHEME_hash_ptr,
|
||||||
SCHEME_hash_bound_id,
|
SCHEME_hash_bound_id,
|
||||||
SCHEME_hash_weak_ptr
|
SCHEME_hash_weak_ptr,
|
||||||
|
SCHEME_hash_late_weak_ptr
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Scheme_Env Scheme_Env;
|
typedef struct Scheme_Env Scheme_Env;
|
||||||
|
|
|
@ -541,7 +541,12 @@ scheme_make_bucket_table (int size, int type)
|
||||||
table->buckets = ba;
|
table->buckets = ba;
|
||||||
}
|
}
|
||||||
|
|
||||||
table->weak = (type == SCHEME_hash_weak_ptr);
|
if (type == SCHEME_hash_weak_ptr)
|
||||||
|
table->weak = 1;
|
||||||
|
else if (type == SCHEME_hash_late_weak_ptr)
|
||||||
|
table->weak = 2;
|
||||||
|
else
|
||||||
|
table->weak = 0;
|
||||||
|
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
@ -714,15 +719,21 @@ get_bucket (Scheme_Bucket_Table *table, const char *key, int add, Scheme_Bucket
|
||||||
if (table->weak) {
|
if (table->weak) {
|
||||||
#ifdef MZ_PRECISE_GC
|
#ifdef MZ_PRECISE_GC
|
||||||
void *kb;
|
void *kb;
|
||||||
kb = GC_malloc_weak_box((void *)key, (void **)bucket, (void **)&bucket->val - (void **)bucket, 0);
|
kb = GC_malloc_weak_box((void *)key, (void **)bucket, (void **)&bucket->val - (void **)bucket,
|
||||||
|
(table->weak > 1));
|
||||||
bucket->key = (char *)kb;
|
bucket->key = (char *)kb;
|
||||||
#else
|
#else
|
||||||
char *kb;
|
char *kb;
|
||||||
kb = (char *)MALLOC_ONE_WEAK(void *);
|
kb = (char *)MALLOC_ONE_WEAK(void *);
|
||||||
bucket->key = kb;
|
bucket->key = kb;
|
||||||
*(void **)bucket->key = (void *)key;
|
*(void **)bucket->key = (void *)key;
|
||||||
|
if (table->weak > 1) {
|
||||||
|
scheme_late_weak_reference_indirect((void **)bucket->key, (void *)key);
|
||||||
|
scheme_late_weak_reference_indirect((void **)&bucket->val, (void *)key);
|
||||||
|
} else {
|
||||||
scheme_weak_reference_indirect((void **)bucket->key, (void *)key);
|
scheme_weak_reference_indirect((void **)bucket->key, (void *)key);
|
||||||
scheme_weak_reference_indirect((void **)&bucket->val, (void *)key);
|
scheme_weak_reference_indirect((void **)&bucket->val, (void *)key);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
} else
|
} else
|
||||||
bucket->key = (char *)key;
|
bucket->key = (char *)key;
|
||||||
|
|
|
@ -7371,14 +7371,15 @@ static Scheme_Object *register_will(int argc, Scheme_Object **argv)
|
||||||
scheme_wrong_type("will-register", "will-executor", 0, argc, argv);
|
scheme_wrong_type("will-register", "will-executor", 0, argc, argv);
|
||||||
scheme_check_proc_arity("will-register", 1, 2, argc, argv);
|
scheme_check_proc_arity("will-register", 1, 2, argc, argv);
|
||||||
|
|
||||||
if (((WillExecutor *)argv[0])->is_stubborn)
|
if (((WillExecutor *)argv[0])->is_stubborn) {
|
||||||
e = scheme_make_pair(argv[0], argv[2]);
|
e = scheme_make_pair(argv[0], argv[2]);
|
||||||
else {
|
scheme_add_finalizer(argv[1], activate_will, e);
|
||||||
|
} else {
|
||||||
/* If we lose track of the will executor, then drop the finalizer. */
|
/* If we lose track of the will executor, then drop the finalizer. */
|
||||||
e = scheme_make_ephemeron(argv[0], argv[2]);
|
e = scheme_make_ephemeron(argv[0], argv[2]);
|
||||||
|
scheme_add_scheme_finalizer(argv[1], activate_will, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme_add_scheme_finalizer(argv[1], activate_will, e);
|
|
||||||
|
|
||||||
return scheme_void;
|
return scheme_void;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user