示例#1
0
文件: sel_main.c 项目: vi4m/zerovm
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;
}
示例#2
0
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;
}