Пример #1
0
/**
 * \brief Blocks the current process until a communication is finished.
 * \param L a Lua state
 * \return number of values returned to Lua
 *
 * - Argument 1 (comm): a comm (previously created by isend or irecv)
 * - Argument 2 (number, optional): timeout (default is no timeout)
 * - Return values (task or nil + string): in case of success, returns the task
 * received if you are the receiver and nil if you are the sender. In case of
 * failure, returns nil plus an error string.
 */
static int l_comm_wait(lua_State* L) {

  msg_comm_t comm = sglua_check_comm(L, 1);
  double timeout = -1;
  if (lua_gettop(L) >= 2) {
    timeout = luaL_checknumber(L, 2);
  }
                                  /* comm ... */
  msg_error_t res = MSG_comm_wait(comm, timeout);

  if (res == MSG_OK) {
    msg_task_t task = MSG_comm_get_task(comm);
    if (MSG_task_get_sender(task) == MSG_process_self()) {
      /* I'm the sender */
      return 0;
    }
    else {
      /* I'm the receiver: find the Lua task from the C task */
      sglua_task_unregister(L, task);
                                  /* comm ... task */
      return 1;
    }
  }
  else {
    /* the communication has failed */
    lua_pushnil(L);
                                  /* comm ... nil */
    lua_pushstring(L, sglua_get_msg_error(res));
                                  /* comm ... nil error */
    return 2;
  }
}
Пример #2
0
msg_error_t peer_wait_for_message(peer_t peer)
{
  msg_error_t status;
  msg_comm_t comm = NULL;
  msg_task_t task = NULL;
  int idx = -1;
  int done = 0;

  while (!done) {
    comm = MSG_task_irecv(&task, peer->me);
    queue_pending_connection(comm, peer->pending_recvs);

    if ((idx = MSG_comm_waitany(peer->pending_recvs)) != -1) {
      comm = xbt_dynar_get_as(peer->pending_recvs, idx, msg_comm_t);
      status = MSG_comm_get_status(comm);
      XBT_DEBUG("peer_wait_for_message: error code = %d", status);
      xbt_assert(status == MSG_OK, "peer_wait_for_message() failed");

      task = MSG_comm_get_task(comm);
      MSG_comm_destroy(comm);
      xbt_dynar_cursor_rm(peer->pending_recvs, (unsigned int*)&idx);
      done = peer_execute_task(peer, task);

      task_message_delete(task);
      task = NULL;
    }
    process_pending_connections(peer->pending_sends);
  }

  return status;
}
Пример #3
0
/** Receiver function  */
int receiver(int argc, char *argv[])
{
  int id = -1;
  int i;
  char mailbox[80];
  xbt_dynar_t comms = xbt_dynar_new(sizeof(msg_comm_t), NULL);
  int tasks = atof(argv[2]);
  msg_task_t *task = xbt_new(msg_task_t, tasks);

  _XBT_GNUC_UNUSED int read;
  read = sscanf(argv[1], "%d", &id);
  xbt_assert(read, "Invalid argument %s\n", argv[1]);
  sprintf(mailbox, "receiver-%d", id);
  MSG_process_sleep(10);
  msg_comm_t res_irecv;
  for (i = 0; i < tasks; i++) {
    XBT_INFO("Wait to receive task %d", i);
    task[i] = NULL;
    res_irecv = MSG_task_irecv(&task[i], mailbox);
    xbt_dynar_push_as(comms, msg_comm_t, res_irecv);
  }

  /* Here we are waiting for the receiving of all communications */
  msg_task_t task_com;
  while (!xbt_dynar_is_empty(comms)) {
    _XBT_GNUC_UNUSED msg_error_t err;
    xbt_dynar_remove_at(comms, MSG_comm_waitany(comms), &res_irecv);
    task_com = MSG_comm_get_task(res_irecv);
    MSG_comm_destroy(res_irecv);
    XBT_INFO("Processing \"%s\"", MSG_task_get_name(task_com));
    MSG_task_execute(task_com);
    XBT_INFO("\"%s\" done", MSG_task_get_name(task_com));
    err = MSG_task_destroy(task_com);
    xbt_assert(err == MSG_OK, "MSG_task_destroy failed");
  }
  xbt_dynar_free(&comms);
  xbt_free(task);

  /* Here we tell to sender that all tasks are done */
  sprintf(mailbox, "finalize");
  res_irecv = MSG_task_isend(MSG_task_create(NULL, 0, 0, NULL), mailbox);
  MSG_comm_wait(res_irecv, -1);
  MSG_comm_destroy(res_irecv);
  XBT_INFO("I'm done. See you!");
  return 0;
}                               /* end_of_receiver */
Пример #4
0
static int receiver(int argc, char *argv[])
{
  xbt_assert(argc==3, "This function expects 2 parameters from the XML deployment file");
  int id = xbt_str_parse_int(argv[1], "ID should be numerical, not %s");
  int task_amount = xbt_str_parse_int(argv[2], "Invalid amount of tasks: %s");
  msg_task_t *tasks = xbt_new(msg_task_t, task_amount);
  xbt_dynar_t comms = xbt_dynar_new(sizeof(msg_comm_t), NULL);

  char mailbox[80];
  snprintf(mailbox,79, "receiver-%d", id);
   
  MSG_process_sleep(10);
  for (int i = 0; i < task_amount; i++) {
    XBT_INFO("Wait to receive task %d", i);
    tasks[i] = NULL;
    msg_comm_t comm = MSG_task_irecv(&tasks[i], mailbox);
    xbt_dynar_push_as(comms, msg_comm_t, comm);
  }

  /* Here we are waiting for the receiving of all communications */
  while (!xbt_dynar_is_empty(comms)) {
    msg_comm_t comm;
    // MSG_comm_waitany returns the rank of the comm that just ended. Remove it.
    xbt_dynar_remove_at(comms, MSG_comm_waitany(comms), &comm);
    msg_task_t task = MSG_comm_get_task(comm);
    MSG_comm_destroy(comm);
    XBT_INFO("Processing \"%s\"", MSG_task_get_name(task));
    MSG_task_execute(task);
    XBT_INFO("\"%s\" done", MSG_task_get_name(task));
    msg_error_t err = MSG_task_destroy(task);
    xbt_assert(err == MSG_OK, "MSG_task_destroy failed");
  }
  xbt_dynar_free(&comms);
  xbt_free(tasks);

  /* Here we tell to sender that all tasks are done */
  MSG_task_send(MSG_task_create(NULL, 0, 0, NULL), "finalize");
  XBT_INFO("I'm done. See you!");
  return 0;
}
Пример #5
0
/**
 * @brief Returns whether a communication is finished.
 *
 * Unlike wait(), This function always returns immediately.
 *
 * - Argument 1 (comm): a comm (previously created by isend or irecv)
 * - Return values (task/boolean or nil + string): if the communication is not
 * finished, return false. If the communication is finished and was successful,
 * returns the task received if you are the receiver or true if you are the
 * sender. If the communication is finished and has failed, returns nil
 * plus an error string.
 */
static int l_comm_test(lua_State* L) {

  msg_comm_t comm = sglua_check_comm(L, 1);
                                  /* comm ... */
  if (!MSG_comm_test(comm)) {
    /* not finished yet */
    lua_pushboolean(L, 0);
                                  /* comm ... false */
    return 1;
  }
  else {
    /* finished but may have failed */
    msg_error_t res = MSG_comm_get_status(comm);

    if (res == MSG_OK) {
      msg_task_t task = MSG_comm_get_task(comm);
      if (MSG_task_get_sender(task) == MSG_process_self()) {
        /* I'm the sender */
        lua_pushboolean(L, 1);
                                  /* comm ... true */
        return 1;
      }
      else {
        /* I'm the receiver: find the Lua task from the C task*/
        sglua_task_unregister(L, task);
                                  /* comm ... task */
        return 1;
      }
    }
    else {
      /* the communication has failed */
      lua_pushnil(L);
                                  /* comm ... nil */
      lua_pushstring(L, sglua_get_msg_error(res));
                                  /* comm ... nil error */
      return 2;
    }
  }
}
Пример #6
0
void jcomm_bind_task(JNIEnv *env, jobject jcomm) {
  msg_comm_t comm = (msg_comm_t) (uintptr_t) env->GetLongField(jcomm, jcomm_field_Comm_bind);
  //test if we are receiving or sending a task.
  jboolean jreceiving = env->GetBooleanField(jcomm, jcomm_field_Comm_receiving);
  if (jreceiving == JNI_TRUE) {
    //bind the task object.
    msg_task_t task = MSG_comm_get_task(comm);
    xbt_assert(task != nullptr, "Task is nullptr");
    jobject jtask_global = static_cast<jobject>(MSG_task_get_data(task));
    //case where the data has already been retrieved
    if (jtask_global == nullptr) {
      return;
    }

    //Make sure the data will be correctly gc.
    jobject jtask_local = env->NewLocalRef(jtask_global);
    env->DeleteGlobalRef(jtask_global);

    env->SetObjectField(jcomm, jtask_field_Comm_task, jtask_local);

    MSG_task_set_data(task, nullptr);
  }
}
Пример #7
0
/**
 * \brief Node Function
 * Arguments:
 * - my id
 * - the id of a guy I know in the system (except for the first node)
 * - the time to sleep before I join (except for the first node)
 * - the deadline time
 */
static int node(int argc, char *argv[])
{
  double init_time = MSG_get_clock();
  msg_task_t task_received = NULL;
  int join_success = 0;
  double deadline;
  xbt_assert(argc == 3 || argc == 5, "Wrong number of arguments for this node");
  s_node_t node = {0};
  node.id = xbt_str_parse_int(argv[1], "Invalid ID: %s");
  node.known_id = -1;
  node.ready = -1;
  node.pending_tasks = xbt_dynar_new(sizeof(msg_task_t), NULL);
  get_mailbox(node.id, node.mailbox);
  XBT_DEBUG("New node with id %s (%08x)", node.mailbox, (unsigned)node.id);

  for (int i=0; i<LEVELS_COUNT; i++){
    int d = domain(node.id, i);
    for (int j=0; j<LEVEL_SIZE; j++)
      node.routing_table[i][j] = (d==j) ? node.id : -1;
  }

  for (int i=0; i<NEIGHBORHOOD_SIZE; i++)
    node.neighborhood_set[i] = -1;

  for (int i=0; i<NAMESPACE_SIZE; i++)
    node.namespace_set[i] = -1;

  if (argc == 3) { // first ring
    XBT_DEBUG("Hey! Let's create the system.");
    deadline = xbt_str_parse_double(argv[2], "Invalid deadline: %s");
    node.ready = 0;
    XBT_DEBUG("Create a new Pastry ring...");
    join_success = 1;
  } else {
    node.known_id = xbt_str_parse_int(argv[2], "Invalid known ID: %s");
    double sleep_time = xbt_str_parse_double(argv[3], "Invalid sleep time: %s");
    deadline = xbt_str_parse_double(argv[4], "Invalid deadline: %s");

    // sleep before starting
    XBT_DEBUG("Let's sleep during %f", sleep_time);
    MSG_process_sleep(sleep_time);
    XBT_DEBUG("Hey! Let's join the system.");

    join_success = join(&node);
  }

  if (join_success) {
    XBT_DEBUG("Waiting ….");

    while (MSG_get_clock() < init_time + deadline
//      && MSG_get_clock() < node.last_change_date + 1000
        && MSG_get_clock() < max_simulation_time) {
      if (node.comm_receive == NULL) {
        task_received = NULL;
        node.comm_receive = MSG_task_irecv(&task_received, node.mailbox);
        // FIXME: do not make MSG_task_irecv() calls from several functions
      }
      if (!MSG_comm_test(node.comm_receive)) {
        MSG_process_sleep(5);
      } else {
        // a transfer has occurred

        msg_error_t status = MSG_comm_get_status(node.comm_receive);

        if (status != MSG_OK) {
          XBT_DEBUG("Failed to receive a task. Nevermind.");
          MSG_comm_destroy(node.comm_receive);
          node.comm_receive = NULL;
        } else {
          // the task was successfully received
          MSG_comm_destroy(node.comm_receive);
          node.comm_receive = NULL;
          handle_task(&node, task_received);
        }
      }

    }
  //Cleanup the receiving communication.
  if (node.comm_receive != NULL) {
    if (MSG_comm_test(node.comm_receive) && MSG_comm_get_status(node.comm_receive) == MSG_OK) {
      task_free(MSG_comm_get_task(node.comm_receive));
    }
    MSG_comm_destroy(node.comm_receive);
  }

  }
  xbt_dynar_free(&node.pending_tasks);
  return 1;
}
Пример #8
0
/* Master Process */
int master(int argc, char *argv[])
{
    char * key;
    struct HdmsgHost *hdmsg_host;
    xbt_dict_cursor_t cursor = NULL;
    
    int i = 0;
    
    long remaining_inits = 0;
    long remaining_mappers = 0;
    long remaining_shufflers = 0;
    long remaining_reducers = 0;
    long expected_messages = 0;
    
    msg_comm_t res_irecv;
    msg_task_t task_com;
    msg_task_t *tasks = xbt_new(msg_task_t, number_of_workers);
    xbt_dynar_t comms = xbt_dynar_new(sizeof(msg_comm_t), NULL);
    
    XBT_INFO("INITIALIZATION BEGIN");
    
    // Initialize processes (mappers, shufflers, and reducers) on each host
    xbt_dict_foreach(hosts, cursor, key, hdmsg_host)
    {
        if (hdmsg_host->is_worker)
        {
            MSG_process_create("Init", initializeProcs, NULL, hdmsg_host->host);
            
            tasks[remaining_inits] = NULL;
            res_irecv = MSG_task_irecv(&tasks[remaining_inits], "master");
            xbt_dynar_push_as(comms, msg_comm_t, res_irecv);
            remaining_inits++;
        }
    }
    
    while (!xbt_dynar_is_empty(comms))
    {
        xbt_dynar_remove_at(comms, MSG_comm_waitany(comms), &res_irecv);
        task_com = MSG_comm_get_task(res_irecv);
        
        if (!strcmp(MSG_task_get_name(task_com), "init_exit"))
        {
            msg_host_t h = MSG_task_get_source(task_com);
            MSG_task_destroy(task_com);
            
            const char *host_name = MSG_host_get_name(h);
            struct HdmsgHost *hdmsg_host = xbt_dict_get(hosts, host_name);
            
            remaining_mappers += get_mapper_count(hdmsg_host);
            remaining_shufflers += get_shuffler_count(hdmsg_host);
            remaining_reducers += get_reducer_count(hdmsg_host);
            
            remaining_inits--;
            
            if (remaining_inits == 0)
            {
                XBT_INFO("INITIALIZATION COMPLETE");
                
                // Add an extra message to account for the message sent when the shuffle phase begins
                expected_messages = 1 + remaining_mappers + remaining_shufflers + remaining_reducers;
                
                free(tasks);
                tasks = xbt_new(msg_task_t, expected_messages);
                
                for (i = 0; i < expected_messages; i++)
                {
                    tasks[i] = NULL;
                    res_irecv = MSG_task_irecv(&tasks[i], "master");
                    xbt_dynar_push_as(comms, msg_comm_t, res_irecv);
                }
                
                XBT_INFO("MAP PHASE BEGIN");
                
                // Activate Mappers
                xbt_dict_foreach(hosts, cursor, key, hdmsg_host)
                {
                    activate_mappers(hdmsg_host);
                }
            }