Example #1
0
long async_send(SendQEntry *entry)
/*
  Entry points to info about a message ... determine which
  transport mechanism is appropriate and send as much as
  possible without blocking.

  Right now just shared memory ... when sockets are working this
  routine will become async_shmem_send.

  Shared-memory protocol aims for low latency. Each process has
  one buffer for every other process.  Thus, to send a message U
  merely have to determine if the receivers buffer for you is empty
  and copy directly into the receivers buffer.

  Return 0 data has not been sent, 1 if the send is complete.
*/
{
  long node = entry->node;
  ShmemBuf *sendbuf= TCGMSG_proc_info[node].sendbuf;
#ifdef NOTIFY_SENDER
  void *busy_flag = &TCGMSG_proc_info[node].recvbuf->flag;
#endif
  long ncopy, complete;
  long pval;
  long info[4];
  pair_t pair;
  
#ifdef DEBUG2
  (void) fprintf(stdout,"%2ld: sending to %ld buf=%lx len=%ld\n",
                 TCGMSG_nodeid, node, entry->buf, entry->lenbuf); 
  (void) fprintf(stdout,"%2ld: sendbuf=%lx\n", TCGMSG_nodeid, sendbuf);
  (void) fflush(stdout);
#endif

  /* return if the receiver buffer is not available */
#ifdef NOTIFY_SENDER
  if ((pval = local_flag(busy_flag))) {
#else
  if ((pval = remote_flag(&sendbuf->info[3], node))) {
#endif
#   ifdef DEBUG
    {
      long info[4];
      FLUSH_CACHE;
      COPY_FROM_REMOTE(sendbuf->info, info, sizeof(info), node);
      fprintf(stdout,"%2ld: snd info after full = %ld %ld %ld\n", TCGMSG_nodeid,
            info[0], info[1], info[2]);
      fflush(stdout);
      sleep(1);
    }
#   endif

    return 0;
  }

  /* if data has been written already and we are here, operation is complete */
  if(entry->written) return 1L;

# ifdef NOTIFY_SENDER
    set_local_flag(busy_flag,true);
# endif

  info[0] = entry->type; info[1] = entry->lenbuf; info[2] = entry->tag;
#if 0
  entry->buffer_number++;
  info[3] = entry->buffer_number;
#else
  pair.n.from = TCGMSG_nodeid;
  pair.n.to   = node;
  info[3] =  pair.fromto;
#endif

  /* Copy over the message if it fits in the receiver buffer */
  ncopy = (long) (( entry->lenbuf <= SHMEM_BUF_SIZE) ? entry->lenbuf : 0 );
  
  GET_LOC_BUF(localbuf);

  if (ncopy) {
#   ifdef DEBUG
      printf("%ld:snd:copying data node=%ld adr=%lx %ld bytes\n",TCGMSG_nodeid,
           node, sendbuf->buf, ncopy);
      fflush(stdout);
#   endif
    COPY_TO_LOCAL(entry->buf+entry->written, localbuf->buf, ncopy);
    complete = 1;
  } else {
#   ifdef DEBUG
      printf("%ld:snd:copying addr node=%ld adr=%lx %ld bytes\n",TCGMSG_nodeid,
           node, sendbuf->buf, ncopy);
      fflush(stdout);
#   endif
    /* copy address of the user buffer to the send buffer */
    COPY_TO_LOCAL(&(entry->buf), localbuf->buf, sizeof(char*));
    ncopy = sizeof(char*);
    complete = 0;  /* sent is complete only when receiver gets the data */
    entry->written = 1; 
  }

# ifdef DEBUG
    printf("%ld:snd:copying info to node=%ld adr=%lx %ld bytes\n",TCGMSG_nodeid,
           node, sendbuf->info, sizeof(info));
    fflush(stdout);
# endif

  COPY_TO_LOCAL(info, localbuf->info, sizeof(info));
  COPY_TO_REMOTE_CNTR(localbuf,sendbuf,sizeof(info)+ncopy,node,&sendbuf->cntr); 

  /* advance to next buf */
  NEXT_LOC_BUF(localbuf);
 
  return complete;
}


void msg_rcv(long type, char *buf, long lenbuf, long *lenmes, long node)
/*
  Receive a message of given type from the specified node, returning
  the message and length of the message.
  
  Right now just shared memory ... when sockets are working this
  routine will become msg_shmem_rcv

  Shared-memory protocol aims for low latency. Each process has
  one buffer for every other process.  Thus, to send a message U
  merely have to determine if the receivers buffer for you is empty
  and copy directly into the receivers buffer.
*/
{
  long me = TCGMSG_nodeid;
  ShmemBuf *recvbuf;		/* Points to receving buffer */
  long nleft;
  long msg_type, msg_tag, msg_len;
  long buffer_number = 1;
  long expected_tag = TCGMSG_proc_info[node].tag_rcv++;
#ifdef NOTIFY_SENDER
  void *busy_flag= &TCGMSG_proc_info[node].sendbuf->flag;
#endif
  
  if (node<0 || node>=TCGMSG_nnodes)
    Error("msg_rcv: node is out of range", node);

  recvbuf = TCGMSG_proc_info[node].recvbuf;  

  /* Wait for first part message to be written */

#ifdef DEBUG
  (void) fprintf(stdout,"%2ld: receiving from %ld buf=%lx len=%ld\n",
                 me, node, recvbuf,lenbuf); 
  (void) fprintf(stdout,"%2ld: user buf=%lx len=%ld\n", me, buf, lenbuf);
  (void) fflush(stdout);
#endif


#ifdef LAPI
  lapi_await(&recvbuf->info[3], buffer_number, &recvbuf->cntr);
#else
  local_await(&recvbuf->info[3], buffer_number);
#endif

  /* Copy over the header information */

  msg_type = recvbuf->info[0]; 
  msg_len  = recvbuf->info[1];
  msg_tag  = recvbuf->info[2];

#ifdef DEBUG
  (void) fprintf(stdout,"%2ld: received msg from %ld len=%ld\n",
                 me, node, msg_len); 
  (void) fflush(stdout);
#endif

  /* Check type and size information */
  if(msg_tag != expected_tag) {
     pair_t pair;
     pair.fromto = recvbuf->info[3];
     fprintf(stdout,
	   "rcv: me=%ld from=%ld type=%ld expectedtag=%ld lenbuf=%ld\ngot: to=%d from=%d type=%ld msg_tag=%ld msg_len=%ld info[3]=%ld\n",
	   me, node, type, expected_tag, lenbuf,
           (int)pair.n.to, (int)pair.n.from, msg_type, msg_tag, msg_len,  recvbuf->info[3]);
    fflush(stdout);
    Error("msg_rcv: tag mismatch ... transport layer failed????", 0L);
  }

  if (msg_type != type) {
    (void) fprintf(stderr,
		   "rcv: me=%ld from=%ld type=(%ld != %ld) tag=%ld len=%ld\n",
                   me, node, type, msg_type, msg_tag, msg_len);
    Error("msg_rcv: type mismatch ... strong typing enforced\n", 0L);
  }

  if (msg_len > lenbuf) {
    (void) fprintf(stderr,
		   "rcv: me=%ld from=%ld type=%ld tag=%ld len=(%ld > %ld)\n",
		   me, node, type, msg_tag, msg_len, lenbuf);
    Error("msg_rcv: message too long for buffer\n", 0L);
  }
    
  nleft = *lenmes = msg_len;

  if (nleft) {
    long ncopy = nleft;

    /* for short messages data is in local buffer, for long in remote buffer */

    if(nleft <= SHMEM_BUF_SIZE) { 

#     if defined(CRAY_T3D) && !defined(CRAY_T3E)
      /* cache flushing optimizations for T3D */
      long line;
      if(ncopy < 321) 
          for(line = 0; line < ncopy; line+=32) 
              FLUSH_CACHE_LINE(recvbuf->buf+line);
      else 
#     endif

        FLUSH_CACHE;

      COPY_FROM_LOCAL(recvbuf->buf, buf, ncopy);

    }else {

      char *addr = *((char**)recvbuf->buf);

#     ifdef CRAY_T3D
        /* WILL NOT WORK ON T3D for data not alligned on 8-byte boundary !!! */
        if(nleft&7)Error("msg_rcv: not alligned",nleft);
#     endif

      COPY_FROM_REMOTE(addr, buf, nleft, node);

    }
  }

    recvbuf->info[3] = false;
#ifdef NOTIFY_SENDER
    /* confirm that data has been transfered */
    set_remote_flag(busy_flag,false,node);
#endif

}
Example #2
0
inline int
add_logfile_entry(time_t date,
		struct in_addr src_ip,
		unsigned long src_port,
		struct in_addr dst_ip,
		unsigned long dst_port,
		double packets,
		double bytes,
		struct t_ip_groups *groups
		)
{
	char date_str[80];
	int src_grp, dst_grp;
	int traf_idx;
	int flag_local1, flag_local2;

	/* Если начальное время еще неопределено, берем его из перой строки */
	if (groups->start == (time_t)-1) {
		struct tm t;
		/* Округляем время на начало часа */
		localtime_r(&date, &t);
		t.tm_sec = 0;
		t.tm_min = 0;
		groups->start = mktime(&t);
		if ( groups->start == (time_t)-1 ) {
			fprintf(stderr, "cannot convert time\n");
			return -1;
		}
	}


	traf_idx = time2idx(groups->start, date);
	if ( traf_idx < 0 || traf_idx >= MAX_HOUR_CNT) {
		ctime_r(&groups->start, date_str);
		date_str[24]='\0';
		fprintf(stderr, "timedate out of range +Start time: %s, max num hour: %u\n", date_str, MAX_HOUR_CNT);
		return -2;
	}
	/* Максимальный индекс для опеределения с какого и по какое время выдавать результат */
	if ( groups->traf_max < traf_idx)
		groups->traf_max = traf_idx;

	src_grp = lookup_ip(groups, src_ip, &flag_local1);
	dst_grp = lookup_ip(groups, dst_ip, &flag_local2);

	if ( (src_grp == -1) && (dst_grp >= 0) ) {
		/* Входящий трафик (к клиенту) */
		groups->grp[dst_grp].traf_inb[traf_idx] += bytes;
	}else
		if ( (src_grp >= 0) && (dst_grp == -1)  ) {
			/* Исходящий трафик (от клиента) */
			groups->grp[src_grp].traf_outb[traf_idx] += bytes;
		}else
			if ( (src_grp >= 0) && (dst_grp >= 0) ) {
				/* 
				 * Локальный трафик (либо между узлами определенными в группах)
				 * Его надо либо не считать, либо записывать только в одну группу
				 * Если его записывать в обе группы, он испортит общую статистику 
				 * по загрузке. 
				 */
				/* groups->grp[dst_grp].traf_inb[traf_idx] += bytes; */

				/* Выводим трафик как локальный. local_flag устанавливается чтобы
				 * выводить меньше одинаковых строк локального трафика
				 */
				if ( !flag_local1 || !flag_local2 ) {
					char src_ip_str[16];
					char dst_ip_str[16];
					set_local_flag(groups, src_ip, 1);
					set_local_flag(groups, dst_ip, 1);
					strncpy(src_ip_str, inet_ntoa(src_ip), sizeof(src_ip_str) - 1);
					strncpy(dst_ip_str, inet_ntoa(dst_ip), sizeof(dst_ip_str) - 1);
					ctime_r(&date, date_str);
					date_str[24]='\0';
					fprintf(stderr, "local: %s(%i) from %s:%lu(%i) to %s:%lu(%i) - %lg packets %lg bytes\n", 
							date_str,
							traf_idx,
							src_ip_str,
							src_port,
							src_grp>=0?groups->grp[src_grp].num:src_grp,
							dst_ip_str,
							dst_port,
							dst_grp>=0?groups->grp[dst_grp].num:dst_grp,
							packets,
							bytes);
				}
			}else
				/*if ( (src_grp == -1 ) && (dst_grp == -1) ) */
			{ 
				/* Неопределенный трафик */
				char src_ip_str[16];
				char dst_ip_str[16];
				strncpy(src_ip_str, inet_ntoa(src_ip), sizeof(src_ip_str) - 1);
				strncpy(dst_ip_str, inet_ntoa(dst_ip), sizeof(dst_ip_str) - 1);
				ctime_r(&date, date_str);
				date_str[24]='\0';
				fprintf(stderr, "unknown: %s(%i) from %s:%lu(%i) to %s:%lu(%i) - %lg packets %lg bytes\n", 
						date_str,
						traf_idx,
						src_ip_str,
						src_port,
						src_grp>=0?groups->grp[src_grp].num:src_grp,
						dst_ip_str,
						dst_port,
						dst_grp>=0?groups->grp[dst_grp].num:dst_grp,
						packets,
						bytes);
			} 

	return 0;
}