Пример #1
0
void
tw_gvt_wait(tw_pe * pe)
{
	/*
	 * If new GVT is available grab it and store in
	 * our PE.  Also decrement the global flag so that
	 * it is known that we have finished doing GVT work.
	 * Then cleanup our lists by doing a fossil collection.
	 */
	pe->GVT = sim_gvt;
	pe->trans_msg_ts = DBL_MAX;

	tw_mutex_lock(&g_tw_gvt_lck);
	g_tw_7oclock_node_flag--;
	tw_mutex_unlock(&g_tw_gvt_lck);

	tw_pe_fossil_collect(pe);
	pe->gvt_status = TW_GVT_NORMAL;

#if VERIFY_GVT
	printf("%d %d new GVT %lf (gvt_wait)\n",
		pe->id, (int) *tw_net_onnode(pe->id), sim_gvt);
	printf("%d %d set gvt_flag = %d in gvt_wait\n",
		pe->id, (int) *tw_net_onnode(pe->id), g_tw_7oclock_node_flag);
#endif
}
Пример #2
0
static int
send_begin(tw_pe *me)
{
  int changed = 0;

  while (posted_sends.cur < send_buffer)
    {
      tw_event *e = tw_eventq_peek(&outq);
      tw_node	*dest_node = NULL;

      unsigned id = posted_sends.cur;

#if ROSS_MEMORY
      tw_event *tmp_prev = NULL;

      tw_lp *tmp_lp = NULL;

      tw_memory *memory = NULL;
      tw_memory *m = NULL;

      char *buffer = NULL;

      size_t mem_size = 0;

      unsigned position = 0;
#endif

      if (!e)
	break;

      if(e == me->abort_event)
	tw_error(TW_LOC, "Sending abort event!");

      dest_node = tw_net_onnode((*e->src_lp->type->map)
				((tw_lpid) e->dest_lp));

      //if(!e->state.cancel_q)
	//e->event_id = (tw_eventid) ++me->seq_num;

      e->send_pe = (tw_peid) g_tw_mynode;
      e->send_lp = e->src_lp->gid;

#if ROSS_MEMORY
      // pack pointers
      tmp_prev = e->prev;
      tmp_lp = e->src_lp;

      // delete when working
      e->src_lp = NULL;

      memory = NULL;
      if(e->memory)
	{
	  memory = e->memory;
	  e->memory = (tw_memory *) tw_memory_getsize(me, memory->fd);
	  e->prev = (tw_event *) memory->fd;
	  mem_size = (size_t) e->memory;
	}

      buffer = posted_sends.buffers[id];
      memcpy(&buffer[position], e, g_tw_event_msg_sz);
      position += g_tw_event_msg_sz;

      // restore pointers
      e->prev = tmp_prev;
      e->src_lp = tmp_lp;

      m = NULL;
      while(memory)
	{
	  m = memory->next;

	  if(m)
	    {
	      memory->next = (tw_memory *)
		tw_memory_getsize(me, m->fd);
	      memory->fd = m->fd;
	    }

	  if(position + mem_size > TW_MEMORY_BUFFER_SIZE)
	    tw_error(TW_LOC, "Out of buffer space!");

	  memcpy(&buffer[position], memory, mem_size);
	  position += mem_size;

	  memory->nrefs--;
	  tw_memory_unshift(e->src_lp, memory, memory->fd);

	  if(NULL != (memory = m))
	    mem_size = tw_memory_getsize(me, memory->fd);
	}

      e->memory = NULL;

      if (MPI_Isend(buffer,
		    EVENT_SIZE(e),
		    MPI_BYTE,
		    *dest_node,
		    EVENT_TAG,
		    MPI_COMM_ROSS,
		    &posted_sends.req_list[id]) != MPI_SUCCESS) {
	return changed;
      }
#else
      if (MPI_Isend(e,
		    (int)EVENT_SIZE(e),
		    MPI_BYTE,
		    (int)*dest_node,
		    EVENT_TAG,
		    MPI_COMM_ROSS,
		    &posted_sends.req_list[id]) != MPI_SUCCESS) {
	return changed;
      }
#endif

      tw_eventq_pop(&outq);
      e->state.owner = e->state.cancel_q
	? TW_net_acancel
	: TW_net_asend;

      posted_sends.event_list[id] = e;
      posted_sends.cur++;
      me->s_nwhite_sent++;

      changed = 1;
    }
  return changed;
}
Пример #3
0
static void
tw_gvt_compute(tw_pe * pe)
{
	tw_stime gvt_temp;
	tw_stime trans_temp;
	tw_pe *p;

	pe->LVT = min(tw_pq_minimum(pe->pq), pe->trans_msg_ts);

#if 0
	printf("%d pq %lf, trans %lf \n", pe->id, tw_pq_minimum(pe->pq), pe->trans_msg_ts);
#endif

	if (pe->LVT < sim_gvt)
		tw_error(
			TW_LOC,
			"%d: LVT < GVT!!! gvt: %f lvt: %f t_msg: %f",
			pe->id, sim_gvt, pe->LVT, pe->trans_msg_ts);

	tw_mutex_lock(&g_tw_gvt_lck);
	if (g_tw_7oclock_node_flag != 1) {
		g_tw_7oclock_node_flag--;
		tw_mutex_unlock(&g_tw_gvt_lck);
		pe->gvt_status = TW_GVT_WAIT_REMOTE;
		return;
	}

	/* Last to compute GVT for this node (LGVT) */
	gvt_temp = pe->LVT;
	trans_temp = pe->trans_msg_ts;

	p = NULL;
	while ((p = tw_pe_next(p)))
	{
		if (gvt_temp > p->LVT)
			gvt_temp = p->LVT;
		if (trans_temp > p->trans_msg_ts)
			trans_temp = p->trans_msg_ts;
	}

	if (trans_temp < gvt_temp)
		gvt_temp = trans_temp;

	if(TW_DISTRIBUTED) {
		node_lvt = gvt_temp;
		g_tw_7oclock_node_flag--;
	} else {
		g_tw_gvt_done++;
		sim_gvt = gvt_temp;
		g_tw_7oclock_node_flag = -1;
	}

	tw_mutex_unlock(&g_tw_gvt_lck);

#if VERIFY_GVT || 0
                if(!TW_DISTRIBUTED)
                {
                        printf("%d %d new GVT %f in gvt_compute\n",
                           pe->id, (int) *tw_net_onnode(pe->id), pe->GVT);
                } else
                        printf("%d %d new LVT %f in gvt_compute\n",
                           pe->id, (int) *tw_net_onnode(pe->id), pe->LVT);

		printf("%d %d sets gvt flag = %d in gvt_compute \n",
			pe->id, (int) *tw_net_onnode(pe->id), g_tw_7oclock_node_flag);
#endif

	/* Send LVT to master node on network */
	if (!tw_node_eq(&pe->node, &g_tw_masternode))
		tw_net_send_lvt(pe, node_lvt);

	pe->gvt_status = TW_GVT_WAIT_REMOTE;
	pe->trans_msg_ts = DBL_MAX;

	if(TW_PARALLEL)
	{
		if (sim_gvt != pe->GVT) {
			g_tw_gvt_no_change = 0;
		} else {
			g_tw_gvt_no_change++;
			if (g_tw_gvt_no_change >= g_tw_gvt_max_no_change) {
				tw_error(
					TW_LOC,
					"GVT computed %d times in a row"
					" without changing: GVT = %g"
					" -- GLOBAL SYNCH -- out of memory!",
					g_tw_gvt_no_change, sim_gvt);
			}
		}

		pe->GVT = sim_gvt;

		if (sim_gvt > g_tw_ts_end)
			return;

		tw_pe_fossil_collect(pe);
		pe->gvt_status = TW_GVT_NORMAL;
		pe->trans_msg_ts = DBL_MAX;
	}
}
Пример #4
0
void
tw_gvt_step1(tw_pe * me)
{
	if(TW_PARALLEL)
	{
		if (me->master)
		{
			gvt_cnt++;
			if (gvt_cnt >= g_tw_gvt_interval &&
				me->gvt_status == TW_GVT_NORMAL)
			{
				gvt_cnt = 0;
				if (g_tw_7oclock_node_flag == -g_tw_npe)
				{
					tw_mutex_lock(&g_tw_gvt_lck);
					g_tw_7oclock_node_flag = g_tw_npe;
					tw_mutex_unlock(&g_tw_gvt_lck);
					me->gvt_status = TW_GVT_COMPUTE;
				}
			}

		} else if (g_tw_7oclock_node_flag > 0
			&& me->gvt_status == TW_GVT_NORMAL)
		{
			me->gvt_status = TW_GVT_COMPUTE;
		}

		return;
	}
	
	if(TW_DISTRIBUTED) 
	{
		if (me->gvt_status != TW_GVT_NORMAL)
			return;

		if (me->local_master)
		{
			/*
			 * start GVT in motion, all nodes see this simultaneously
			 * and make a consistent cut by setting the gvt flag 
			 * atomically over the network
			 */
			if (tw_clock_now(me) >= g_tw_clock_gvt_interval)
			{
				if (g_tw_7oclock_node_flag == -g_tw_npe)
				{
					gvt_cnt++;
					g_tw_clock_gvt_interval += g_tw_clock_gvt_window_size;

					g_tw_7oclock_node_flag = g_tw_npe;
					me->gvt_status = TW_GVT_COMPUTE_LGVT;

#if VERIFY_GVT || 0
					printf("\n\n\nGVT COUNT = %d (%d %d) \n",
						gvt_cnt, me->id, (int) *tw_net_onnode(me->id));
#endif
				}
			}
		} else
		{
			if (g_tw_7oclock_node_flag > 0 &&
				tw_clock_now(me) >= g_tw_clock_gvt_interval)
			{
				me->gvt_status = TW_GVT_COMPUTE_LGVT;
			}
		}
	}
}