diff --git a/src/racket/src/places.c b/src/racket/src/places.c index b3ddd54280..16fcfe2935 100644 --- a/src/racket/src/places.c +++ b/src/racket/src/places.c @@ -1,4 +1,3 @@ - #include "schpriv.h" /* READ ONLY SHARABLE GLOBALS */ @@ -18,7 +17,6 @@ static Scheme_Object *scheme_place(int argc, Scheme_Object *args[]); static Scheme_Object *scheme_place_wait(int argc, Scheme_Object *args[]); static Scheme_Object *scheme_place_sleep(int argc, Scheme_Object *args[]); static Scheme_Object *scheme_place_p(int argc, Scheme_Object *args[]); -static Scheme_Object *scheme_places_deep_copy_in_master(Scheme_Object *so); static Scheme_Object *scheme_place_send(int argc, Scheme_Object *args[]); static Scheme_Object *scheme_place_recv(int argc, Scheme_Object *args[]); static Scheme_Object *scheme_place_channel_p(int argc, Scheme_Object *args[]); @@ -31,8 +29,11 @@ static Scheme_Place_Bi_Channel *scheme_place_bi_peer_channel_create(Scheme_Place static int scheme_place_channel_ready(Scheme_Object *so); -static void scheme_place_async_send(Scheme_Place_Async_Channel *ch, Scheme_Object *o); -static Scheme_Object *scheme_place_async_recv(Scheme_Place_Async_Channel *ch); +static void scheme_place_async_send(Scheme_Place_Async_Channel *ch, Scheme_Object *o, void *msg_memory); +static Scheme_Object *scheme_place_async_recv(Scheme_Place_Async_Channel *ch, void **msg_memory); + +static Scheme_Object *scheme_places_deep_copy_to_master(Scheme_Object *so); +/* Scheme_Object *scheme_places_deep_copy(Scheme_Object *so); */ #if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) static Scheme_Object *scheme_places_deep_copy_worker(Scheme_Object *so, Scheme_Hash_Table *ht); @@ -166,9 +167,9 @@ Scheme_Object *scheme_place(int argc, Scheme_Object *args[]) { if (argc == 2) { Scheme_Object *so; - so = scheme_places_deep_copy_in_master(args[0]); + so = scheme_places_deep_copy_to_master(args[0]); place_data->module = so; - so = scheme_places_deep_copy_in_master(args[1]); + so = scheme_places_deep_copy_to_master(args[1]); place_data->function = so; place_data->ready = ready; @@ -186,7 +187,7 @@ Scheme_Object *scheme_place(int argc, Scheme_Object *args[]) { } collection_paths = scheme_current_library_collection_paths(0, NULL); - collection_paths = scheme_places_deep_copy_in_master(collection_paths); + collection_paths = scheme_places_deep_copy_to_master(collection_paths); place_data->current_library_collection_paths = collection_paths; /* create new place */ @@ -478,7 +479,9 @@ void scheme_done_with_process_id(int pid, int is_group) static void got_sigchld() XFORM_SKIP_PROC { - write(2, "SIGCHLD handler called (some thread has SIGCHLD unblocked)\n", 59); + if(-1 == write(2, "SIGCHLD handler called (some thread has SIGCHLD unblocked)\n", 59)) { + + } } void scheme_places_block_child_signal() XFORM_SKIP_PROC @@ -879,6 +882,9 @@ Scheme_Object *scheme_places_deep_copy_worker(Scheme_Object *so, Scheme_Hash_Tab } #endif + +#if 0 +/* unused code, may be useful when/if we revive shared symbol and prefab key tables */ Scheme_Struct_Type *scheme_make_prefab_struct_type_in_master(Scheme_Object *base, Scheme_Object *parent, int num_fields, @@ -915,6 +921,7 @@ Scheme_Struct_Type *scheme_make_prefab_struct_type_in_master(Scheme_Object *base return stype; } +#endif static void *place_start_proc(void *data_arg) { void *stack_base; @@ -1002,7 +1009,7 @@ static void *place_start_proc_after_stack(void *data_arg, void *stack_base) { Scheme_Hash_Table *force_hash(Scheme_Object *so); # endif -Scheme_Object *scheme_places_deep_copy_in_master(Scheme_Object *so) { +Scheme_Object *scheme_places_deep_copy_to_master(Scheme_Object *so) { #if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) Scheme_Object *o; void *original_gc; @@ -1010,21 +1017,127 @@ Scheme_Object *scheme_places_deep_copy_in_master(Scheme_Object *so) { ht = force_hash(so); -# ifdef MZ_PRECISE_GC original_gc = GC_switch_to_master_gc(); scheme_start_atomic(); -# endif + o = scheme_places_deep_copy_worker(so, ht); -# ifdef MZ_PRECISE_GC + scheme_end_atomic_no_swap(); GC_switch_back_from_master(original_gc); -# endif return o; #else return so; #endif } +Scheme_Object *scheme_places_deserialize_worker(Scheme_Object *so) +{ + Scheme_Object *new_so = so; + if (SCHEME_INTP(so)) { + return so; + } + switch (so->type) { + case scheme_true_type: + case scheme_false_type: + case scheme_null_type: + /* place_bi_channels are allocated in the master and can be passed along as is */ + case scheme_place_bi_channel_type: + case scheme_char_type: + case scheme_rational_type: + case scheme_float_type: + case scheme_double_type: + case scheme_complex_type: + case scheme_char_string_type: + case scheme_byte_string_type: + case scheme_unix_path_type: + case scheme_flvector_type: + new_so = so; + break; + case scheme_symbol_type: + scheme_log_abort("scheme_symbol_type: shouldn't be seen during deserialization step"); + break; + case scheme_serialized_symbol_type: + new_so = scheme_intern_exact_symbol(SCHEME_BYTE_STR_VAL(so), SCHEME_BYTE_STRLEN_VAL(so)); + break; + case scheme_pair_type: + { + Scheme_Object *tmp; + tmp = scheme_places_deserialize_worker(SCHEME_CAR(so)); + SCHEME_CAR(so) = tmp; + tmp = scheme_places_deserialize_worker(SCHEME_CDR(so)); + SCHEME_CDR(so) = tmp; + new_so = so; + } + break; + case scheme_vector_type: + { + long i; + long size = SCHEME_VEC_SIZE(so); + for (i = 0; i num_slots; + stype = scheme_lookup_prefab_type(SCHEME_CDR(st->prefab_key), size); + nst = (Scheme_Structure*) scheme_make_blank_prefab_struct_instance(stype); + for (i = 0; i slots[i]); + nst->slots[i] = tmp; + } + new_so = (Scheme_Object*)nst; + } + break; + + case scheme_resolved_module_path_type: + default: + scheme_log_abort("cannot deserialize object"); + abort(); + break; + } + return new_so; +} + +Scheme_Object *scheme_places_serialize(Scheme_Object *so, void **msg_memory) { +#if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) + Scheme_Object *new_so; + Scheme_Object *tmp; + GC_create_message_allocator(); + new_so = scheme_places_deep_copy(so); + tmp = GC_finish_message_allocator(); + (*msg_memory) = tmp; + return new_so; +#else + return so; +#endif +} + +Scheme_Object *scheme_places_deserialize(Scheme_Object *so, void *msg_memory) { +#if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) + Scheme_Object *new_so; + new_so = scheme_places_deserialize_worker(so); + GC_adopt_message_allocator(msg_memory); + return new_so; +#else + return so; +#endif +} + Scheme_Object *scheme_place_send(int argc, Scheme_Object *args[]) { if (argc == 2) { Scheme_Object *mso; @@ -1035,8 +1148,11 @@ Scheme_Object *scheme_place_send(int argc, Scheme_Object *args[]) { else { ch = (Scheme_Place_Bi_Channel *)args[0]; } - mso = scheme_places_deep_copy_in_master(args[1]); - scheme_place_async_send((Scheme_Place_Async_Channel *) ch->sendch, mso); + { + void *msg_memory; + mso = scheme_places_serialize(args[1], &msg_memory); + scheme_place_async_send((Scheme_Place_Async_Channel *) ch->sendch, mso, msg_memory); + } } else { scheme_wrong_count_m("place-channel-send", 1, 2, argc, args, 0); @@ -1054,8 +1170,11 @@ Scheme_Object *scheme_place_recv(int argc, Scheme_Object *args[]) { else { ch = (Scheme_Place_Bi_Channel *) args[0]; } - mso = scheme_place_async_recv((Scheme_Place_Async_Channel *) ch->recvch); - return scheme_places_deep_copy(mso); + { + void *msg_memory; + mso = scheme_place_async_recv((Scheme_Place_Async_Channel *) ch->recvch, &msg_memory); + return scheme_places_deserialize(mso, msg_memory); + } } else { scheme_wrong_count_m("place-channel-recv", 1, 2, argc, args, 0); @@ -1127,7 +1246,7 @@ void force_hash_worker(Scheme_Object *so, Scheme_Hash_Table *ht) long i; long size = SCHEME_VEC_SIZE(so); for (i = 0; i so.type = scheme_place_async_channel_type; ch->in = 0; @@ -1212,6 +1333,7 @@ Scheme_Place_Async_Channel *scheme_place_async_channel_create() { ch->size = 8; mzrt_mutex_create(&ch->lock); ch->msgs = msgs; + ch->msg_memory = msg_memory; ch->wakeup_signal = NULL; return ch; } @@ -1261,32 +1383,40 @@ static Scheme_Object *scheme_place_channel_p(int argc, Scheme_Object *args[]) return SAME_TYPE(SCHEME_TYPE(args[0]), scheme_place_bi_channel_type) ? scheme_true : scheme_false; } -void scheme_place_async_send(Scheme_Place_Async_Channel *ch, Scheme_Object *o) { +static void scheme_place_async_send(Scheme_Place_Async_Channel *ch, Scheme_Object *o, void *msg_memory) { int cnt; mzrt_mutex_lock(ch->lock); { cnt = ch->count; if (ch->count == ch->size) { /* GROW QUEUE */ Scheme_Object **new_msgs; + void **new_msg_memory; - new_msgs = GC_master_malloc(sizeof(Scheme_Object*) *2); + new_msgs = GC_master_malloc(sizeof(Scheme_Object*) * ch->size * 2); + new_msg_memory = GC_master_malloc(sizeof(void*) * ch->size * 2); if (ch->out < ch->in) { memcpy(new_msgs, ch->msgs + ch->out, sizeof(Scheme_Object *) * (ch->in - ch->out)); + memcpy(new_msg_memory, ch->msg_memory + ch->out, sizeof(void*) * (ch->in - ch->out)); } else { int s1 = (ch->size - ch->out); memcpy(new_msgs, ch->msgs + ch->out, sizeof(Scheme_Object *) * s1); memcpy(new_msgs + s1, ch->msgs, sizeof(Scheme_Object *) * ch->in); + + memcpy(new_msg_memory, ch->msg_memory + ch->out, sizeof(void*) * s1); + memcpy(new_msg_memory + s1, ch->msg_memory, sizeof(void*) * ch->in); } ch->msgs = new_msgs; + ch->msg_memory = new_msg_memory; ch->in = ch->size; ch->out = 0; ch->size *= 2; } ch->msgs[ch->in] = o; + ch->msg_memory[ch->in] = msg_memory; ++ch->count; ch->in = (++ch->in % ch->size); } @@ -1320,14 +1450,18 @@ static int scheme_place_channel_ready(Scheme_Object *so) { return scheme_place_async_ch_ready((Scheme_Place_Async_Channel *) ch->recvch); } -Scheme_Object *scheme_place_async_recv(Scheme_Place_Async_Channel *ch) { +static Scheme_Object *scheme_place_async_recv(Scheme_Place_Async_Channel *ch, void **msg_memory) { Scheme_Object *msg = NULL; while(1) { mzrt_mutex_lock(ch->lock); { if (ch->count > 0) { /* GET MSG */ msg = ch->msgs[ch->out]; + *msg_memory = ch->msg_memory[ch->out]; + ch->msgs[ch->out] = NULL; + ch->msg_memory[ch->out] = NULL; + --ch->count; ch->out = (++ch->out % ch->size); } diff --git a/src/racket/src/schpriv.h b/src/racket/src/schpriv.h index 3b71f0f25e..75ddbd2cfc 100644 --- a/src/racket/src/schpriv.h +++ b/src/racket/src/schpriv.h @@ -3540,6 +3540,7 @@ typedef struct Scheme_Place_Async_Channel { mzrt_mutex *lock; #endif Scheme_Object **msgs; + void **msg_memory; void *wakeup_signal; } Scheme_Place_Async_Channel;