Skip to content

Commit b93a9dc

Browse files
committed
Add forking support
1 parent eae75e1 commit b93a9dc

File tree

8 files changed

+67
-3
lines changed

8 files changed

+67
-3
lines changed

Diff for: gc.c

+21
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,9 @@ typedef struct gc_function_map {
680680
// Object ID
681681
VALUE (*object_id)(void *objspace_ptr, VALUE obj);
682682
VALUE (*object_id_to_ref)(void *objspace_ptr, VALUE object_id);
683+
// Forking
684+
void (*before_fork)(void *objspace_ptr);
685+
void (*after_fork)(void *objspace_ptr, rb_pid_t pid);
683686
// Statistics
684687
VALUE (*set_measure_total_time)(void *objspace_ptr, VALUE flag);
685688
VALUE (*get_measure_total_time)(void *objspace_ptr);
@@ -810,6 +813,9 @@ ruby_external_gc_init(void)
810813
// Object ID
811814
load_external_gc_func(object_id);
812815
load_external_gc_func(object_id_to_ref);
816+
// Forking
817+
load_external_gc_func(before_fork);
818+
load_external_gc_func(after_fork);
813819
// Statistics
814820
load_external_gc_func(set_measure_total_time);
815821
load_external_gc_func(get_measure_total_time);
@@ -888,6 +894,9 @@ ruby_external_gc_init(void)
888894
// Object ID
889895
# define rb_gc_impl_object_id rb_gc_functions.object_id
890896
# define rb_gc_impl_object_id_to_ref rb_gc_functions.object_id_to_ref
897+
// Forking
898+
# define rb_gc_impl_before_fork rb_gc_functions.before_fork
899+
# define rb_gc_impl_after_fork rb_gc_functions.after_fork
891900
// Statistics
892901
# define rb_gc_impl_set_measure_total_time rb_gc_functions.set_measure_total_time
893902
# define rb_gc_impl_get_measure_total_time rb_gc_functions.get_measure_total_time
@@ -4374,6 +4383,18 @@ rb_obj_info_dump_loc(VALUE obj, const char *file, int line, const char *func)
43744383
fprintf(stderr, "<OBJ_INFO:%s@%s:%d> %s\n", func, file, line, rb_raw_obj_info(buff, 0x100, obj));
43754384
}
43764385

4386+
void
4387+
rb_gc_before_fork(void)
4388+
{
4389+
rb_gc_impl_before_fork(rb_gc_get_objspace());
4390+
}
4391+
4392+
void
4393+
rb_gc_after_fork(rb_pid_t pid)
4394+
{
4395+
rb_gc_impl_after_fork(rb_gc_get_objspace(), pid);
4396+
}
4397+
43774398
/*
43784399
* Document-module: ObjectSpace
43794400
*

Diff for: gc/default.c

+3
Original file line numberDiff line numberDiff line change
@@ -9347,6 +9347,9 @@ gc_malloc_allocations(VALUE self)
93479347
}
93489348
#endif
93499349

9350+
void rb_gc_impl_before_fork(void *objspace_ptr) { /* no-op */ }
9351+
void rb_gc_impl_after_fork(void *objspace_ptr, rb_pid_t pid) { /* no-op */ }
9352+
93509353
void *
93519354
rb_gc_impl_objspace_alloc(void)
93529355
{

Diff for: gc/gc_impl.h

+3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ GC_IMPL_FN void rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr);
8484
// Object ID
8585
GC_IMPL_FN VALUE rb_gc_impl_object_id(void *objspace_ptr, VALUE obj);
8686
GC_IMPL_FN VALUE rb_gc_impl_object_id_to_ref(void *objspace_ptr, VALUE object_id);
87+
// Forking
88+
GC_IMPL_FN void rb_gc_impl_before_fork(void *objspace_ptr);
89+
GC_IMPL_FN void rb_gc_impl_after_fork(void *objspace_ptr, rb_pid_t pid);
8790
// Statistics
8891
GC_IMPL_FN VALUE rb_gc_impl_set_measure_total_time(void *objspace_ptr, VALUE flag);
8992
GC_IMPL_FN VALUE rb_gc_impl_get_measure_total_time(void *objspace_ptr);

Diff for: gc/mmtk.c

+16-2
Original file line numberDiff line numberDiff line change
@@ -748,13 +748,13 @@ rb_gc_impl_mark_maybe(void *objspace_ptr, VALUE obj)
748748
void
749749
rb_gc_impl_mark_weak(void *objspace_ptr, VALUE *ptr)
750750
{
751-
mmtk_mark_weak((const MMTk_ObjectReference *)ptr);
751+
mmtk_mark_weak((MMTk_ObjectReference *)ptr);
752752
}
753753

754754
void
755755
rb_gc_impl_remove_weak(void *objspace_ptr, VALUE parent_obj, VALUE *ptr)
756756
{
757-
mmtk_remove_weak((const MMTk_ObjectReference *)ptr);
757+
mmtk_remove_weak((MMTk_ObjectReference *)ptr);
758758
}
759759

760760
// Compaction
@@ -1080,6 +1080,20 @@ rb_gc_impl_object_id_to_ref(void *objspace_ptr, VALUE object_id)
10801080
}
10811081
}
10821082

1083+
// Forking
1084+
1085+
void
1086+
rb_gc_impl_before_fork(void *objspace_ptr)
1087+
{
1088+
mmtk_before_fork();
1089+
}
1090+
1091+
void
1092+
rb_gc_impl_after_fork(void *objspace_ptr, rb_pid_t pid)
1093+
{
1094+
mmtk_after_fork(rb_gc_get_ractor_newobj_cache());
1095+
}
1096+
10831097
// Statistics
10841098
VALUE rb_gc_impl_set_measure_total_time(void *objspace_ptr, VALUE flag) { }
10851099
VALUE rb_gc_impl_get_measure_total_time(void *objspace_ptr) { }

Diff for: gc/mmtk.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ void mmtk_post_alloc(MMTk_Mutator *mutator,
127127

128128
void mmtk_add_obj_free_candidate(MMTk_ObjectReference object);
129129

130-
void mmtk_mark_weak(const MMTk_ObjectReference *ptr);
130+
void mmtk_mark_weak(MMTk_ObjectReference *ptr);
131131

132132
void mmtk_remove_weak(const MMTk_ObjectReference *ptr);
133133

@@ -141,6 +141,10 @@ struct MMTk_RawVecOfObjRef mmtk_get_all_obj_free_candidates(void);
141141

142142
void mmtk_free_raw_vec_of_obj_ref(struct MMTk_RawVecOfObjRef raw_vec);
143143

144+
void mmtk_before_fork(void);
145+
146+
void mmtk_after_fork(MMTk_VMThread tls);
147+
144148
size_t mmtk_total_bytes(void);
145149

146150
size_t mmtk_used_bytes(void);

Diff for: gc/mmtk/src/api.rs

+13
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,19 @@ pub extern "C" fn mmtk_free_raw_vec_of_obj_ref(raw_vec: RawVecOfObjRef) {
193193
unsafe { raw_vec.into_vec() };
194194
}
195195

196+
// =============== Forking ===============
197+
198+
#[no_mangle]
199+
pub extern "C" fn mmtk_before_fork() {
200+
mmtk().prepare_to_fork();
201+
binding().join_all_gc_threads();
202+
}
203+
204+
#[no_mangle]
205+
pub extern "C" fn mmtk_after_fork(tls: VMThread) {
206+
mmtk().after_fork(tls);
207+
}
208+
196209
// =============== Statistics ===============
197210

198211
#[no_mangle]

Diff for: internal/gc.h

+3
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ void rb_gc_ref_update_table_values_only(st_table *tbl);
213213

214214
void rb_gc_initial_stress_set(VALUE flag);
215215

216+
void rb_gc_before_fork(void);
217+
void rb_gc_after_fork(rb_pid_t pid);
218+
216219
#define rb_gc_mark_and_move_ptr(ptr) do { \
217220
VALUE _obj = (VALUE)*(ptr); \
218221
rb_gc_mark_and_move(&_obj); \

Diff for: process.c

+3
Original file line numberDiff line numberDiff line change
@@ -1676,12 +1676,15 @@ after_exec(void)
16761676
static void
16771677
before_fork_ruby(void)
16781678
{
1679+
rb_gc_before_fork();
16791680
before_exec();
16801681
}
16811682

16821683
static void
16831684
after_fork_ruby(rb_pid_t pid)
16841685
{
1686+
rb_gc_after_fork(pid);
1687+
16851688
if (pid == 0) {
16861689
// child
16871690
clear_pid_cache();

0 commit comments

Comments
 (0)