Пример #1
0
static int cos_net_tcp_recv(struct intern_connection *ic, void *data, int sz)
{
	int xfer_amnt = 0;

	assert(ic->conn_type == TCP);
	/* If there is data available, get it */
	if (ic->incoming_size > 0) {
		struct packet_queue *pq;
		struct tcp_pcb *tp;
		char *data_start;
		int data_left;

		pq = ic->incoming;
		assert(pq);
		data_start = ((char*)pq->data) + ic->incoming_offset;
		data_left = pq->len - ic->incoming_offset;
		assert(data_left > 0 && (u32_t)data_left <= pq->len);
		/* Consume all of first packet? */
		if (data_left <= sz) {
			ic->incoming = pq->next;
			if (ic->incoming_last == pq) {
				assert(NULL == ic->incoming);
				ic->incoming_last = NULL;
			}
			memcpy(data, data_start, data_left);
			xfer_amnt = data_left;
			ic->incoming_offset = 0;
#ifdef TEST_TIMING
			ic->ts_start = timing_record(APP_RECV, pq->ts_start);
#endif			
			free(pq);
		} 
		/* Consume part of first packet */
		else {
			memcpy(data, data_start, sz);
			xfer_amnt = sz;
			ic->incoming_offset += sz;
			assert(ic->incoming_offset >= 0 && (u32_t)ic->incoming_offset < pq->len);
		}
		ic->incoming_size -= xfer_amnt;
		tp = ic->conn.tp;
		tcp_recved(tp, xfer_amnt);
	}

	return xfer_amnt;
}
Пример #2
0
static err_t cos_net_stack_send(struct netif *ni, struct pbuf *p, struct ip_addr *ip)
{
	int tot_len = 0, sz;
	char *buff;
	cbuf_t cb;

	/* assuming the net lock is taken here */

	assert(p && p->ref == 1);
	assert(p->type == PBUF_RAM);
	buff = cbuf_alloc(MTU, &cb);
	assert(buff);
	while (p) {
		if (p->len + tot_len > MTU) BUG();
		memcpy(buff + tot_len, p->payload, p->len);
		tot_len += p->len;

#ifdef TCP_SEND_COPY
#ifdef TEST_TIMING
		if ((p->type == PBUF_REF || p->type == PBUF_ROM)) {
			struct packet_queue *pq;
			pq = net_packet_pq(p->payload);
			timing_record(SEND, pq->ts_start);
		}
#endif
#endif
		assert(p->type != PBUF_POOL);
		assert(p->ref == 1);
		p = p->next;
	}

	
	sz = parent_twrite(cos_spd_id(), ip_td, cb, tot_len);
	if (sz <= 0) {
		printc("<<transmit returns %d -> %d>>\n", sz, tot_len);
	}
	tcp_twrite_cnt++;
	assert(sz > 0);
	cbuf_free(buff);
	
	/* cannot deallocate packets here as we might need to
	 * retransmit them. */
	return ERR_OK;
}
Пример #3
0
void timing_basic_alltoall_nelements( int DIM1, int procs, int loop, char* testname, MPI_Comm local_communicator) {
      
  float* send_array;
  float* recv_array;
  
  int myrank;
  int base, typesize, bytes, i;
  char method[50];

  send_array = malloc( DIM1 * procs * sizeof(float));
  recv_array = malloc( DIM1 * procs * sizeof(float));

  MPI_Comm_rank( local_communicator, &myrank );

  base = myrank * DIM1 + 1;
  utilities_fill_unique_array_1D_float( &send_array[0], DIM1, base );

  if ( myrank == 0 ) {
    snprintf(method, 50, "reference");
        
    MPI_Type_size( MPI_FLOAT, &typesize );
    bytes = typesize * DIM1 * procs;

    timing_init( testname, &method[0], bytes );
  }

  for( i=0 ; i<loop ; i++ ) {
    MPI_Alltoall(&send_array[0], DIM1, MPI_FLOAT, &recv_array[0], DIM1, MPI_FLOAT, local_communicator );
    MPI_Alltoall(&recv_array[0], DIM1, MPI_FLOAT, &send_array[0], DIM1, MPI_FLOAT, local_communicator );
    if ( myrank == 0 ) {
      timing_record(3);
    }
  }

  if ( myrank == 0 ) {
    timing_print( 1 );
  }

  free(send_array);
  free(recv_array);
}     
Пример #4
0
void timing_basic_ping_pong_nelements( int DIM1, int loop, char* testname, MPI_Comm local_communicator) {

  float* array;
  int myrank;
  int base, typesize, bytes, i;
  char method[50];

  array = malloc( DIM1 * sizeof(float));

  MPI_Comm_rank( local_communicator, &myrank );

  base = myrank * DIM1 + 1;
  utilities_fill_unique_array_1D_float( &array[0], DIM1, base );

  if ( myrank == 0 ) {
    snprintf(&method[0], 50, "reference");

    MPI_Type_size( MPI_FLOAT, &typesize );
    bytes = typesize * DIM1;

    timing_init( testname, &method[0], bytes );
  }

  for( i=0 ; i<loop ; i++ ){
    if ( myrank == 0 ) {
      MPI_Send( &array[0], DIM1, MPI_FLOAT, 1, itag, local_communicator );
      MPI_Recv( &array[0], DIM1, MPI_FLOAT, 1, itag, local_communicator, MPI_STATUS_IGNORE );
      timing_record(3);
    } else {
      MPI_Recv( &array[0], DIM1, MPI_FLOAT, 0, itag, local_communicator, MPI_STATUS_IGNORE );
      MPI_Send( &array[0], DIM1, MPI_FLOAT, 0, itag, local_communicator );
    }
  }

  if ( myrank == 0 ) {
    timing_print( 1 );
  }

  free(array);
}
Пример #5
0
static err_t cos_net_lwip_tcp_recv(void *arg, struct tcp_pcb *tp, struct pbuf *p, err_t err)
{
	struct intern_connection *ic;
	struct packet_queue *pq, *last;
	void *headers;
	struct pbuf *first;
	
	ic = (struct intern_connection*)arg;
	assert(NULL != ic);
	assert(TCP == ic->conn_type);
	if (NULL == p) {
		assert(ic->conn.tp == tp);
		/* 
		 * This should call our registered error function
		 * above with ERR_ABRT, which will make progress
		 * towards closing the connection.
		 *
		 * Later, when the app calls some function in the API,
		 * TCP_CLOSED will be seen and the internal connection
		 * will be deallocated, and the application notified.
		 */
		tcp_abort(tp);
		assert(ic->conn_type == TCP_CLOSED && NULL == ic->conn.tp);
		/* tcp_close(tp);  // Jiguo: aggressive close */
		return ERR_CLSD;
	}
	first = p;
	while (p) {
		struct pbuf *q;

		if (p->ref != 1) printc("pbuf with len %d, totlen %d and refcnt %d", p->len, p->tot_len, p->ref);
		assert(p->len > 0);
		assert(p->type == PBUF_ROM || p->type == PBUF_REF);
		headers = cos_net_header_start(p, TCP);
		assert (NULL != headers);
		pq = net_packet_pq(headers);
		pq->data = p->payload;
		pq->len = p->len;
		pq->next = NULL;
#ifdef TEST_TIMING
		pq->ts_start = timing_record(RECV, pq->ts_start);
#endif
	
		assert((NULL == ic->incoming) == (NULL == ic->incoming_last));
		/* Is the queue empty? */
		if (NULL == ic->incoming) {
			assert(NULL == ic->incoming_last);
			ic->incoming = ic->incoming_last = pq;
		} else {
			last = ic->incoming_last;
			last->next = pq;
			ic->incoming_last = pq;
		}
		ic->incoming_size += p->len;
		//assert(1 == p->ref);
		q = p->next;
		p->payload = p->alloc_track = NULL;
		assert(NULL != q || p->len == p->tot_len);
		assert(p->ref == 1);
		p = q;
	}
	/* Just make sure lwip is doing what we think its doing */
	assert(first->ref == 1);
	/* This should deallocate the entire chain */
	pbuf_free(first);

	/* printc("thd in %ld tcp_recv call trigger evt id %d\n", cos_get_thd_id(), ic->data); */
	if (-1 != ic->data && evt_trigger(cos_spd_id(), ic->data)) BUG();
	tcp_recv_cnt++;
/* 	/\* If the thread blocked waiting for a packet, wake it up *\/ */
/* 	if (RECVING == ic->thd_status) { */
/* 		ic->thd_status = ACTIVE; */
/* 		assert(ic->thd_status == ACTIVE); /\* Detect races *\/ */
/* 		if (sched_wakeup(cos_spd_id(), ic->tid)) BUG(); */
/* 	} */

	return ERR_OK;
}
Пример #6
0
int net_send(spdid_t spdid, net_connection_t nc, void *data, int sz)
{
	struct intern_connection *ic;
	u16_t tid = cos_get_thd_id();
	int ret = sz;

//	if (!cos_argreg_buff_intern(data, sz)) return -EFAULT;
	if (!net_conn_valid(nc)) return -EINVAL;
	if (sz > MAX_SEND) return -EMSGSIZE;

//	NET_LOCK_TAKE();
	ic = net_conn_get_internal(nc);
	if (NULL == ic) {
		ret = -EINVAL;
		goto err;
	}
	if (tid != ic->tid) {
		ret = -EPERM;
		goto err;
	}

	switch (ic->conn_type) {
	case UDP:
	{
		struct udp_pcb *up;
		struct pbuf *p;

		/* There's no blocking in the UDP case, so this is simple */
		up = ic->conn.up;
		p = pbuf_alloc(PBUF_TRANSPORT, sz, PBUF_ROM);
		if (NULL == p) {
			ret = -ENOMEM;
			goto err;
		}
		p->payload = data;

		if (ERR_OK != udp_send(up, p)) {
			pbuf_free(p);
			/* IP/port must not be set */
			ret = -ENOTCONN;
			goto err;
		}
		pbuf_free(p);
		break;
	}
	case TCP:
	{
		struct tcp_pcb *tp;
#define TCP_SEND_COPY
#ifdef TCP_SEND_COPY
		void *d;
		struct packet_queue *pq;
#endif
		tp = ic->conn.tp;
		if (tcp_sndbuf(tp) < sz) { 
			ret = 0;
			break;
		}
#ifdef TCP_SEND_COPY
		pq = malloc(sizeof(struct packet_queue) + sz);
		if (unlikely(NULL == pq)) {
			ret = -ENOMEM;
			goto err;
		}
#ifdef TEST_TIMING
		pq->ts_start = timing_record(APP_PROC, ic->ts_start);
#endif
		pq->headers = NULL;
		d = net_packet_data(pq);
		memcpy(d, data, sz);
		if (ERR_OK != (ret = tcp_write(tp, d, sz, 0))) {
#else
		if (ERR_OK != (ret = tcp_write(tp, data, sz, TCP_WRITE_FLAG_COPY))) {
#endif
			free(pq);
			printc("tcp_write returned %d (sz %d, tcp_sndbuf %d, ERR_MEM: %d)", 
			       ret, sz, tcp_sndbuf(tp), ERR_MEM);
			BUG();
		}
		/* No implementation of nagle's algorithm yet.  Send
		 * out the packet immediately if possible. */
		if (ERR_OK != (ret = tcp_output(tp))) {
			printc("tcp_output returned %d, ERR_MEM: %d", ret, ERR_MEM);
			BUG();
		}
		ret = sz;

		break;
	}
	case TCP_CLOSED:
		ret = -EPIPE;
		break;
	default:
		BUG();
	}
err:
//	NET_LOCK_RELEASE();
	return ret;
}

/************************ LWIP integration: **************************/

struct ip_addr ip, mask, gw;
struct netif   cos_if;

static void cos_net_interrupt(char *packet, int sz)
{
	void *d;
	int len;
	struct pbuf *p;
	struct ip_hdr *ih;
	struct packet_queue *pq;
#ifdef TEST_TIMING
	unsigned long long ts;
#endif
//	printc(">>> %d\n", net_lock.lock_id);
	NET_LOCK_TAKE();
//	printc("<<< %d\n", net_lock.lock_id);

	assert(packet);
	ih = (struct ip_hdr*)packet;
	if (unlikely(4 != IPH_V(ih))) goto done;
	len = ntohs(IPH_LEN(ih));
	if (unlikely(len != sz || len > MTU)) {
		printc("len %d != %d or > %d", len, sz, MTU);
		goto done;
	}

	p = pbuf_alloc(PBUF_IP, len, PBUF_ROM);
	if (unlikely(!p)) {
		prints("OOM in interrupt: allocation of pbuf failed.\n");
		goto done;
	}

	/* For now, we're going to do an additional copy.  Currently,
	 * packets should be small, so this shouldn't hurt that badly.
	 * This is done because 1) we are freeing the packet
	 * elsewhere, 2) we want to malloc some (small) packets to
	 * save space and free up the ring buffers, 3) it is difficult
	 * to know in (1) which deallocation method (free or return to
	 * ring buff) to use */
	pq = malloc(len + sizeof(struct packet_queue));
	if (unlikely(NULL == pq)) {
		printc("OOM in interrupt: allocation of packet data (%d bytes) failed.\n", len);
		pbuf_free(p);
		goto done;
	}
	pq->headers = d = net_packet_data(pq);
#ifdef TEST_TIMING
#ifdef TCP_SEND_COPY
	ts = pq->ts_start = timing_timestamp();
#endif	
#endif	
	memcpy(d, packet, len);
	p->payload = p->alloc_track = d;
	/* hand off packet ownership here... */
	if (ERR_OK != cos_if.input(p, &cos_if)) {
		prints("net: failure in IP input.");
		pbuf_free(p);
		goto done;
	}

#ifdef TEST_TIMING
	timing_record(UPCALL_PROC, ts);
#endif
done:
	NET_LOCK_RELEASE();
	return;
}
Пример #7
0
int
main (int argc, char **argv)
{
  char *ch;

  if (argc != 2) {
    fputs("Invalid number of arguments\n", stderr);
    fputs("usage: hspwrap EXEFILE\n", stderr);
    exit(EXIT_FAILURE);
  }

  ch = getenv("HSP_BCAST_CHUNK_SIZE");
  if (ch) {
    sscanf(ch, "%zu", &bcast_chunk_size);
  } else {
    bcast_chunk_size = 4L << 20;
  }

  ch = getenv("HSP_INPUT_FORMAT");
  if (!ch || ch[0] == '\0' || ch[0] == 'l') {
    info("Input format: Lines\n");
    input_fmt = 'l';
  } else if (ch[0] == 'f') {
    info("Input format: FASTA\n");
    input_fmt = 'f';
  } else {
    fputs("Invalid input format specified\n", stderr);
    exit(EXIT_FAILURE);
  }

  // Pre-fork process pool (even on master)
#ifndef TIMING_MODE
  sleep(1);
  pool_ctl = process_pool_fork();
  trace("Process pool created.\n");
  sleep(1);
#endif

  // Initialize MPI
  int rank, ranks;
  if (MPI_Init(NULL, NULL) != MPI_SUCCESS) {
    fprintf(stderr, "Error initialize MPI.\n");
    return EXIT_FAILURE;
  }

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &ranks);
  trace("MPI Initialized.\n");

  // Initialize our state
  timing_init(&timing);
  if (rank) {
    slave_init(rank, ranks-1, NUM_PROCS);
  } else {
    print_banner_slant(stderr);
    master_init();
  }

  // Broadcast binary files first
  if (rank) {
    slave_broadcast_work_file("exefile");
  } else {
    master_broadcast_file(getenv("HSP_EXEFILE"));
  }

  // Distribute DB files
  MPI_Barrier(MPI_COMM_WORLD);
  timing_record(&timing.db_start);

  char *dbdir   = getenv("HSP_DBDIR");
  char *dbfiles = strdup(getenv("HSP_DBFILES"));
  char *fn, path[PATH_MAX];

  for (fn = strtok(dbfiles, ":"); fn; fn = strtok(NULL, ":")) {
    snprintf(path, sizeof(path), "%s/%s", dbdir, fn);    

    if (rank) {
      timing.db_kbytes += slave_broadcast_shared_file(path)/1024;
    } else {
      timing.db_kbytes += master_broadcast_file(path)/1024;
    }
  }
  free(dbfiles);

  MPI_Barrier(MPI_COMM_WORLD);
  timing_record(&timing.db_end);

#ifdef TIMING_MODE
  if (!rank) {
    timing_print(&timing);
  }
  MPI_Finalize();
  return 0;
#endif

  // FIXME: The order of things is generally wrong. Should be:
  // Fork Forker, MPI_Init, PS Ctl, EXE/DB distro, forking, main loop

#if 0
  // Now print some stats
  if (rank) {
    MPI_Barrier(MPI_COMM_WORLD);
    printf("Rank %d Processes: %d", rank, ps_ctl->nprocesses);
    printf("  Process ID: %d", getpid());
    printf("  Files: %d (", ps_ctl->ft.nfiles);
    for (i=0; i<ps_ctl->ft.nfiles; ++i) {
      printf("%s, ", ps_ctl->ft.file[i].name);
    }
    puts(")");
  } else {
    printf("Ranks: %d\n\n", ranks);
    MPI_Barrier(MPI_COMM_WORLD);
  }
#endif

  if (rank) {
    slave_main(argv[1]);
  } else {
    master_main(ranks-1);
    timing_print(&timing);
  }

  return 0;
}