int main(int argc, char **argv) { struct NaClApp state, *nap = &state; struct SystemManifest sys_mft; struct GioMemoryFileSnapshot main_file; struct NaClPerfCounter time_all_main; /* zerovm initialization */ memset(nap, 0, sizeof *nap); nap->system_manifest = &sys_mft; memset(nap->system_manifest, 0, sizeof *nap->system_manifest); gnap = nap; ParseCommandLine(nap, argc, argv); NaClSignalHandlerInit(); NaClTimeInit(); NaClSyscallTableInit(); NaClPerfCounterCtor(&time_all_main, "SelMain"); /* initialize mem_map and set nap fields to default values */ ZLOGFAIL(NaClAppCtor(nap) == 0, EFAULT, "Error while constructing app state"); /* We use the signal handler to verify a signal took place. */ if(nap->skip_qualification == 0) NaClRunSelQualificationTests(); /* Remove the signal handler if we are not using it. */ if(nap->handle_signals == 0) { NaClSignalHandlerFini(); NaClSignalAssertNoHandlers(); /* Sanity check. */ } #define PERF_CNT(str) \ NaClPerfCounterMark(&time_all_main, str);\ NaClPerfCounterIntervalLast(&time_all_main); /* read nexe into memory */ ZLOGFAIL(0 == GioMemoryFileSnapshotCtor(&main_file, nap->system_manifest->nexe), ENOENT, "Cannot open '%s'. %s", nap->system_manifest->nexe, strerror(errno)); PERF_CNT("SnapshotNaclFile"); /* validate given nexe (ensure that text segment is safe) */ ValidateNexe(nap); /* validate nexe structure (check elf header and segments) */ ZLOGS(LOG_DEBUG, "Loading nacl file %s", nap->system_manifest->nexe); NaClAppLoadFile((struct Gio *) &main_file, nap); PERF_CNT("AppLoadEnd"); if(-1 == (*((struct Gio *)&main_file)->vtbl->Close)((struct Gio *)&main_file)) ZLOG(LOG_ERROR, "Error while closing '%s'", nap->system_manifest->nexe); (*((struct Gio *) &main_file)->vtbl->Dtor)((struct Gio *) &main_file); if(nap->quit_after_load) NaClExit(0); /* setup zerovm from manifest */ SystemManifestCtor(nap); /* needs dyn_array initialized */ /* "defence in depth" call */ LastDefenseLine(nap); /* start accounting */ AccountingCtor(nap); /* Make sure all the file buffers are flushed before entering the nexe */ fflush((FILE*) NULL); /* set user code trap() exit location and switch to the user code */ PERF_CNT("CreateMainThread"); if(setjmp(user_exit) == 0) ZLOGFAIL(!NaClCreateMainThread(nap), EFAULT, "switching to nexe failed"); SetExitState(OK_STATE); PERF_CNT("WaitForMainThread"); PERF_CNT("SelMainEnd"); /* zerovm exit with finalization, report and stuff */ NaClExit(0); /* Unreachable, but having the return prevents a compiler error. */ return -1; }
bool Message_Statics::receive_and_handle_one_message(bool wait) { Squeak_Interpreter* const interp = The_Squeak_Interpreter(); const int rank_on_threads_or_zero_on_processes = interp->rank_on_threads_or_zero_on_processes(); // Without this check, if the spin request has already been received, // any message received below could have roots that would be missed by GC -- dmu 10/1/10 interp->safepoint_tracker->spin_if_safepoint_requested(); abstractMessage_class* buffered_msg; Logical_Core* buffer_owner; messages msg_type_or_encoded_acking_type; messages msg_type; for (;;) { // added this loop and pass in false to receiver prims below in order to do timeout checks const bool do_timeout_checks = true; // tried false but no speedup loading image -- dmu 6/10 u_int64 start = OS_Interface::get_cycle_count(); buffered_msg = (abstractMessage_class*)Message_Queue::buffered_receive_from_anywhere(wait && !do_timeout_checks, &buffer_owner, interp->my_core()); u_int64 end = OS_Interface::get_cycle_count(); Message_Stats::record_buffered_recieve(rank_on_threads_or_zero_on_processes, end - start); msg_type_or_encoded_acking_type = buffered_msg == NULL ? noMessage : buffered_msg->header; msg_type = is_encoded_for_ack(msg_type_or_encoded_acking_type) ? ackMessage : msg_type_or_encoded_acking_type; # if Check_Reliable_At_Most_Once_Message_Delivery if (buffered_msg) Message_Stats::check_received_transmission_sequence_number(msg_type, buffered_msg->transmission_serial_number, buffered_msg->sender); # endif if (msg_type_or_encoded_acking_type != noMessage) { PERF_CNT(interp, count_received_intercore_messages()); if (Collect_Receive_Message_Statistics) Message_Stats::collect_receive_msg_stats(msg_type_or_encoded_acking_type); break; } Timeout_Timer::check_all(); if (!wait) return false; } Message_Or_Ack_Request* matching_msg_or_ack_request = Message_Or_Ack_Request::find(msg_type_or_encoded_acking_type); Message_Or_Ack_Request* matching_msg_request = msg_type == ackMessage ? NULL : matching_msg_or_ack_request; # define MAKE_CASE(name, superclass, constructor_formals, superconstructor_actuals, constructor_body, class_body, ack_setting, safepoint_delay_setting) \ case name: { \ name##_class local_buf(&The_Receive_Marker); \ name##_class* final_dest = matching_msg_request != NULL ? (name##_class*)matching_msg_request->buf_or_nil_for_ack : &local_buf; \ /* Used to try to not copy the buffer, but if handle_me ends up receiving another msg from sender, such as doAllRootsHere, causes problems. Be simple, even if slower -- Ungar 1/10 */ \ *final_dest = *(name##_class*)buffered_msg; \ buffer_owner->message_queue.release_oldest_buffer(buffered_msg); \ final_dest->handle_me_and_ack(); \ \ break; \ } switch (msg_type) { default: { fatal("bad message"); return false; } /* all other messages */ FOR_ALL_MESSAGES_DO(MAKE_CASE) } # undef MAKE_CASE interp->safepoint_tracker->spin_if_safepoint_requested(); // xxxxxx right place for a spin? if (matching_msg_or_ack_request != NULL) matching_msg_or_ack_request->is_fulfilled = true; last_msg_type = msg_type; // for debugging return true; }