void
getsucc_cb (chordID dest, str desthost, 
	    chord_nodelistextres *res, u_int64_t start, clnt_stat err, vec<float> coords, float e)
{
  assert (err == 0 && res->status == CHORD_OK);
  assert (res->resok->nlist.size () >= 2);

  if (coords.size () == 0)
    warnx << dest << " " << desthost << "\n";
  else {
    char s[1024];
    sprintf (s, "%f %f %f e=%f", coords[0], coords[1], coords[2], e/Coord::PRED_ERR_MULT);
    warnx << dest << " " << desthost << " "
	  << s << " "
	  << (getusec () - start) << " "
	  << "\n";
  }

  chord_node z = make_chord_node (res->resok->nlist[1].n);
  
  // wrapped around ring. done.
  if (z.x == wellknown_ID) {
    warnx << getusec () << "--------------------------\n";
    exit (0);
  }

  getsucc (z);
}
Exemple #2
0
void DEX_PASS_MGR::perform_scalar_opt(OPT_CTX & oc)
{
	LIST<IR_OPT*> opt_list; //A list of optimization.
	IR_SSA_MGR * ssamgr = (IR_SSA_MGR*)register_opt(OPT_SSA_MGR);
	bool is_ssa_avail = false;
	if (ssamgr != NULL) {
		is_ssa_avail = ssamgr->is_ssa_construct();
	}

	opt_list.append_tail(register_opt(OPT_CP));
	opt_list.append_tail(register_opt(OPT_DCE));
	opt_list.append_tail(register_opt(OPT_RP));
	opt_list.append_tail(register_opt(OPT_CP));
	opt_list.append_tail(register_opt(OPT_DCE));
	opt_list.append_tail(register_opt(OPT_RP));
	opt_list.append_tail(register_opt(OPT_CP));
	opt_list.append_tail(register_opt(OPT_DCE));
	opt_list.append_tail(register_opt(OPT_LOOP_CVT));
	opt_list.append_tail(register_opt(OPT_LICM));
	opt_list.append_tail(register_opt(OPT_GCSE));

	((IR_DCE*)register_opt(OPT_DCE))->set_elim_cfs(false);
	((IR_DCE*)register_opt(OPT_DCE))->set_ssa_available(is_ssa_avail);

	if (opt_list.get_elem_count() != 0) {
		LOG("\tScalar optimizations for '%s'", m_ru->get_ru_name());
	}

	bool change;
	UINT count = 0;
	//do {
		change = false;
		for (IR_OPT * opt = opt_list.get_head();
			 opt != NULL; opt = opt_list.get_next()) {
			CHAR const* optn = opt->get_opt_name();
			LOG("\t\tpass %s", optn);
			IS_TRUE0(verify_ir_and_bb(m_ru->get_bb_list(), m_dm));
			ULONGLONG t = getusec();

			//dump_bbs(m_ru->get_bb_list(), "before");
			//m_ru->get_cfg()->dump_vcg("before.vcg");

			bool doit = opt->perform(oc);

			//dump_bbs(m_ru->get_bb_list(), "after");
			//m_ru->get_cfg()->dump_vcg("after.vcg");

			append_ti(opt->get_opt_name(), getusec() - t);
			if (doit) {
				LOG("\t\t\tchanged");
				change = true;
				IS_TRUE0(verify_ir_and_bb(m_ru->get_bb_list(), m_dm));
				IS_TRUE0(m_ru->get_cfg()->verify());
			}
		}
		count++;
	//} while (change && count < 20);
	//IS_TRUE0(!change);
}
Exemple #3
0
static
void do_pp_client(void)
{
	unsigned long t1, t2;
	double time;
	double throuput;
	unsigned int msgsize;
	double ms;
	int res;
	double loops = arg_loops;

	memset(abuffer, 24, sizeof(*abuffer));

	if (!arg_pscom) {
		printf("Warning! This is not a ping pong with msize Messagesize!!!\n");
	}
	printf("%7s %8s %8s %8s\n", "msize", "loops", "time", "throughput");
	printf("%7s %8s %8s %8s\n", "[bytes]", "[cnt]", "[us/cnt]", "[MB/s]");
	for (ms = 1.4142135; ms < arg_maxmsize; ms = ms * 1.4142135) {
		unsigned int iloops = loops;
		msgsize = ms + 0.5;

		if (((unsigned)msgsize < 4) && !arg_poll_char) continue;

		if (msgsize >= IB_MTU * psoib_sendq_size) break;
		if (msgsize >= IB_MTU * psoib_recvq_size) break;
		if (arg_pscom && (unsigned)msgsize > IB_MTU_PAYLOAD) break;

		/* warmup, for sync */
		run_pp_c(4, 2);

		t1 = getusec();
		res = run_pp_c(msgsize, iloops);
		t2 = getusec();

		time = (double)(t2 - t1) / (iloops * 2);
		throuput = msgsize / time;
		if (res == 0) {
			printf("%7d %8d %8.2f %8.2f\n", msgsize, iloops, time, throuput);
			fflush(stdout);
		} else {
			printf("Error in communication...\n");
		}

		{
			double t = (t2 - t1) / 1000;
			while (t > arg_maxtime) {
				loops = loops / 1.4142135;
				t /= 1.4142135;
			}
			if (loops < 1) loops = 1;
		}
	}

	return;
}
Exemple #4
0
inline void wait(unsigned long time_in_us){
#ifdef NB_WAIT_RANDOM
  time_in_us=xorshf96()%time_in_us;
#endif
  unsigned long long before_time, after_time;
  before_time=getusec();
  do{
    after_time=getusec();
  } while (after_time-before_time<time_in_us);
}
Exemple #5
0
void
getsucc (const chord_node &n)
{
  chord_nodelistextres *res = New chord_nodelistextres ();
  doRPC (n, chord_program_1, succproc, &n.x, res,
	 wrap (&getsucc_cb, getusec (), n, res));
}
Exemple #6
0
static
void cycles_cal(void)
{
    unsigned long t1, t2, rt1, rt2;
    t1 = getusec();
    GET_CPU_CYCLES(rt1);
    /* usleep call kapm-idled and slowdown the cpu! */
    while (getusec() - 1000 < t1);
    GET_CPU_CYCLES(rt2);
    t2 = getusec();

    t2 -= t1;
    rt2 -= rt1;
    cycles_us = 1.0 * t2 / rt2;
    printf("# %ld usec = %ld cycles, 1 usec = %f\n", t2, rt2, 1 / cycles_us);
}
Exemple #7
0
void
user_args::reply (void *res)
{
  //marshall result
  xdrproc_t inproc = prog->tbl[procno].xdr_res;
  xdrsuio x (XDR_ENCODE);
  if ((!inproc) || (!inproc (x.xdrp (), res))) 
    fatal << "couldn't marshall result\n";

  int res_len = x.uio ()->resid ();
  track_reply (*prog, procno, res_len);

  //stuff into a transport wrapper
  dorpc_res *rpc_res = New dorpc_res (DORPC_OK);
  
  me_->fill_node (rpc_res->resok->src);
  rpc_res->resok->send_time_echo = send_time;
  rpc_res->resok->results.setsize (res_len);
  if (res_len > 0)
    x.uio ()->copyout (rpc_res->resok->results.base ());

  assert (rpc_res->status == DORPC_OK);
  
  u_int64_t diff = getusec (true) - init_time;
  track_proctime (*prog, procno, diff);
 
  //reply
  sbp->reply (rpc_res);
  delete rpc_res;
  delete this;
}
Exemple #8
0
/*
 * Функция вызывается по таймеру реального времени.
 */
static void cpu_sigalarm (int signum)
{
	if (counter == 0) {
		/* Первый отсчёт времени. */
		t0 = getusec ();
	}
	++counter;
	if (counter <= N)
		return;

	/* Последний отсчёт после N интервалов. */
	t1 = getusec ();
	printf ("Measured interval is %.2f msec.\n",
		(t1 - t0) / 1000.0 / N);
	exit (0);

}
Exemple #9
0
static
void do_pp_client(void)
{
	unsigned long t1, t2;
	double time;
	double throuput;
	unsigned int msgsize;
	double ms;
	int res;
	double loops = arg_loops;

	printf("%7s %8s %8s %8s\n", "msize", "loops", "time", "throughput");
	printf("%7s %8s %8s %8s\n", "[bytes]", "[cnt]", "[us/cnt]", "[MB/s]");
	for (ms = 0.0/*1.4142135*/; ms < arg_maxmsize;
	     ms = (ms < 128) ? (ms + 1) : (ms * 1.4142135)) {
		unsigned int iloops = (unsigned int)(loops + 0.5);
		msgsize = (unsigned int)(ms + 0.5);

		/* warmup, for sync */
		run_pp_c(1, 2);

		t1 = getusec();
		res = run_pp_c(msgsize, iloops);
		t2 = getusec();

		time = (double)(t2 - t1) / (iloops * 2);
		throuput = msgsize / time;
		if (res == 0) {
			printf("%7d %8d %8.2f %8.2f\n", msgsize, iloops, time, throuput);
			fflush(stdout);
		} else {
			printf("Error in communication...\n");
		}

		{
			double t = (double)(t2 - t1) / 1000;
			while (t > arg_maxtime) {
				loops = loops / 1.4142135;
				t /= 1.4142135;
			}
			if (loops < 1) loops = 1;
		}
	}

	return;
}
Exemple #10
0
void
getsucc_cb (u_int64_t start, chord_node curr, chord_nodelistextres *res, clnt_stat err)
{
  chord_node next;
    
  if (err != 0 || res->status != CHORD_OK) {
    aout << "failed to get a reading from " << curr << "; skipping.\n";
    sequential.pop_front ();
    if (sequential.size () == 0) {
      fatal << "too many consecutive failures.\n";
    }
    next = sequential[0];
    delete res;
    getsucc (next);
    return;
  }

  size_t sz = res->resok->nlist.size ();
  vec<chord_node> zs;
  for (size_t i = 0; i < sz; i++) {
    chord_node z = make_chord_node (res->resok->nlist[i].n);
    zs.push_back (z);
  }
  delete res;

  curr = zs[0];
  // ensure we talked to who we think we should be talking to.
  assert (curr.x == sequential[0].x);

  // Print full information for the node we just talked to
  int index = curr.vnode_num;
  assert (index >= 0);
  char s[128];
  sprintf (s, "e=%f", curr.e / Coord::PRED_ERR_MULT);
  aout  << format (strbuf (), curr) << " "
        << curr.coords[0] << " " << curr.coords[1] << " " << curr.coords[2] << " "
	<< s << " "
	<< (getusec () - start) << "\n";

  if (verify) {
    sequential.pop_front ();
    verify_succlist (zs);
  } else {
    sequential = zs;
    sequential.pop_front ();
  }
  // Out of nodes, done.
  if (!sequential.size ())
    exit (verify_errors == true ? 1 : 0);

  next = sequential[0];

  // wrapped around ring. done.
  if (next.x == wellknown_ID)
    exit (verify_errors == true ? 1 : 0);
  
  getsucc (next);
}
Exemple #11
0
void
getsucc (const chord_node &n)
{
  chord_nodelistextres *res = New chord_nodelistextres ();
  u_int64_t start = getusec ();

  doRPC (n, CHORDPROC_GETSUCC_EXT, &n.x, res,
	 wrap (&getsucc_cb, n.x, n.r.hostname, res, start));
}
Exemple #12
0
static
void run_pp_client(psdapl_con_info_t *ci)
{
	unsigned long t1, t2;
	double time;
	double throuput;
	unsigned int msgsize;
	double ms;
	int res;
	double loops = arg_loops;

	printf("%7s %8s %8s %8s\n", "msize", "loops", "time", "throughput");
	printf("%7s %8s %8s %8s\n", "[bytes]", "[cnt]", "[us/cnt]", "[MB/s]");
	for (ms = 1.4142135; ms < arg_maxmsize; ms = ms * 1.4142135) {
		unsigned int iloops = loops;
		msgsize = ms + 0.5;

		/* warmup, for sync */
		run_pp_c(ci, 20, 5);

		t1 = getusec();
		res = run_pp_c(ci, msgsize, iloops);
		t2 = getusec();

		time = (double)(t2 - t1) / (iloops * 2);
		throuput = msgsize / time;
		if (res == 0) {
			printf("%7d %8d %8.2f %8.2f\n", msgsize, iloops, time, throuput);
			fflush(stdout);
		} else {
			printf("Error in communication...\n");
		}

		{
			double t = (t2 - t1) / 1000;
			while (t > arg_maxtime) {
				loops = loops / 1.4142135;
				t /= 1.4142135;
			}
			if (loops < 1) loops = 1;
		}
	}
	psdapl_send_eof(ci);
}
Exemple #13
0
void print_stat(int newline)
{
    unsigned long long now;
    double dt;
    now = getusec();
    dt = (now - stat_time_start) / 1000000.0;
    fprintf(stderr, "%10ld bytes in %7.3f seconds (%7.2f MB/s)    %c",
	    stat_bytes_tx, dt,
	    stat_bytes_tx / (1024.0 * 1024.0) / dt,
	    newline ? '\n' : '\r');
    fflush(stderr);
}
Exemple #14
0
long
rpc_manager::doRPC (ptr<location> from, ptr<location> l,
		    const rpc_program &prog, int procno, 
		    ptr<void> in, void *out, aclnt_cb cb,
		    cbtmo_t cb_tmo)
{
  ref<aclnt> c = aclnt::alloc (dgram_xprt, prog, 
			       (sockaddr *)&(l->saddr ()));

  // Make sure that there is an entry in the table for this guy.
  (void) lookup_host (l->address ());
  
  u_int64_t sent = getusec ();
  c->call (procno, in, out,
	   wrap (this, &rpc_manager::doRPCcb, cb, l, sent)); 
  return 0;
}
Exemple #15
0
void
tcp_manager::send_RPC (RPC_delay_args *args)
{

  hostinfo *hi = lookup_host (args->l->address ());
  if (!hi->xp) {
    delaycb (0, 0, wrap (this, &tcp_manager::send_RPC_ateofcb, args));
  }
  else if (hi->xp->ateof()) {
    hostlru.remove (hi);
    hostlru.insert_tail (hi);
    args->l->set_alive (false);
    remove_host (hi);
    delaycb (0, 0, wrap (this, &tcp_manager::send_RPC_ateofcb, args));
  }
  else {
    hi->orpc++;
    args->now = getusec ();
    ptr<aclnt> c = aclnt::alloc (hi->xp, args->prog);
    c->call (args->procno, args->in, args->out, 
	     wrap (this, &tcp_manager::doRPC_tcp_cleanup, c, args));
  }
}
Exemple #16
0
void
rpc_manager::doRPCcb (aclnt_cb realcb, ptr<location> l, u_int64_t sent,
		      clnt_stat err)
{
  if (err) {
    nrpcfailed++;
    l->set_alive (false);
  } else {
    nrpc++;
    // Only update latency on successful RPC.
    // This probably includes time needed for rexmits.
    u_int64_t now = getusec ();
    // prevent overflow, caused by time reversal
    if (now >= sent) {
      u_int64_t lat = now - sent;
      update_latency (NULL, l, lat);
    } else {
      warn << "*** Ignoring timewarp: sent " << sent
	   << " > now " << now << "\n";
    }
  }
  
  (realcb) (err);
}
Exemple #17
0
void PassMgr::performScalarOpt(OptCtx & oc)
{
    TTab<Pass*> opt_tab;
    List<Pass*> passlist;
    SimpCtx simp;
    if (g_do_gvn) { registerPass(PASS_GVN); }

    if (g_do_pre) {
        //Do PRE individually.
        //Since it will incur the opposite effect with Copy-Propagation.
        Pass * pre = registerPass(PASS_PRE);
        pre->perform(oc);
        ASSERT0(verifyIRandBB(m_ru->get_bb_list(), m_ru));
    }

    if (g_do_dce) {
        IR_DCE * dce = (IR_DCE*)registerPass(PASS_DCE);
        passlist.append_tail(dce);
        if (g_do_dce_aggressive) {
            dce->set_elim_cfs(true);
        }
    }

    bool in_ssa_form = false;
    IR_SSA_MGR * ssamgr =
            (IR_SSA_MGR*)(m_ru->get_pass_mgr()->queryPass(PASS_SSA_MGR));
    if (ssamgr != NULL && ssamgr->is_ssa_constructed()) {
        in_ssa_form = true;
    }

    if (!in_ssa_form) {
        //RP can reduce the memory operations and
        //improve the effect of PR SSA, so perform
        //RP before SSA construction.
        //TODO: Do SSA renaming when after register promotion done.
        if (g_do_rp) {
            //First RP.
            passlist.append_tail(registerPass(PASS_RP));
        }
    }

    if (g_do_cp) {
        IR_CP * pass = (IR_CP*)registerPass(PASS_CP);
        pass->set_prop_kind(CP_PROP_SIMPLEX);
        passlist.append_tail(pass);
    }

    if (g_do_rp) {
        //Second RP.
        passlist.append_tail(registerPass(PASS_RP));
    }

    if (g_do_gcse) {
        passlist.append_tail(registerPass(PASS_GCSE));
    }

    if (g_do_lcse) {
        passlist.append_tail(registerPass(PASS_LCSE));
    }

    if (g_do_rce) {
        passlist.append_tail(registerPass(PASS_RCE));
    }

    if (g_do_dse) {
        passlist.append_tail(registerPass(PASS_DSE));
    }

    if (g_do_licm) {
        passlist.append_tail(registerPass(PASS_LICM));
    }

    if (g_do_ivr) {
        passlist.append_tail(registerPass(PASS_IVR));
    }

    if (g_do_loop_convert) {
        passlist.append_tail(registerPass(PASS_LOOP_CVT));
    }

    bool change;
    UINT count = 0;
    BBList * bbl = m_ru->get_bb_list();
    IR_CFG * cfg = m_ru->get_cfg();
    UNUSED(cfg);
    do {
        change = false;
        for (Pass * pass = passlist.get_head();
             pass != NULL; pass = passlist.get_next()) {
            CHAR const* passname = pass->get_pass_name();
            ASSERT0(verifyIRandBB(bbl, m_ru));
            ULONGLONG t = getusec();
            bool doit = pass->perform(oc);
            appendTimeInfo(passname, getusec() - t);
            if (doit) {
                change = true;
                ASSERT0(verifyIRandBB(bbl, m_ru));
                ASSERT0(cfg->verify());
            }
            RefineCtx rc;
            m_ru->refineBBlist(bbl, rc);
            ASSERT0(m_ru->verifyRPO(oc));
        }
        count++;
    } while (change && count < 20);
    ASSERT0(!change);

    if (g_do_lcse) {
        IR_LCSE * lcse = (IR_LCSE*)registerPass(PASS_LCSE);
        lcse->set_enable_filter(false);
        ULONGLONG t = getusec();
        lcse->perform(oc);
        t = getusec() - t;
        appendTimeInfo(lcse->get_pass_name(), t);
    }

    if (g_do_rp) {
        IR_RP * r = (IR_RP*)registerPass(PASS_RP);
        ULONGLONG t = getusec();
        r->perform(oc);
        appendTimeInfo(r->get_pass_name(), getusec() - t);
    }
}
Exemple #18
0
void
do_pp(void)
{
    con_info_t con;
    IB_lid_t remote_lid; /* remote peer's LID */
    IB_wqpn_t remote_qpn; /* remote peer's QPN */
    if (psib_init_con(&default_hca, &default_port, &con)) goto err_init_con;

    printf("Local LID / QP :  0x%04x 0x%06x\n",
	   con.lid,
	   con.qp_prop.qp_num);
    {
	int rlid, rqpn;
	while (1) {
	    printf("Remote LID and QP?\n");
	    fflush(stdout);
	    if (scanf("%x %x", &rlid, &rqpn) == 2) break;
	    printf("wrong format...\n");
	}
	remote_lid = rlid;
	remote_qpn = rqpn;
    }

    if (psib_connect_con(&con, remote_lid, remote_qpn)) goto err_connect_con;

    /* Wait until both sides reach rts */
    sleep(2);


    if (arg_client) {
	unsigned long t1, t2;
	double time;
	double throuput;
	unsigned int msgsize;
	double ms;
	int res;

	printf("%5s %8s %6s %6s\n", "msize", "loops", "time", "throughput");
	for (ms = 1.4142135; ms < IB_MTU_PAYLOAD - 1; ms = ms * 1.4142135) {
//	for (ms = 1.4142135; ms < IB_MTU_PAYLOAD - 1; ms = ms +1) {
	    msgsize = ms + 0.5;
	    /* warmup, for sync */
	    run_pp(&default_hca, &con, 2, 1);
	    t1 = getusec();
	    res = run_pp(&default_hca, &con, arg_loops, msgsize);
	    t2 = getusec();
	    time = (double)(t2 - t1) / (arg_loops * 2);
	    throuput = msgsize / time;
	    if (res == 0) {
		printf("%5d %8d %6.2f %6.2f\n", msgsize, arg_loops, time, throuput);
		fflush(stdout);
	    } else {
		printf("Error in communication: %m\n");
	    }
	}
    } else {
	printf("Server started.\n");
	run_pp_server(&default_hca, &con);
    }

    return;
    /* --- */
 err_init_con:
    printf("psib_init_con() failed : %s\n", psib_err_str);
    exit(1);
 err_connect_con:
    printf("psib_connect_con() failed : %s\n", psib_err_str);
    exit(1);
}
Exemple #19
0
void doClient(void)
{
    int forward_id;
    ps_recv_info_t rinfo;
    ps_send_info_t sinfo;
    FILE *output = NULL;
    PSP_PortH_t porth;
    char *buf, *buf2;

    buf = malloc(arg_maxmsize);
    if (!buf) { perror("malloc(buf)"); exit(1); }
    buf2 = malloc(arg_maxmsize);
    if (!buf2) { perror("malloc(buf2)"); exit(1); }

    output = stdout;

    if (arg_ofile) {
	output = fopen(arg_ofile, "w");
	if (!output) {
	    fprintf(stderr, "Cant open file '%s' for writing : %s\n",
		    arg_ofile, strerror(errno));
	    exit(1);
	}
    } else if (arg_ocmd) {
	output = popen(arg_ocmd, "w");
	if (!output) {
	    fprintf(stderr, "Cant start output command '%s' : %s\n",
		    arg_icmd, strerror(errno));
	    exit(1);
	}
    }

    porth = start_client(&forward_id);
    ps_recv_info_init(&rinfo, porth);
    ps_send_info_init(&sinfo, porth, forward_id);
    PSP_StopListen(porth);

    stat_time_start = getusec();
    while (1) {
	int len;
	char *tmp;

	len = ps_recv(&rinfo, buf, arg_maxmsize);
	ps_send(&sinfo, buf, len);

	if (len <= 0) break;
	assert(fwrite(buf, 1, len, output) == (unsigned) len);

	tmp = buf; buf = buf2; buf2 = tmp;

	if (timer_called) {
	    if (arg_manual) print_stat(0);
	    timer_called = 0;
	}
    }

    if (arg_ofile) {
	fclose(output);
    } else if (arg_ocmd) {
	pclose(output);
    }
    ps_recv_close(&rinfo);
    ps_send_close(&sinfo);
    free(buf2);
    free(buf);
}
Exemple #20
0
void doServer(void)
{
    int forward_id, numClients;
    ps_send_info_t sinfo;
    FILE *input = NULL;
    PSnodes_ID_t node;
    PSP_PortH_t porth;
    char *buf, *buf2;

    buf = malloc(arg_maxmsize);
    if (!buf) { perror("malloc(buf)"); exit(1); }
    buf2 = malloc(arg_maxmsize);
    if (!buf2) { perror("malloc(buf2)"); exit(1); }

    input = stdin;
    if (arg_ifile) {
	input = fopen(arg_ifile, "r");
	if (!input) {
	    fprintf(stderr, "Cant open file '%s' for reading : %s\n",
		    arg_ifile, strerror(errno));
	    exit(1);
	}
    } else if (arg_icmd) {
	input = popen(arg_icmd, "r");
	if (!input) {
	    fprintf(stderr, "Cant start input command '%s' : %s\n",
		    arg_icmd, strerror(errno));
	    exit(1);
	}
    }

    porth = start_server();

    if (arg_manual) {
	numClients = arg_manual;
    } else {
	int clientRank = 1;

	if (arg_hosts) {
	    nodeList = getNLFromHosts(arg_hosts);
	} else if (arg_nodes) {
	    nodeList = getNLFromNodes(arg_nodes);
	} else {
	    nodeList = getNLFromNodes("all");
	}

	if (!nodeList && !arg_manual) {
	    fprintf(stderr, "Unknown clients\n");
	    exit(1);
	}

	/* Start clients */
	for (node=0; node<PSC_getNrOfNodes(); node++) {
	    if (node == PSC_getMyID()) continue;
	    if (nodeList[node]) {
		int ret = PSE_spawnAdmin(node, clientRank,
					 rem_argc, rem_argv, 0);
		if (!ret) clientRank++;
	    }
	}
	numClients = clientRank - 1;
	if (arg_verbose)
	    fprintf(stderr, "Distribute to %d clients\n", numClients);
    }

    forward_id = assign_clients(porth, numClients);
    PSP_StopListen(porth);
    ps_send_info_init(&sinfo, porth, forward_id);

    stat_time_start = getusec();
    // read from stdin, forward to forward_id
    while (1) {
	int len;
	char *tmp;

	len = read(fileno(input), buf, arg_maxmsize);
	if (len <= 0) break;

	ps_send(&sinfo, buf, len);
	// swap buffers (ps_send use PSP_ISend. We can read more
	// data, while we transmit the old data.)
	tmp = buf; buf = buf2; buf2 = tmp;

	if (timer_called) {
	    print_stat(arg_cp ? 1 : 0);
	    timer_called = 0;
	}
    }

    if (arg_ifile) {
	fclose(input);
    } else if (arg_icmd) {
	pclose(input);
    }

    // Send eof:
    ps_send(&sinfo, NULL, 0);
    ps_send_close(&sinfo);

    free(buf);
    free(buf2);
}
chord::chord (str host, int port, 
	      vnode_producer_t p, int nvnodes,
              int max_cache) :
  max_vnodes (0),
  myname (host),
  myport (port),
  fd_dgram (-1),
  fd_stream (-1),
  x_dgram (NULL),
  nrcv (NULL),
  rpcm (NULL),
  locations (NULL)
{
  bool ok (false);

  ok = Configurator::only ().get_int ("chord.max_vnodes", max_vnodes);
  assert (ok);
  if (nvnodes > max_vnodes)
    fatal << "Requested more than allowed vnodes: " 
          << nvnodes << ">" << max_vnodes << "\n";
  if (nvnodes < 1) {
    warn << "Creating at least one vnode.\n";
    nvnodes = 1;
  }
  
  str rpcstr;
  ok = Configurator::only ().get_str ("chord.rpc_mode", rpcstr);
  assert (ok);
  chord_rpc_style = CHORD_RPC_STP;
  if (rpcstr == "tcp" || rpcstr == "TCP")
    chord_rpc_style = CHORD_RPC_SFST;
  else if (rpcstr == "udp" || rpcstr == "UDP")
    chord_rpc_style = CHORD_RPC_SFSU;

  nrcv = New refcounted<u_int32_t>;
  *nrcv = 0;
  switch (chord_rpc_style) {
  case CHORD_RPC_STP:
    rpcm = New refcounted<stp_manager> (nrcv);
    break;
  case CHORD_RPC_SFSU:
    rpcm = New refcounted<rpc_manager> (nrcv);
    break;
  case CHORD_RPC_SFST:
  case CHORD_RPC_SFSBT:
    rpcm = New refcounted<tcp_manager> (nrcv);
    break;
  default:
    fatal << "bad chord_rpc_style value: " << chord_rpc_style << "\n";
  }

  /* In case myport == 0, need to initialize to something in order
   * to create chordIDs during vnode initialization */
  myport = initxprt (myport, SOCK_DGRAM, &fd_dgram);
  myport = initxprt (myport, SOCK_STREAM, &fd_stream);

  warnx << "chord: running on " << myname << ":" << myport << "\n";

  locations = New refcounted<locationtable> (max_cache);

  srandom ((unsigned int) (getusec() & 0xFFFFFFFF));

  for (int i = 0; i < nvnodes; i++) 
  {
    chordID newID = make_chordID (myname, myport, i);
    warnx << gettime () << ": creating new vnode: " << newID << "\n";
    Coord coords;
    ptr<location> l = locations->insert (newID, myname, myport,
					 i, coords, 30, 0, 1, true);
    assert (l);
    locations->pin (newID);

    ptr<vnode> vnodep = (*p) (mkref (this), rpcm, l);
  
    vnodes.insert (newID, vnodep);
    vlist.push_back (vnodep);
  }
}