Beispiel #1
0
static DDS_boolean
PP_array_handler (
    unsigned int nof_cycles
    )
{
    DDS_SampleInfoSeq     infoList = { 0, 0, NULL, FALSE };
    int                   amount;
    DDS_boolean           result = FALSE;

    /* printf "PING: PING_array arrived\n"); */

    preTakeTime = timeGet ();
    pingpong_PP_array_msgDataReader_take (
    PP_array_reader,
    &PP_array_dataList,
    &infoList,
    DDS_LENGTH_UNLIMITED,
    DDS_ANY_SAMPLE_STATE,
    DDS_ANY_VIEW_STATE,
    DDS_ANY_INSTANCE_STATE);
    postTakeTime = timeGet ();

    amount = PP_array_dataList._length;
    if (amount != 0) {
        if (amount > 1) {
            printf ("PING: Ignore excess messages : %d msg received\n", amount);
        }
        PP_array_dataList._buffer[0].count++;
        if (PP_array_dataList._buffer[0].count < nof_cycles) {
            preWriteTime = timeGet ();
            pingpong_PP_array_msgDataWriter_write (PP_array_writer, &PP_array_dataList._buffer[0], DDS_HANDLE_NIL);
            postWriteTime = timeGet ();
            add_stats (&write_access, 1E6 * timeToReal (timeSub (postWriteTime, preWriteTime)));
        } else {
            result = TRUE;
        }
        add_stats (&read_access, 1E6 * timeToReal (timeSub (postTakeTime, preTakeTime)));
        add_stats (&roundtrip,   1E6 * timeToReal (timeSub (postTakeTime, roundTripTime)));
        roundTripTime = preWriteTime;
        pingpong_PP_array_msgDataReader_return_loan (PP_array_reader, &PP_array_dataList, &infoList);
    } else {
        printf ("PING: PING_array triggered, but no data available\n");
    }
    return result;
}
void
update_stats_dc(void){

    if( !half_cycle_step || (half_cycle_step < curr_count) ){
        rotate_stats();
        calc_output();
    }

    add_stats();
}
Beispiel #3
0
void populate_roster(unsigned char *buffer, Team *team, int offset)
{
    int position_count = sizeof(POSITIONS) / sizeof(unsigned long);

    for (int i = 0 ; i < 25 ; i++) {
        Player *player = new_player();
        strcpy(player->pos, POSITIONS[i]); // Set position for player
        add_stats(buffer, player, i + offset);
        team->roster[i] = *player;
    }
}
Beispiel #4
0
void write_daily_stats(statistics_t *stat)
{
	char cct[BUFSIZE], sct[BUFSIZE];
	statistics_t running;
	char timebuf[BUFSIZE];

	get_current_stats(&running);
	add_stats(stat, &running, 0);

	strncpy(cct, connect_average (stat->client_connect_time, stat->client_connections + info.num_clients, timebuf), BUFSIZE);
	strncpy(sct, connect_average (stat->source_connect_time, stat->source_connections + info.num_sources, timebuf), BUFSIZE);
}
Beispiel #5
0
int
google_parse_query(char *source, char *uh, char *target, char *data)
{
    char *s1 = NULL;
    char *s2 = NULL;
    char *s3 = NULL;
    char *s4 = NULL;
    char url[STRING_LONG] = { 0 };
    char sub1[] = "<p class=g><a href=";
 
    if(strstr(data, "did not match any documents") != NULL)
    {
        S("PRIVMSG %s :Sorry, your search did not match any documents.\n", target);
        return ERR_NO_DOCUMENTS;
    }

    if((s1 = strstr(data, "Results ")) != NULL)
    {
        if((s2 = strstr(s1, sub1)) != NULL)
        {
            s2 += strlen(sub1);

            if((s4 = strstr(s2, "http")) == NULL)
            {
                S("PRIVMSG %s :Try again later.\n", target);
                return ERR_NO_DOCUMENTS;
            }
            if((s3 = strchr(s4, '\"')) != NULL)
            {
                *s3 = '\0';
            }
            if((s3 = strstr(s4, "&e=")) != NULL)
            {
                *s3 = '\0';
            }
            snprintf(url, sizeof(url), "%s", s4);
        }
        if(url[0] != 'h')
        {
            S("PRIVMSG %s :Try again later.\n", target);
            return ERR_NO_DOCUMENTS;
        }
        
        S("PRIVMSG %s :%s%s\n", target, rand_reply(source), url);
        add_stats (source, uh, 1, time (NULL), time (NULL));
    }
    else
    {
        S("PRIVMSG %s :Sorry, your search did not match any documents.\n", target);
        return ERR_NO_DOCUMENTS;
    }
    return SUCCESS;
}
Beispiel #6
0
int
taf_parse_query(char *source, char *uh, char *target, char *data)
{
    char *s1 = NULL;
    char *s2 = NULL;
    char tafdata[STRING_LONG] = { 0 };
    int i = 0;
 
    if((s1 = strstr(data, "The observation is:")) != NULL)
    {
	/* skip the next 4 html tags */
	while(i<4)
	{
	    while(*s1 != '>')
	    {
		s1++;
	    }
	    s1++;
	    i++;
	}
	while((*s1 == 0x0D) || (*s1 == 0x0A))
	{
	    s1++;
	}
        if((s2 = strchr(s1, '<')) != NULL)
        {
            *s2 = '\0';
        }
	s2 = s1;
	while (*s2 != '\0')
	{
	    if ((*s2 == 0x0D) || (*s2 == 0x0A) || (*s2 == 0x09))
	    {
		*s2 = ' '; 
	    }
	    s2++;
	}
        snprintf(tafdata, sizeof(tafdata), "%s", s1);
        
        S("PRIVMSG %s :%s%s\n", target, rand_reply(source), tafdata);
        add_stats (source, uh, 1, time (NULL), time (NULL));
    }
    else
    {
        S("PRIVMSG %s :Sorry, no TAF data available.\n", target);
        return ERR_NO_DOCUMENTS;
    }
    return SUCCESS;
}
Beispiel #7
0
static int
handle_echo_reply(struct conn *conn)
{
	int ret;
	uint64_t off;
	struct kdbus_msg *msg;
	const struct kdbus_item *item;

	ret = ioctl(conn->fd, KDBUS_CMD_MSG_RECV, &off);
	if (ret < 0) {
		fprintf(stderr, "error receiving message: %d (%m)\n", ret);
		return EXIT_FAILURE;
	}

	msg = (struct kdbus_msg *)(conn->buf + off);
	item = msg->items;

	KDBUS_ITEM_FOREACH(item, msg, items) {
		switch (item->type) {
		case KDBUS_ITEM_PAYLOAD_MEMFD: {
			char *buf;

			buf = mmap(NULL, item->memfd.size, PROT_READ, MAP_SHARED, item->memfd.fd, 0);
			if (buf == MAP_FAILED) {
				printf("mmap() fd=%i failed: %m", item->memfd.fd);
				break;
			}

			add_stats((struct timeval *) buf);
			munmap(buf, item->memfd.size);
			close(item->memfd.fd);
			break;
		}

		case KDBUS_ITEM_PAYLOAD_OFF: {
			/* ignore */
			break;
		}
		}
	}

	ret = ioctl(conn->fd, KDBUS_CMD_FREE, &off);
	if (ret < 0) {
		fprintf(stderr, "error free message: %d (%m)\n", ret);
		return EXIT_FAILURE;
	}

	return 0;
}
Beispiel #8
0
 void update_tag( const tag_object& current, const comment_object& comment, double hot )const
 {
     const auto& stats = get_stats( current.tag );
     remove_stats( current, stats );
     _db.modify( current, [&]( tag_object& obj ) {
        obj.active            = comment.active;
        obj.cashout           = comment.cashout_time;
        obj.children          = comment.children;
        obj.net_rshares       = comment.net_rshares.value;
        obj.net_votes         = comment.net_votes;
        obj.children_rshares2 = comment.children_rshares2;
        obj.hot               = hot;
        obj.total_payout      = comment.total_payout_value;
    });
    add_stats( current, stats );
 }
Beispiel #9
0
static void *
mb_malloc_(size_t size, const void *caller)
{
  void *p;
  struct mb_head *h;

  LOCK();
  RESTORE_HOOK();

  assert(size > 0);

  if (mem_limit && mb_allocated + size > mem_limit)
    p = 0;
  else if (call_limit && malloc_called + realloc_called > call_limit)
    p = 0;
  else
    p = malloc(size + HEADER_SIZE);

  malloc_called++;
  if (p) {
    mb_allocated += size;
    add_stats(size);
    SET_PEAK();

    h = (struct mb_head *)p;
    h->size = size;
    h->created = 0;
    h->modified = 0;
  }

  print_trace();

  mb_log("%10zd: malloc(%zu) from %p => %p",
         (ssize_t)size, size, caller, p ? p + HEADER_SIZE : 0);

  SAVE_HOOK();
  UNLOCK();

  return p ? p + HEADER_SIZE : 0;
}
static void
update_stats(void){

    if( !half_cycle_step || (half_cycle_step < curr_count) ){

        rotate_stats();

        calc_itarg();
        calc_output();
    }

    add_stats();

    // RSN - determine power factor from po_min + po_max
    //
    //               max + min
    // angle = acos( --------- )
    //               max - min

    // lead/lag : look at sign of io

}
Beispiel #11
0
static void add_line(struct file *info, const char *str)
{
	struct line *line;
	struct pattern *p;
	struct values *vals;

	p = get_pattern(str, &vals);

	line = linehash_get(&info->patterns, p);
	if (line) {
		add_stats(line, p, vals);
	} else {
		/* We need to keep a copy of this! */
		p->text = strdup(p->text); 
		line = malloc(sizeof(*line));
		line->pattern = p;
		list_head_init(&line->vals);
		list_add(&line->vals, &vals->list);
		linehash_add(&info->patterns, line);
		list_add_tail(&info->lines, &line->list);
	}
}
Beispiel #12
0
//
//=========================================================================
//
// This function is called a few times every second by main in order to
// perform tasks we need to do continuously, like accepting new clients
// from the net, refreshing the screen in interactive mode, and so forth
//
void backgroundTasks(void) {
    static uint64_t next_stats_display;
    static uint64_t next_stats_update;
    static uint64_t next_json, next_history;

    uint64_t now = mstime();

    icaoFilterExpire();
    trackPeriodicUpdate();

    if (Modes.net) {
	modesNetPeriodicWork();
    }    


    // Refresh screen when in interactive mode
    if (Modes.interactive) {
        interactiveShowData();
    }

    // always update end time so it is current when requests arrive
    Modes.stats_current.end = now;

    if (now >= next_stats_update) {
        int i;

        if (next_stats_update == 0) {
            next_stats_update = now + 60000;
        } else {
            Modes.stats_latest_1min = (Modes.stats_latest_1min + 1) % 15;
            Modes.stats_1min[Modes.stats_latest_1min] = Modes.stats_current;
            
            add_stats(&Modes.stats_current, &Modes.stats_alltime, &Modes.stats_alltime);
            add_stats(&Modes.stats_current, &Modes.stats_periodic, &Modes.stats_periodic);
            
            reset_stats(&Modes.stats_5min);
            for (i = 0; i < 5; ++i)
                add_stats(&Modes.stats_1min[(Modes.stats_latest_1min - i + 15) % 15], &Modes.stats_5min, &Modes.stats_5min);
            
            reset_stats(&Modes.stats_15min);
            for (i = 0; i < 15; ++i)
                add_stats(&Modes.stats_1min[i], &Modes.stats_15min, &Modes.stats_15min);
            
            reset_stats(&Modes.stats_current);
            Modes.stats_current.start = Modes.stats_current.end = now;
            
            if (Modes.json_dir)
                writeJsonToFile("stats.json", generateStatsJson);

            next_stats_update += 60000;
        }
    }

    if (Modes.stats && now >= next_stats_display) {
        if (next_stats_display == 0) {
            next_stats_display = now + Modes.stats;
        } else {
            add_stats(&Modes.stats_periodic, &Modes.stats_current, &Modes.stats_periodic);
            display_stats(&Modes.stats_periodic);
            reset_stats(&Modes.stats_periodic);

            next_stats_display += Modes.stats;
        }
    }

    if (Modes.json_dir && now >= next_json) {
        writeJsonToFile("aircraft.json", generateAircraftJson);
        next_json = now + Modes.json_interval;
    }

    if ((Modes.json_dir || Modes.net_http_port) && now >= next_history) {
        int rewrite_receiver_json = (Modes.json_aircraft_history[HISTORY_SIZE-1].content == NULL);

        free(Modes.json_aircraft_history[Modes.json_aircraft_history_next].content); // might be NULL, that's OK.
        Modes.json_aircraft_history[Modes.json_aircraft_history_next].content =
            generateAircraftJson("/data/aircraft.json", &Modes.json_aircraft_history[Modes.json_aircraft_history_next].clen);

        if (Modes.json_dir) {
            char filebuf[PATH_MAX];
            snprintf(filebuf, PATH_MAX, "history_%d.json", Modes.json_aircraft_history_next);
            writeJsonToFile(filebuf, generateHistoryJson);
        }

        Modes.json_aircraft_history_next = (Modes.json_aircraft_history_next+1) % HISTORY_SIZE;

        if (rewrite_receiver_json)
            writeJsonToFile("receiver.json", generateReceiverJson); // number of history entries changed

        next_history = now + HISTORY_INTERVAL;
    }
}
Beispiel #13
0
char *do_item_stats(uint32_t (*add_stats)(char *buf,
                    const char *key, const uint16_t klen, const char *val,
                    const uint32_t vlen, void *cookie), void *c, int *bytes) {

    size_t bufleft = (size_t) LARGEST_ID * 240;
    char *buffer = malloc(bufleft);
    char *bufcurr = buffer;
    rel_time_t now = current_time;
    protocol_binary_response_header *header;
    int hdrsiz = sizeof(header->response);
    int i, linelen = 0;

    if (buffer == NULL) {
        *bytes = -1;
        return NULL;
    }

    for (i = 0; i < LARGEST_ID; i++) {
        if (tails[i] != NULL) {
            char key[128];
            char val[256];
            uint32_t nbytes = 0;

            sprintf(key, "items:%d:number", i);
            sprintf(val, "%u", sizes[i]);
            nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c);
            linelen += nbytes;
            bufcurr += nbytes;

            sprintf(key, "items:%d:age", i);
            sprintf(val, "%u", now - tails[i]->time);
            nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c);
            linelen += nbytes;
            bufcurr += nbytes;

            sprintf(key, "items:%d:evicted", i);
            sprintf(val, "%u", itemstats[i].evicted);
            nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c);
            linelen += nbytes;
            bufcurr += nbytes;

            sprintf(key, "items:%d:evicted_time", i);
            sprintf(val, "%u", itemstats[i].evicted_time);
            nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c);
            linelen += nbytes;
            bufcurr += nbytes;

            sprintf(key, "items:%d:outofmemory", i);
            sprintf(val, "%u", itemstats[i].outofmemory);
            nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c);
            linelen += nbytes;
            bufcurr += nbytes;

            /* check whether binary protocol terminator will fit */
            if (linelen + hdrsiz < bufleft) {
                bufleft -= linelen;
            } else {
                free(buffer);
                return NULL;
            }
        }
    }

    /* getting here means both ascii and binary terminators fit */
    linelen += add_stats(bufcurr, NULL, 0, NULL, 0, c);
    *bytes = linelen;

    return buffer;
}
Beispiel #14
0
static void display_total_stats(void)
{
    struct stats added;
    add_stats(&Modes.stats_alltime, &Modes.stats_current, &added);
    display_stats(&added);
}
Beispiel #15
0
static void *
mb_realloc_(void *ptr, size_t size, const void *caller)
{
  void *p;
  struct mb_head *h = HEADER(ptr);
  size_t oldsize;

  LOCK();
  RESTORE_HOOK();

  realloc_called++;

  if (!ptr) {
    assert(size > 0);

    if ((mem_limit && mb_allocated + size > mem_limit) ||
        (call_limit && malloc_called + realloc_called > call_limit))
      p = 0;
    else
      p = malloc(size + HEADER_SIZE);

    if (p) {
      mb_allocated += size;
      add_stats(size);
      SET_PEAK();
    }
    print_trace();
    mb_log("%10zd: realloc(%p, %zu) from %p => %p", (ssize_t)size,
           ptr, size, caller, p ? p + HEADER_SIZE : 0);

    SET_HEAD(p, size);
    SAVE_HOOK();
    UNLOCK();
    return p ? (unsigned char *)p + HEADER_SIZE : 0;
  }

  if (h->size == size) {
    print_trace();
    mb_log("%10zd: realloc(%p, %zu) from %p => %p", (ssize_t)0,
           ptr, size, caller, p + HEADER_SIZE);

    if (call_limit && malloc_called + realloc_called > call_limit)
      ptr = 0;

    SAVE_HOOK();
    UNLOCK();
    return ptr;
  }

  oldsize = h->size;

  if ((mem_limit && mb_allocated + size - oldsize > mem_limit) ||
      (call_limit && malloc_called + realloc_called > call_limit))
    p = 0;
  else
    p = realloc((unsigned char *)ptr - HEADER_SIZE, size + HEADER_SIZE);

  if (p) {
    mb_allocated += size - oldsize;
    add_stats(size);
    SET_PEAK();
  }

  print_trace();
  mb_log("%10zd: realloc(%p, %zu) from %p => %p",
         (int)(size - oldsize), ptr, size, caller, p ? p + HEADER_SIZE : 0);
  SET_HEAD(p, size - oldsize);

  SAVE_HOOK();
  UNLOCK();

  return p ? (unsigned char *)p + HEADER_SIZE : 0;
}
Beispiel #16
0
int OSPL_MAIN (int argc, char ** argv)
#endif
{
    DDS_ConditionSeq                        *conditionList;
    DDS_WaitSet                              w;

    DDS_DomainParticipantQos                 *dpQos;
    DDS_TopicQos                             *tQos;
    DDS_PublisherQos                         *pQos;
    DDS_DataWriterQos                        *dwQos;
    DDS_SubscriberQos                        *sQos;
    DDS_DataReaderQos                        *drQos;

    DDS_Condition                            exp_condition = NULL;
    pong_handler                            *active_handler = NULL;
    DDS_Duration_t                           wait_timeout = {3,0};

    DDS_boolean                              finish_flag = FALSE;
    DDS_boolean                              timeout_flag = FALSE;
    DDS_boolean                              terminate = FALSE;
    DDS_ReturnCode_t                         result;

    int                                      imax = 1;
    int                                      i;
    unsigned int                             block;

    printf ("Starting ping example\n");
    fflush(stdout);

    /*
     * init timing statistics
     */
    init_stats (&roundtrip,    "round_trip");
    init_stats (&write_access, "write_access");
    init_stats (&read_access,  "read_access");

    /*
     * Evaluate cmdline arguments
     */
#ifdef INTEGRITY
    nof_blocks = 100;
    nof_cycles = 100;
#if defined (PING1)
    topic_id = 'm';
#elif defined (PING2)
    topic_id = 'q';
#elif defined (PING3)
    topic_id = 's';
#elif defined (PING4)
    topic_id = 'f';
#elif defined (PING5)
    topic_id = 'b';
#elif defined (PING6)
    nof_blocks = 1;
    nof_cycles = 10;
    topic_id = 't';
#endif
    write_partition = "PongRead";
    read_partition = "PongWrite";
#else
    if (argc != 1) {
    if (argc != 6) {
            printf ("Invalid.....\n Usage: %s [blocks blocksize topic_id WRITE_PARTITION READ_PARTITION]\n", argv[0]);
            exit (1);
        }
        nof_blocks      = atoi (argv[1]);
        nof_cycles      = atoi (argv[2]);
        topic_id        = argv[3][0];
        write_partition = argv[4];
        read_partition  = argv[5];
    }
#endif

#ifdef _WIN32
     init_clock();
#endif

    /*
     * Create WaitSet
     */
    w     = DDS_WaitSet__alloc ();
    /*
     * Initialize Qos variables
     */
    dpQos = DDS_DomainParticipantQos__alloc();
    tQos  = DDS_TopicQos__alloc();
    pQos  = DDS_PublisherQos__alloc();
    dwQos = DDS_DataWriterQos__alloc();
    sQos  = DDS_SubscriberQos__alloc();
    drQos = DDS_DataReaderQos__alloc();
    /*
     * Initialize condition list
     */
    conditionList = NULL;

    /*
     * Create participant
     */
    dpf = DDS_DomainParticipantFactory_get_instance ();
    dp = DDS_DomainParticipantFactory_create_participant (dpf, myDomain, DDS_PARTICIPANT_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);
    if (dp == DDS_HANDLE_NIL) {
        printf ("%s PING: ERROR - Splice Daemon not running", argv[0]);
        exit (1);
    }

    /*
     * Create PING publisher
     */
    DDS_DomainParticipant_get_default_publisher_qos (dp, pQos);
    pQos->partition.name._length = 1;
    pQos->partition.name._maximum = 1;
    pQos->partition.name._buffer = DDS_StringSeq_allocbuf (1);
    pQos->partition.name._buffer[0] = DDS_string_dup (write_partition);
    p = DDS_DomainParticipant_create_publisher (dp, pQos, NULL, DDS_STATUS_MASK_NONE);
    DDS_free (pQos);

    /*
     * Create PONG subscriber
     */
    DDS_DomainParticipant_get_default_subscriber_qos (dp, sQos);
    sQos->partition.name._length = 1;
    sQos->partition.name._maximum = 1;
    sQos->partition.name._buffer = DDS_StringSeq_allocbuf (1);
    sQos->partition.name._buffer[0] = DDS_string_dup (read_partition);
    s = DDS_DomainParticipant_create_subscriber (dp, sQos, NULL, DDS_STATUS_MASK_NONE);
    DDS_free (sQos);

    /*
     * PP_min_msg
     */

    /*  Create Topic */
    PP_min_dt = pingpong_PP_min_msgTypeSupport__alloc ();
    pingpong_PP_min_msgTypeSupport_register_type (PP_min_dt, dp, "pingpong::PP_min_msg");
    PP_min_topic = DDS_DomainParticipant_create_topic (dp, "PP_min_topic", "pingpong::PP_min_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    DDS_Publisher_get_default_datawriter_qos(p, dwQos);
    dwQos->reliability.kind = DDS_BEST_EFFORT_RELIABILITY_QOS;
    dwQos->history.kind = DDS_KEEP_ALL_HISTORY_QOS;

    /* Create datawriter */
    PP_min_writer = DDS_Publisher_create_datawriter (p, PP_min_topic, dwQos, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_min_reader = DDS_Subscriber_create_datareader (s, PP_min_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Add datareader statuscondition to waitset */
    PP_min_sc = DDS_DataReader_get_statuscondition (PP_min_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_min_sc, DDS_DATA_AVAILABLE_STATUS);
    DDS_WaitSet_attach_condition (w, PP_min_sc);

    /*
     * PP_seq_msg
     */

    /*  Create Topic */
    PP_seq_dt = pingpong_PP_seq_msgTypeSupport__alloc ();
    pingpong_PP_seq_msgTypeSupport_register_type (PP_seq_dt, dp, "pingpong::PP_seq_msg");
    PP_seq_topic = DDS_DomainParticipant_create_topic (dp, "PP_seq_topic", "pingpong::PP_seq_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_seq_writer = DDS_Publisher_create_datawriter (p, PP_seq_topic, dwQos, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_seq_reader = DDS_Subscriber_create_datareader (s, PP_seq_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Add datareader statuscondition to waitset */
    PP_seq_sc = DDS_DataReader_get_statuscondition (PP_seq_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_seq_sc, DDS_DATA_AVAILABLE_STATUS);
    DDS_WaitSet_attach_condition (w, PP_seq_sc);

    /*
     * PP_string_msg
     */

    /*  Create Topic */
    PP_string_dt = pingpong_PP_string_msgTypeSupport__alloc ();
    pingpong_PP_string_msgTypeSupport_register_type (PP_string_dt, dp, "pingpong::PP_string_msg");
    PP_string_topic = DDS_DomainParticipant_create_topic (dp, "PP_string_topic", "pingpong::PP_string_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_string_writer = DDS_Publisher_create_datawriter (p, PP_string_topic, dwQos, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_string_reader = DDS_Subscriber_create_datareader (s, PP_string_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Add datareader statuscondition to waitset */
    PP_string_sc = DDS_DataReader_get_statuscondition (PP_string_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_string_sc, DDS_DATA_AVAILABLE_STATUS);
    DDS_WaitSet_attach_condition (w, PP_string_sc);

    /*
     * PP_fixed_msg
     */

    /*  Create Topic */
    PP_fixed_dt = pingpong_PP_fixed_msgTypeSupport__alloc ();
    pingpong_PP_fixed_msgTypeSupport_register_type (PP_fixed_dt, dp, "pingpong::PP_fixed_msg");
    PP_fixed_topic = DDS_DomainParticipant_create_topic (dp, "PP_fixed_topic", "pingpong::PP_fixed_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_fixed_writer = DDS_Publisher_create_datawriter (p, PP_fixed_topic, dwQos, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_fixed_reader = DDS_Subscriber_create_datareader (s, PP_fixed_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Add datareader statuscondition to waitset */
    PP_fixed_sc = DDS_DataReader_get_statuscondition (PP_fixed_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_fixed_sc, DDS_DATA_AVAILABLE_STATUS);
    DDS_WaitSet_attach_condition (w, PP_fixed_sc);

    /*
     * PP_array_msg
     */

    /*  Create Topic */
    PP_array_dt = pingpong_PP_array_msgTypeSupport__alloc ();
    pingpong_PP_array_msgTypeSupport_register_type (PP_array_dt, dp, "pingpong::PP_array_msg");
    PP_array_topic = DDS_DomainParticipant_create_topic (dp, "PP_array_topic", "pingpong::PP_array_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_array_writer = DDS_Publisher_create_datawriter (p, PP_array_topic, dwQos, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_array_reader = DDS_Subscriber_create_datareader (s, PP_array_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Add datareader statuscondition to waitset */
    PP_array_sc = DDS_DataReader_get_statuscondition (PP_array_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_array_sc, DDS_DATA_AVAILABLE_STATUS);
    DDS_WaitSet_attach_condition (w, PP_array_sc);


    /*
     * PP_bseq_msg
     */

    /*  Create Topic */
    PP_bseq_dt = pingpong_PP_bseq_msgTypeSupport__alloc ();
    pingpong_PP_bseq_msgTypeSupport_register_type (PP_bseq_dt, dp, "pingpong::PP_bseq_msg");
    PP_bseq_topic = DDS_DomainParticipant_create_topic (dp, "PP_bseq_topic", "pingpong::PP_bseq_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_bseq_writer = DDS_Publisher_create_datawriter (p, PP_bseq_topic, dwQos, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_bseq_reader = DDS_Subscriber_create_datareader (s, PP_bseq_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Add datareader statuscondition to waitset */
    PP_bseq_sc = DDS_DataReader_get_statuscondition (PP_bseq_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_bseq_sc, DDS_DATA_AVAILABLE_STATUS);
    DDS_WaitSet_attach_condition (w, PP_bseq_sc);

    /*
     * PP_quit_msg
     */

    /*  Create Topic */
    PP_quit_dt = pingpong_PP_quit_msgTypeSupport__alloc ();
    pingpong_PP_quit_msgTypeSupport_register_type (PP_quit_dt, dp, "pingpong::PP_quit_msg");
    PP_quit_topic = DDS_DomainParticipant_create_topic (dp, "PP_quit_topic", "pingpong::PP_quit_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_quit_writer = DDS_Publisher_create_datawriter (p, PP_quit_topic, dwQos, NULL, DDS_STATUS_MASK_NONE);

    /* Fr: workarround for ticket dds1712 */
    conditionList = DDS_ConditionSeq__alloc();
    assert(conditionList);
    DDS_WaitSet_wait (w, conditionList, &wait_timeout);
    DDS_free(conditionList);

    for (block = 0; block < nof_blocks && !terminate ; block++) {
        while (!finish_flag) {
            /*
             * Send Initial message
             */
            timeout_flag = FALSE;

            switch(topic_id) {
                case 'm':
                    {
                        /* printf ("PING: sending initial ping_min\n"); */
                        pingpong_PP_min_msg *PPdata = pingpong_PP_min_msg__alloc ();
                        exp_condition = PP_min_sc;
                        active_handler = &PP_min_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        preWriteTime = timeGet ();
                        pingpong_PP_min_msgDataWriter_write (PP_min_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 'q':
                    {
                        /* printf ("PING: sending initial ping_seq\n"); */
                        pingpong_PP_seq_msg *PPdata = pingpong_PP_seq_msg__alloc ();
                        exp_condition = PP_seq_sc;
                        active_handler = &PP_seq_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        {
                            int i = 0;
                            PPdata->payload._buffer = pingpong_seq_char_allocbuf(SEQ_PAYLOAD_SIZE);
                            PPdata->payload._length = SEQ_PAYLOAD_SIZE;
                            PPdata->payload._maximum = SEQ_PAYLOAD_SIZE;
                            for (i=0; i<SEQ_PAYLOAD_SIZE; i++) {
                                PPdata->payload._buffer[i] = (char)i;
                            }
                        }
                        preWriteTime = timeGet ();
                        pingpong_PP_seq_msgDataWriter_write (PP_seq_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 's':
                    {
                        /* printf ("PING: sending initial ping_string\n"); */
                        pingpong_PP_string_msg *PPdata = pingpong_PP_string_msg__alloc ();
                        exp_condition = PP_string_sc;
                        active_handler = &PP_string_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        PPdata->a_string = DDS_string_dup ("a_string");
                        preWriteTime = timeGet ();
                        pingpong_PP_string_msgDataWriter_write (PP_string_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 'f':
                    {
                        /* printf ("PING: sending initial ping_fixed\n"); */
                        pingpong_PP_fixed_msg *PPdata = pingpong_PP_fixed_msg__alloc ();
                        exp_condition = PP_fixed_sc;
                        active_handler = &PP_fixed_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        PPdata->a_bstring = DDS_string_dup ("a_bstring");
                        preWriteTime = timeGet ();
                        pingpong_PP_fixed_msgDataWriter_write (PP_fixed_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 'a':
                    {
                        /* printf ("PING: sending initial ping_array\n"); */
                        pingpong_PP_array_msg *PPdata = pingpong_PP_array_msg__alloc ();
                        exp_condition = PP_array_sc;
                        active_handler = &PP_array_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        preWriteTime = timeGet ();
                        pingpong_PP_array_msgDataWriter_write (PP_array_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 'b':
                    {
                        /* printf ("PING: sending initial ping_bseq_msg\n"); */
                        pingpong_PP_bseq_msg *PPdata = pingpong_PP_bseq_msg__alloc ();
                        exp_condition = PP_bseq_sc;
                        active_handler = &PP_bseq_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        preWriteTime = timeGet ();
                        pingpong_PP_bseq_msgDataWriter_write (PP_bseq_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 't':
                    {
                        /* printf ("PING: sending initial ping_quit\n"); */
                        pingpong_PP_quit_msg *PPdata = pingpong_PP_quit_msg__alloc();
                        PPdata->quit = TRUE;
                        terminate = TRUE;
                        finish_flag = TRUE;
                        sleep(1);
                        preWriteTime = timeGet ();
                        pingpong_PP_quit_msgDataWriter_write (PP_quit_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        sleep(1);
                        DDS_free (PPdata);
                    }
                    break;
                default:
                    printf("Invalid topic-id\n");
                    exit(1);
            }

            if (!terminate) {
                roundTripTime = preWriteTime;
                add_stats (&write_access, 1E6 * timeToReal (timeSub (postWriteTime, preWriteTime)));

                /*
                 * Wait for response, calculate timing, and send another data if not ready
                 */
                while (!(timeout_flag || finish_flag)) {
                    conditionList = DDS_ConditionSeq__alloc();
                    result = DDS_WaitSet_wait (w, conditionList, &wait_timeout);
                    if(result == DDS_RETCODE_OK || result == DDS_RETCODE_NO_DATA || result == DDS_RETCODE_TIMEOUT)
                    {
                        if (conditionList) {
                            imax = conditionList->_length;
                            if (imax != 0) {
                                for (i = 0; i < imax; i++) {
                                    if (conditionList->_buffer[i] == exp_condition) {
                                        finish_flag = active_handler (nof_cycles);
                                    } else {
                                        printf ("PING: unexpected condition triggered: %lx\n",
                                            (unsigned long)conditionList->_buffer[i]);
                                    }
                                }
                            } else {
                                printf ("PING: TIMEOUT - message lost\n");
                                timeout_flag = TRUE;
                            }
                            DDS_free(conditionList);
                        } else {
                            printf ("PING: TIMEOUT - message lost\n");
                            timeout_flag = TRUE;
                        }
                    } else
                    {
                        printf ("PING: Waitset wait failed (code %d), terminating.\n", result);
                        finish_flag = TRUE;
                        terminate = TRUE;
                    }
                }
            }
        }
        if (!terminate) {
            finish_flag = FALSE;
            if (block == 0) {
                printf ("# PING PONG measurements (in us) \n");
                printf ("#           Roundtrip time [us]             Write-access time [us]          Read-access time [us]\n");
                printf ("# Block     Count   mean    min    max      Count   mean    min    max      Count   mean    min    max\n");
            }
            printf ("%6d %10d %6.0f %6.0f %6.0f %10d %6.0f %6.0f %6.0f %10d %6.0f %6.0f %6.0f\n",
                block,
                roundtrip.count,
                roundtrip.average,
                roundtrip.min,
                roundtrip.max,
                write_access.count,
                write_access.average,
                write_access.min,
                write_access.max,
                read_access.count,
                read_access.average,
                read_access.min,
                read_access.max);
            fflush (stdout);
            init_stats (&write_access, "write_access");
            init_stats (&read_access,  "read_access");
            init_stats (&roundtrip,    "round_trip");
        }
    }
    DDS_Subscriber_delete_datareader (s, PP_min_reader);
    DDS_Publisher_delete_datawriter (p, PP_min_writer);
    DDS_Subscriber_delete_datareader (s, PP_seq_reader);
    DDS_Publisher_delete_datawriter (p, PP_seq_writer);
    DDS_Subscriber_delete_datareader (s, PP_string_reader);
    DDS_Publisher_delete_datawriter (p, PP_string_writer);
    DDS_Subscriber_delete_datareader (s, PP_fixed_reader);
    DDS_Publisher_delete_datawriter (p, PP_fixed_writer);
    DDS_Subscriber_delete_datareader (s, PP_array_reader);
    DDS_Publisher_delete_datawriter (p, PP_array_writer);
    DDS_Subscriber_delete_datareader (s, PP_bseq_reader);
    DDS_Publisher_delete_datawriter (p, PP_bseq_writer);
    DDS_Publisher_delete_datawriter (p, PP_quit_writer);
    DDS_DomainParticipant_delete_subscriber (dp, s);
    DDS_DomainParticipant_delete_publisher (dp, p);
    DDS_DomainParticipant_delete_topic (dp, PP_min_topic);
    DDS_DomainParticipant_delete_topic (dp, PP_seq_topic);
    DDS_DomainParticipant_delete_topic (dp, PP_string_topic);
    DDS_DomainParticipant_delete_topic (dp, PP_fixed_topic);
    DDS_DomainParticipant_delete_topic (dp, PP_array_topic);
    DDS_DomainParticipant_delete_topic (dp, PP_bseq_topic);
    DDS_DomainParticipant_delete_topic (dp, PP_quit_topic);
    DDS_DomainParticipantFactory_delete_participant (dpf, dp);
    DDS_free (w);
    DDS_free (PP_min_dt);
    DDS_free (PP_seq_dt);
    DDS_free (PP_string_dt);
    DDS_free (PP_fixed_dt);
    DDS_free (PP_array_dt);
    DDS_free (PP_bseq_dt);
    DDS_free (PP_quit_dt);
    DDS_free (dpQos);
    DDS_free (tQos);
    DDS_free (dwQos);
    DDS_free (drQos);

    printf ("Completed ping example\n");
    fflush(stdout);
    return 0;
}
Beispiel #17
0
int
main (
    int argc,
    char *argv[]
    )
{
    DDS_ConditionSeq                        *conditionList;
    DDS_WaitSet                              w;
    DDS_Condition                            exp_condition;
    pong_handler                            *active_handler;

    DDS_DomainParticipantQos                 *dpQos;
    DDS_TopicQos                             *tQos;
    DDS_PublisherQos                         *pQos;
    DDS_DataWriterQos                        *dwQos;
    DDS_SubscriberQos                        *sQos;
    DDS_DataReaderQos                        *drQos;
    
    time_t                                   clock = time (NULL);
    DDS_Duration_t                           wait_timeout = {3,0};

    DDS_ReturnCode_t                         result;
    DDS_boolean                              finish_flag = FALSE;
    DDS_boolean                              timeout_flag = FALSE;
    DDS_boolean                              terminate = FALSE;

    int                                      imax = 1;
    int                                      i;
    unsigned int                             block;

    init_clock();
    /*
     * init timing statistics 
     */
    init_stats (&roundtrip,    "round_trip");
    init_stats (&write_access, "write_access");
    init_stats (&read_access,  "read_access");

    /*
     * Evaluate cmdline arguments
     */
    if (argc != 1) {
        if (argc != 6) {
            printf ("Invalid.....\n Usage: %s [blocks blocksize topic_id WRITE_PARTITION READ_PARTITION]\n", argv[0]);
            exit (1);
        }
        nof_blocks      = atoi (argv[1]);
        nof_cycles      = atoi (argv[2]);
        topic_id        = argv[3][0];
        write_partition = argv[4];
        read_partition  = argv[5];
    }

    /*
     * Create WaitSet
     */
    w = DDS_WaitSet__alloc ();
    /*
     * Initialize Qos variables
     */
    dpQos = DDS_DomainParticipantQos__alloc();
    tQos  = DDS_TopicQos__alloc();
    pQos  = DDS_PublisherQos__alloc();
    dwQos = DDS_DataWriterQos__alloc();
    sQos  = DDS_SubscriberQos__alloc();
    drQos = DDS_DataReaderQos__alloc();
    /*
     * Initialize condition list
     */
    conditionList = NULL;

    /*
     * Create participant
     */
    dpf = DDS_DomainParticipantFactory_get_instance ();
	dp = DDS_DomainParticipantFactory_create_participant (dpf, myDomain, DDS_PARTICIPANT_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);
    if (dp == DDS_HANDLE_NIL) {
        printf ("%s PING: ERROR - Splice Daemon not running", argv[0]);
        exit (1);
    }

    /* 
     * Create PING publisher
     */
    DDS_DomainParticipant_get_default_publisher_qos (dp, pQos);
    pQos->partition.name._length = 1;
    pQos->partition.name._maximum = 1;
    pQos->partition.name._buffer = DDS_StringSeq_allocbuf (1);
    pQos->partition.name._buffer[0] = DDS_string_alloc (strlen(write_partition) + 1);
    strcpy (pQos->partition.name._buffer[0], write_partition);
    p = DDS_DomainParticipant_create_publisher (dp, pQos, NULL, DDS_STATUS_MASK_NONE);
    DDS_free (pQos);

    /*
     * Create PONG subscriber
     */
    DDS_DomainParticipant_get_default_subscriber_qos (dp, sQos);
    sQos->partition.name._length = 1;
    sQos->partition.name._maximum = 1;
    sQos->partition.name._buffer = DDS_StringSeq_allocbuf (1);
    sQos->partition.name._buffer[0] = DDS_string_alloc (strlen(read_partition) + 1);
    strcpy (sQos->partition.name._buffer[0], read_partition);
    s = DDS_DomainParticipant_create_subscriber (dp, sQos, NULL, DDS_STATUS_MASK_NONE);
    DDS_free (sQos);

    /*
     * PP_min_msg
     */

    /*  Create Topic */
    PP_min_dt = pingpong_PP_min_msgTypeSupport__alloc ();
    pingpong_PP_min_msgTypeSupport_register_type (PP_min_dt, dp, "pingpong::PP_min_msg");
    PP_min_topic = DDS_DomainParticipant_create_topic (dp, "PP_min_topic", "pingpong::PP_min_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_min_writer = DDS_Publisher_create_datawriter (p, PP_min_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_min_reader = DDS_Subscriber_create_datareader (s, PP_min_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Add datareader statuscondition to waitset */
    PP_min_sc = DDS_DataReader_get_statuscondition (PP_min_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_min_sc, DDS_DATA_AVAILABLE_STATUS);
    result = DDS_WaitSet_attach_condition (w, PP_min_sc);

    /*
     * PP_seq_msg
     */

    /*  Create Topic */
    PP_seq_dt = pingpong_PP_seq_msgTypeSupport__alloc ();
    pingpong_PP_seq_msgTypeSupport_register_type (PP_seq_dt, dp, "pingpong::PP_seq_msg");
    PP_seq_topic = DDS_DomainParticipant_create_topic (dp, "PP_seq_topic", "pingpong::PP_seq_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_seq_writer = DDS_Publisher_create_datawriter (p, PP_seq_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_seq_reader = DDS_Subscriber_create_datareader (s, PP_seq_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);
    
    /* Add datareader statuscondition to waitset */
    PP_seq_sc = DDS_DataReader_get_statuscondition (PP_seq_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_seq_sc, DDS_DATA_AVAILABLE_STATUS);
    result = DDS_WaitSet_attach_condition (w, PP_seq_sc);
    
    /*
     * PP_string_msg
     */

    /*  Create Topic */
    PP_string_dt = pingpong_PP_string_msgTypeSupport__alloc ();
    pingpong_PP_string_msgTypeSupport_register_type (PP_string_dt, dp, "pingpong::PP_string_msg");
    PP_string_topic = DDS_DomainParticipant_create_topic (dp, "PP_string_topic", "pingpong::PP_string_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_string_writer = DDS_Publisher_create_datawriter (p, PP_string_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_string_reader = DDS_Subscriber_create_datareader (s, PP_string_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Add datareader statuscondition to waitset */
    PP_string_sc = DDS_DataReader_get_statuscondition (PP_string_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_string_sc, DDS_DATA_AVAILABLE_STATUS);
    result = DDS_WaitSet_attach_condition (w, PP_string_sc);
    
    /*
     * PP_fixed_msg
     */
    
    /*  Create Topic */
    PP_fixed_dt = pingpong_PP_fixed_msgTypeSupport__alloc ();
    pingpong_PP_fixed_msgTypeSupport_register_type (PP_fixed_dt, dp, "pingpong::PP_fixed_msg");
    PP_fixed_topic = DDS_DomainParticipant_create_topic (dp, "PP_fixed_topic", "pingpong::PP_fixed_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_fixed_writer = DDS_Publisher_create_datawriter (p, PP_fixed_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_fixed_reader = DDS_Subscriber_create_datareader (s, PP_fixed_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);
    
    /* Add datareader statuscondition to waitset */
    PP_fixed_sc = DDS_DataReader_get_statuscondition (PP_fixed_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_fixed_sc, DDS_DATA_AVAILABLE_STATUS);
    result = DDS_WaitSet_attach_condition (w, PP_fixed_sc);
    
    /*
     * PP_array_msg
     */
    
    /*  Create Topic */
    PP_array_dt = pingpong_PP_array_msgTypeSupport__alloc ();
    pingpong_PP_array_msgTypeSupport_register_type (PP_array_dt, dp, "pingpong::PP_array_msg");
    PP_array_topic = DDS_DomainParticipant_create_topic (dp, "PP_array_topic", "pingpong::PP_array_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_array_writer = DDS_Publisher_create_datawriter (p, PP_array_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datareader */
    PP_array_reader = DDS_Subscriber_create_datareader (s, PP_array_topic, DDS_DATAREADER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);
    
    /* Add datareader statuscondition to waitset */
    PP_array_sc = DDS_DataReader_get_statuscondition (PP_array_reader);
    DDS_StatusCondition_set_enabled_statuses (PP_array_sc, DDS_DATA_AVAILABLE_STATUS);
    result = DDS_WaitSet_attach_condition (w, PP_array_sc);

    /*
     * PP_quit_msg
     */
    
    /*  Create Topic */
    PP_quit_dt = pingpong_PP_quit_msgTypeSupport__alloc ();
    pingpong_PP_quit_msgTypeSupport_register_type (PP_quit_dt, dp, "pingpong::PP_quit_msg");
    PP_quit_topic = DDS_DomainParticipant_create_topic (dp, "PP_quit_topic", "pingpong::PP_quit_msg", DDS_TOPIC_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    /* Create datawriter */
    PP_quit_writer = DDS_Publisher_create_datawriter (p, PP_quit_topic, DDS_DATAWRITER_QOS_DEFAULT, NULL, DDS_STATUS_MASK_NONE);

    for (block = 0; block < nof_blocks ; block++) {
        while (!finish_flag) {
            /*
             * Send Initial message
             */
            timeout_flag = FALSE;
            
            switch(topic_id) {
                case 'm':
                    {
                        /* printf ("PING: sending initial ping_min\n"); */
                        pingpong_PP_min_msg *PPdata = pingpong_PP_min_msg__alloc ();
                        exp_condition = PP_min_sc;
                        active_handler = &PP_min_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        preWriteTime = timeGet ();
                        result = pingpong_PP_min_msgDataWriter_write (PP_min_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 'q':
                    {
                        /* printf ("PING: sending initial ping_seq\n"); */
                        pingpong_PP_seq_msg *PPdata = pingpong_PP_seq_msg__alloc ();
                        exp_condition = PP_seq_sc;
                        active_handler = &PP_seq_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        preWriteTime = timeGet ();
                        result = pingpong_PP_seq_msgDataWriter_write (PP_seq_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 's':
                    {
                        /* printf ("PING: sending initial ping_string\n"); */
                        pingpong_PP_string_msg *PPdata = pingpong_PP_string_msg__alloc ();
                        exp_condition = PP_string_sc;
                        active_handler = &PP_string_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        PPdata->a_string = DDS_string_alloc (8);
                        strcpy (PPdata->a_string, "a_string");
                        preWriteTime = timeGet ();
                        result = pingpong_PP_string_msgDataWriter_write (PP_string_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 'f':
                    {
                        /* printf ("PING: sending initial ping_fixed\n"); */
                        pingpong_PP_fixed_msg *PPdata = pingpong_PP_fixed_msg__alloc ();
                        exp_condition = PP_fixed_sc;
                        active_handler = &PP_fixed_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        PPdata->a_bstring = DDS_string_alloc (9);
                        strcpy (PPdata->a_bstring, "a_bstring");
                        preWriteTime = timeGet ();
                        result = pingpong_PP_fixed_msgDataWriter_write (PP_fixed_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 'a':
                    {
                        /* printf ("PING: sending initial ping_array\n"); */
                        pingpong_PP_array_msg *PPdata = pingpong_PP_array_msg__alloc ();
                        exp_condition = PP_array_sc;
                        active_handler = &PP_array_handler;
                        PPdata->count = 0;
                        PPdata->block = block;
                        preWriteTime = timeGet ();
                        result = pingpong_PP_array_msgDataWriter_write (PP_array_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                case 't':
                    {
                        /* printf ("PING: sending initial ping_quit\n"); */
                        pingpong_PP_quit_msg *PPdata = pingpong_PP_quit_msg__alloc();
                        PPdata->quit = TRUE;
                        terminate = TRUE;
                        finish_flag = TRUE;
                        preWriteTime = timeGet ();
                        result = pingpong_PP_quit_msgDataWriter_write (PP_quit_writer, PPdata, DDS_HANDLE_NIL);
                        postWriteTime = timeGet ();
                        DDS_free (PPdata);
                    }
                    break;
                default:
                    printf("Invalid topic-id\n");
                    exit(1);
            }

	    if (!terminate) {
                roundTripTime = preWriteTime;
                add_stats (&write_access, 1E6 * timeToReal (timeSub (postWriteTime, preWriteTime)));
            
                /*
                 * Wait for response, calculate timing, and send another data if not ready
                 */
                while (!(timeout_flag || finish_flag)) {
                    conditionList = DDS_ConditionSeq__alloc();
                    result = DDS_WaitSet_wait (w, conditionList, &wait_timeout);
                    if (conditionList) {
                        imax = conditionList->_length;
                        if (imax != 0) {
                            for (i = 0; i < imax; i++) {
                                if (conditionList->_buffer[i] == exp_condition) {
                                    finish_flag = active_handler (nof_cycles);
                                } else {
                                    printf ("PING: unexpected condition triggered: %x\n",
                                            (unsigned int)conditionList->_buffer[i]);
                                }
                            }
                        } else {
                            printf ("PING: TIMEOUT - message lost\n");
                            timeout_flag = TRUE;
                        }
                        DDS_free(conditionList);
                    } else {
                        printf ("PING: TIMEOUT - message lost\n");
                        timeout_flag = TRUE;
					}
                }
            }
        }
        if (!terminate) {
            finish_flag = FALSE;
            if (block == 0) {
                printf ("# PING PONG measurements (in us) \n");
                printf ("# Executed at: %s", ctime(&clock));
                printf ("#           Roundtrip time [us]             Write-access time [us]          Read-access time [us]\n");
                printf ("# Block     Count   mean    min    max      Count   mean    min    max      Count   mean    min    max\n");
            }
            printf ("%6d %10d %6.0f %6.0f %6.0f %10d %6.0f %6.0f %6.0f %10d %6.0f %6.0f %6.0f\n",
                block,
                roundtrip.count,
                roundtrip.average,
                roundtrip.min,
                roundtrip.max,
                write_access.count,
                write_access.average,
                write_access.min,
                write_access.max,
                read_access.count,
                read_access.average,
                read_access.min,
                read_access.max);
            fflush (NULL);
            init_stats (&write_access, "write_access");
            init_stats (&read_access,  "read_access");
            init_stats (&roundtrip,    "round_trip");
        }
    }
    result = DDS_Subscriber_delete_datareader (s, PP_min_reader);
    result = DDS_Publisher_delete_datawriter (p, PP_min_writer);
    result = DDS_Subscriber_delete_datareader (s, PP_seq_reader);
    result = DDS_Publisher_delete_datawriter (p, PP_seq_writer);
    result = DDS_Subscriber_delete_datareader (s, PP_string_reader);
    result = DDS_Publisher_delete_datawriter (p, PP_string_writer);
    result = DDS_Subscriber_delete_datareader (s, PP_fixed_reader);
    result = DDS_Publisher_delete_datawriter (p, PP_fixed_writer);
    result = DDS_Subscriber_delete_datareader (s, PP_array_reader);
    result = DDS_Publisher_delete_datawriter (p, PP_array_writer);
    result = DDS_Publisher_delete_datawriter (p, PP_quit_writer);
    result = DDS_DomainParticipant_delete_subscriber (dp, s);
    result = DDS_DomainParticipant_delete_publisher (dp, p);
    result = DDS_DomainParticipant_delete_topic (dp, PP_min_topic);
    result = DDS_DomainParticipant_delete_topic (dp, PP_seq_topic);
    result = DDS_DomainParticipant_delete_topic (dp, PP_string_topic);
    result = DDS_DomainParticipant_delete_topic (dp, PP_fixed_topic);
    result = DDS_DomainParticipant_delete_topic (dp, PP_array_topic);
    result = DDS_DomainParticipant_delete_topic (dp, PP_quit_topic);
    result = DDS_DomainParticipantFactory_delete_participant (dpf, dp);
    DDS_free (w);
    DDS_free (PP_min_dt);
    DDS_free (PP_seq_dt);
    DDS_free (PP_string_dt);
    DDS_free (PP_fixed_dt);
    DDS_free (PP_array_dt);
    DDS_free (PP_quit_dt);
    DDS_free (dpQos);
    DDS_free (tQos);
    DDS_free (dwQos);
    DDS_free (drQos);

    return 0;
}
/*
 * This will get data on an object
 * It gets a lot of stuff, pretty much everything that I
 * thought was reasonable to get.  However, you might have
 * a much different opinion.  Luckily, I tried to make it
 * trivial to add new items to log.
*/ 
static void get_obj_data(const struct object *obj, int y, int x, bool mon,
						 bool uniq)
{

	bool vault = square_isvault(cave, y, x);
	int number = obj->number;
	static int lvl;
	struct artifact *art;

	double gold_temp = 0;

	assert(obj->kind);

	/* get player depth */
	lvl = player->depth;

	/* check for some stuff that we will use regardless of type */
	/* originally this was armor, but I decided to generalize it */

	/* has free action (hack: don't include Inertia)*/
	if (of_has(obj->flags, OF_FREE_ACT) && 
		!((obj->tval == TV_AMULET) &&
		  (!strstr(obj->kind->name, "Inertia")))) {

			/* add the stats */
			add_stats(ST_FA_EQUIPMENT, vault, mon, number);

			/* record first level */
			first_find(ST_FF_FA);
		}


	/* has see invis */
	if (of_has(obj->flags, OF_SEE_INVIS)){

		add_stats(ST_SI_EQUIPMENT, vault, mon, number);
		first_find(ST_FF_SI);
	}
	/* has at least one basic resist */
 	if ((obj->el_info[ELEM_ACID].res_level == 1) ||
		(obj->el_info[ELEM_ELEC].res_level == 1) ||
		(obj->el_info[ELEM_COLD].res_level == 1) ||
		(obj->el_info[ELEM_FIRE].res_level == 1)){

			add_stats(ST_RESIST_EQUIPMENT, vault, mon, number);
	}

	/* has rbase */
	if ((obj->el_info[ELEM_ACID].res_level == 1) &&
		(obj->el_info[ELEM_ELEC].res_level == 1) &&
		(obj->el_info[ELEM_COLD].res_level == 1) &&
		(obj->el_info[ELEM_FIRE].res_level == 1))
		add_stats(ST_RBASE_EQUIPMENT, vault, mon, number);

	/* has resist poison */
	if (obj->el_info[ELEM_POIS].res_level == 1){

		add_stats(ST_RPOIS_EQUIPMENT, vault, mon, number);
		first_find(ST_FF_RPOIS);
		
	}
	/* has resist nexus */
	if (obj->el_info[ELEM_NEXUS].res_level == 1){

		add_stats(ST_RNEXUS_EQUIPMENT, vault, mon, number);
		first_find(ST_FF_RNEXUS);
	}
	/* has resist blind */
	if (of_has(obj->flags, OF_PROT_BLIND)){

		add_stats(ST_RBLIND_EQUIPMENT, vault, mon, number);
		first_find(ST_FF_RBLIND);
	}

	/* has resist conf */
	if (of_has(obj->flags, OF_PROT_CONF)){

		add_stats(ST_RCONF_EQUIPMENT, vault, mon, number);
		first_find(ST_FF_RCONF);
	}

	/* has speed */
	if (obj->modifiers[OBJ_MOD_SPEED] != 0)
		add_stats(ST_SPEED_EQUIPMENT, vault, mon, number);

	/* has telepathy */
	if (of_has(obj->flags, OF_TELEPATHY)){

		add_stats(ST_TELEP_EQUIPMENT, vault, mon, number);
		first_find(ST_FF_TELEP);
	}

	switch(obj->tval){

		/* armor */
		case TV_BOOTS:
		case TV_GLOVES:
		case TV_HELM:
		case TV_CROWN:
		case TV_SHIELD:
		case TV_CLOAK:
		case TV_SOFT_ARMOR:
		case TV_HARD_ARMOR:
		case TV_DRAG_ARMOR:{

			/* do not include artifacts */
			if (obj->artifact) break;

			/* add to armor total */
			add_stats(ST_ARMORS, vault, mon, number);

			/* check if bad, good, or average */
			if (obj->to_a < 0)
				add_stats(ST_BAD_ARMOR, vault, mon, number);
			if (obj->to_h == 0)
				add_stats(ST_AVERAGE_ARMOR, vault, mon, number);
			if (obj->to_h > 0)
				add_stats(ST_GOOD_ARMOR, vault, mon, number);

			/* has str boost */
			if (obj->modifiers[OBJ_MOD_STR] != 0)
				add_stats(ST_STR_ARMOR, vault, mon, number);

			/* has dex boost */
			if (obj->modifiers[OBJ_MOD_DEX] != 0)
				add_stats(ST_DEX_ARMOR, vault, mon, number);

			/* has int boost */
			if (obj->modifiers[OBJ_MOD_INT] != 0)
				add_stats(ST_INT_ARMOR, vault, mon, number);

			if (obj->modifiers[OBJ_MOD_WIS] != 0)
				add_stats(ST_WIS_ARMOR, vault, mon, number);

			if (obj->modifiers[OBJ_MOD_CON] != 0)
				add_stats(ST_CON_ARMOR, vault, mon, number);

			if (of_has(obj->flags, OF_LIGHT_CURSE))
				add_stats(ST_CURSED_ARMOR, vault, mon, number);

			break;
		}

		/* weapons */
		case TV_DIGGING:
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:{

			/* do not include artifacts */
			if (obj->artifact) break;

			/* add to weapon total */
			add_stats(ST_WEAPONS, vault, mon, number);

			/* check if bad, good, or average */
			if ((obj->to_h < 0)  && (obj->to_d < 0))
				add_stats(ST_BAD_WEAPONS, vault, mon, number);
			if ((obj->to_h == 0) && (obj->to_d == 0))
				add_stats(ST_AVERAGE_WEAPONS, vault, mon, number);
			if ((obj->to_h > 0) && (obj->to_d > 0))
				add_stats(ST_GOOD_WEAPONS, vault, mon, number);

			/* Egos by name - changes results a little */
			if (obj->ego) {
				/* slay evil */
				if (strstr(obj->ego->name, "of Slay Evil"))
					add_stats(ST_SLAYEVIL_WEAPONS, vault, mon, number);

				/* slay weapons */
				else if (strstr(obj->ego->name, "of Slay"))
					add_stats(ST_SLAY_WEAPONS, vault, mon, number);
				/* kill flag */
				if (strstr(obj->ego->name, "of *Slay"))
					add_stats(ST_KILL_WEAPONS, vault, mon, number);

				/* determine westernesse by flags */
				if (strstr(obj->ego->name, "Westernesse"))
					add_stats(ST_WESTERNESSE_WEAPONS, vault, mon, number);

				/* determine defender by flags */
				if (strstr(obj->ego->name, "Defender"))
					add_stats(ST_DEFENDER_WEAPONS, vault, mon, number);

				/* determine gondolin by flags */
				if (strstr(obj->ego->name, "Gondolin"))
					add_stats(ST_GONDOLIN_WEAPONS, vault, mon, number);

				/* determine holy avenger by flags */
				if (strstr(obj->ego->name, "Avenger"))
					add_stats(ST_HOLY_WEAPONS, vault, mon, number);

				/* is morgul */
				if (strstr(obj->ego->name, "Morgul"))
					add_stats(ST_MORGUL_WEAPONS, vault, mon, number);
			}

			/* branded weapons */
			if (obj->brands)
				add_stats(ST_BRAND_WEAPONS, vault, mon, number);

			/* extra blows */
			if (obj->modifiers[OBJ_MOD_BLOWS] > 0)
				add_stats(ST_XTRABLOWS_WEAPONS, vault, mon, number);

			/* telepathy */
			if (of_has(obj->flags, OF_TELEPATHY))
				add_stats(ST_TELEP_WEAPONS, vault, mon, number);

			/* is a top of the line weapon */
			if (((obj->tval == TV_HAFTED) &&
				 (!strstr(obj->kind->name, "Disruption"))) ||
				((obj->tval == TV_POLEARM) &&
				 (!strstr(obj->kind->name, "Slicing"))) ||
				((obj->tval == TV_SWORD) &&
				 (!strstr(obj->kind->name, "Chaos")))) {
				add_stats(ST_HUGE_WEAPONS, vault, mon, number);

				/* is uber need to fix ACB
				if ((of_has(obj->flags, OF_SLAY_EVIL)) || (obj->modifiers[OBJ_MOD_BLOWS] > 0))
				add_stats(ST_UBWE, vault, mon, number); */

			}

			break;
		}

		/* launchers */
		case TV_BOW:{

			/* do not include artifacts */
			if (obj->artifact) break;

			/* add to launcher total */
			add_stats(ST_BOWS, vault, mon, number);

			/* check if bad, average, good, or very good */
			if ((obj->to_h < 0) && (obj->to_d < 0))
				add_stats(ST_BAD_BOWS, vault, mon, number);
			if ((obj->to_h == 0) && (obj->to_d == 0))
				add_stats(ST_AVERAGE_BOWS, vault, mon, number);
			if ((obj->to_h > 0) && (obj->to_d > 0))
				add_stats(ST_GOOD_BOWS, vault, mon, number);
			if ((obj->to_h > 15) || (obj->to_d > 15))
				add_stats(ST_VERYGOOD_BOWS, vault, mon, number);

			/* check long bows and xbows for xtra might and/or shots */
			if (obj->pval > 2)
			{
				if (obj->modifiers[OBJ_MOD_SHOTS] > 0)
					add_stats(ST_XTRASHOTS_BOWS, vault, mon, number);

				if (obj->modifiers[OBJ_MOD_MIGHT] > 0)
					add_stats(ST_XTRAMIGHT_BOWS, vault, mon, number);
			}

			/* check for buckland */
			if ((obj->pval == 2) &&
				kf_has(obj->kind->kind_flags, KF_SHOOTS_SHOTS) &&
				(obj->modifiers[OBJ_MOD_MIGHT] > 0) &&
				(obj->modifiers[OBJ_MOD_SHOTS] > 0))
					add_stats(ST_BUCKLAND_BOWS, vault, mon, number);

			/* has telep */
			if (of_has(obj->flags, OF_TELEPATHY))
				add_stats(ST_TELEP_BOWS, vault, mon, number);

			/* is cursed */
			if (of_has(obj->flags, OF_LIGHT_CURSE))
				add_stats(ST_CURSED_BOWS, vault, mon, number);
			break;
		}

		/* potion */
		case TV_POTION:{

			/* Add total amounts */
			add_stats(ST_POTIONS, vault, mon, number);

			/* Stat gain */
			if (strstr(obj->kind->name, "Strength") ||
				strstr(obj->kind->name, "Intelligence") ||
				strstr(obj->kind->name, "Wisdom") ||
				strstr(obj->kind->name, "Dexterity") ||
				strstr(obj->kind->name, "Constitution")) {
				add_stats(ST_GAINSTAT_POTIONS, vault, mon, number);
			} else if (strstr(obj->kind->name, "Augmentation")) {
				/* Augmentation counts as 5 stat gain pots */
				add_stats(ST_GAINSTAT_POTIONS, vault, mon, number * 5);
			} else if (strstr(obj->kind->name, "*Enlightenment*")) {
				/* *Enlight* counts as 2 stat pots */
				add_stats(ST_GAINSTAT_POTIONS, vault, mon, number * 2);
			} else if (strstr(obj->kind->name, "Restore Mana")) {
				add_stats(ST_RESTOREMANA_POTIONS, vault, mon, number);
			} else if ((strstr(obj->kind->name, "Life")) ||
					   (strstr(obj->kind->name, "*Healing*"))) {
				add_stats(ST_ELVEN_RINGS, vault, mon, number);
			} else if (strstr(obj->kind->name, "Healing")) {
				add_stats(ST_HEALING_POTIONS, vault, mon, number);
			}
			break;
		}

		/* scrolls */
		case TV_SCROLL:{

			/* add total amounts */
			add_stats(ST_SCROLLS, vault, mon, number);

			if (strstr(obj->kind->name, "Banishment") ||
				strstr(obj->kind->name, "Mass Banishment") ||
				strstr(obj->kind->name, "Rune of Protection") ||
				strstr(obj->kind->name, "*Destruction*")) {
				add_stats(ST_ENDGAME_SCROLLS, vault, mon, number);
			} else if (strstr(obj->kind->name, "Acquirement")) {
				add_stats(ST_ACQUIRE_SCROLLS, vault, mon, number);
			} else if (strstr(obj->kind->name, "*Acquirement*")) {
				/* do the effect of 2 acquires */
				add_stats(ST_ACQUIRE_SCROLLS, vault, mon, number * 2);
			}
			break;
		}

		/* rods */
		case TV_ROD:{

			/* add to total */
			add_stats(ST_RODS, vault, mon, number);

			if (strstr(obj->kind->name, "Trap Detection") ||
				strstr(obj->kind->name, "Treasure Detection") ||
				strstr(obj->kind->name, "Door/Stair Location") ||
				strstr(obj->kind->name, "Illumination") ||
				strstr(obj->kind->name, "Light")) {
				add_stats(ST_UTILITY_RODS, vault, mon, number);
			} else if (strstr(obj->kind->name, "Teleport Other")) {
				add_stats(ST_TELEPOTHER_RODS, vault, mon, number);
			} else if (strstr(obj->kind->name, "Detection")) {
				add_stats(ST_DETECTALL_RODS, vault, mon, number);
			} else if (strstr(obj->kind->name, "Speed") ||
					   strstr(obj->kind->name, "Healing")) {
				add_stats(ST_ENDGAME_RODS, vault, mon, number);
			}
			break;
		}

		/* staves */
		case TV_STAFF:{

			add_stats(ST_STAVES, vault, mon, number);

			if (strstr(obj->kind->name, "Speed")) {
				add_stats(ST_SPEED_STAVES, vault, mon, number);
			} else if (strstr(obj->kind->name, "*Destruction*")) {
				add_stats(ST_DESTRUCTION_STAVES, vault, mon, number);
			} else if (strstr(obj->kind->name, "Dispel Evil") ||
					   strstr(obj->kind->name, "Power") ||
					   strstr(obj->kind->name, "Holiness")) {
				add_stats(ST_KILL_STAVES, vault, mon, number);
			} else if (strstr(obj->kind->name, "Healing") ||
					   strstr(obj->kind->name, "Banishment") ||
					   strstr(obj->kind->name, "the Magi")) {
				add_stats(ST_ENDGAME_STAVES, vault, mon, number);
			}
			break;
		}

		case TV_WAND:{

			add_stats(ST_WANDS, vault, mon, number);

			if (strstr(obj->kind->name, "Teleport Other"))
				add_stats(ST_TELEPOTHER_WANDS, vault, mon, number);
			break;
		}

		case TV_RING:{

			add_stats(ST_RINGS, vault, mon, number);

			/* is it cursed */
			if (of_has(obj->flags,OF_LIGHT_CURSE))
				add_stats(ST_CURSED_RINGS, vault, mon, number);

			if (strstr(obj->kind->name, "Speed")) {
				add_stats(ST_SPEEDS_RINGS, vault, mon, number);
			} else if ((strstr(obj->kind->name, "Strength")) ||
					   (strstr(obj->kind->name, "Intelligence")) ||
					   (strstr(obj->kind->name, "Dexterity")) ||
					   (strstr(obj->kind->name, "Constitution"))) {
				add_stats(ST_STAT_RINGS, vault, mon, number);
			} else if (strstr(obj->kind->name, "Resist Poison")) {
				add_stats(ST_RPOIS_RINGS, vault, mon, number);
			} else if (strstr(obj->kind->name, "Free Action")) {
				add_stats(ST_FA_RINGS, vault, mon, number);
			} else if (strstr(obj->kind->name, "See invisible")) {
				add_stats(ST_SI_RINGS, vault, mon, number);
			} else if ((strstr(obj->kind->name, "Flames")) ||
					   (strstr(obj->kind->name, "Ice")) ||
					   (strstr(obj->kind->name, "Acid")) ||
					   (strstr(obj->kind->name, "Lightning"))) {
				add_stats(ST_BRAND_RINGS, vault, mon, number);
			} else if ((strstr(obj->kind->name, "Fire")) ||
					   (strstr(obj->kind->name, "Adamant")) ||
					   (strstr(obj->kind->name, "Firmament"))) {
				add_stats(ST_ELVEN_RINGS, vault, mon, number);
			} else if (strstr(obj->kind->name, "Power")) {
				add_stats(ST_ONE_RINGS, vault, mon, number);
			}


			break;
		}

		case TV_AMULET:{

			add_stats(ST_AMULETS, vault, mon, number);

			if (strstr(obj->kind->name, "Wisdom")) {
				add_stats(ST_WIS_AMULETS, vault, mon, number);
			} else if ((strstr(obj->kind->name, "Magi")) || 
					   (strstr(obj->kind->name, "Trickery")) ||
					   (strstr(obj->kind->name, "Weaponmastery"))) {
				add_stats(ST_ENDGAME_AMULETS, vault, mon, number);
			} else if (strstr(obj->kind->name, "ESP")) {
				add_stats(ST_TELEP_AMULETS, vault, mon, number);
			}

			/* is cursed */
			if (of_has(obj->flags, OF_LIGHT_CURSE))
				add_stats(ST_CURSED_AMULETS, vault, mon, number);

			break;
		}

		case TV_SHOT:
		case TV_ARROW:
		case TV_BOLT:{

			add_stats(ST_AMMO, vault, mon, number);

			/* check if bad, average, good */
			if ((obj->to_h < 0) && (obj->to_d < 0))
				add_stats(ST_BAD_AMMO, vault, mon, number);
			if ((obj->to_h == 0) && (obj->to_d == 0))
				add_stats(ST_AVERAGE_AMMO, vault, mon, number);
			if ((obj->to_h > 0) && (obj->to_d > 0))
				add_stats(ST_GOOD_AMMO, vault, mon, number);

			if (obj->ego)
				add_stats(ST_BRANDSLAY_AMMO, vault, mon, number);

			if (strstr(obj->kind->name, "Seeker") ||
				strstr(obj->kind->name, "Mithril")) {

				/* Mithril and seeker ammo */
				add_stats(ST_VERYGOOD_AMMO, vault, mon, number);

				/* Ego mithril and seeker ammo */
				if (obj->ego) {
					add_stats(ST_AWESOME_AMMO, vault, mon, number);

					if (strstr(obj->ego->name, "of Slay Evil"))
						add_stats(ST_SLAYEVIL_AMMO, vault, mon, number);

					if (strstr(obj->ego->name, "of Holy Might"))
						add_stats(ST_HOLY_AMMO, vault, mon, number);
				}
			}
			break;
		}

		/* prayer books and magic books have the same probability 
		   only track one of them */
		case TV_MAGIC_BOOK:{

			switch(obj->sval){

				/* svals begin at 0 and end at 8 */
				case 0:{

					add_stats(ST_1ST_BOOKS, vault, mon, number);
					first_find(ST_FF_BOOK1);
					break;
				}

				case 1:{

					add_stats(ST_2ND_BOOKS, vault, mon, number);
					first_find(ST_FF_BOOK2);
					break;
				}

				case 2:{

					add_stats(ST_3RD_BOOKS, vault, mon, number);
					first_find(ST_FF_BOOK3);
					break;
				}

				case 3:{

					add_stats(ST_4TH_BOOKS, vault, mon, number);
					first_find(ST_FF_BOOK4);
					break;
				}

				case 4:{

					add_stats(ST_5TH_BOOKS, vault, mon, number);
					first_find(ST_FF_BOOK5);
					break;
				}

				case 5:{

					add_stats(ST_6TH_BOOKS, vault, mon, number);
					first_find(ST_FF_BOOK6);
					break;
				}

				case 6:{

					add_stats(ST_7TH_BOOKS, vault, mon, number);
					first_find(ST_FF_BOOK7);
					break;
				}

				case 7:{

					add_stats(ST_8TH_BOOKS, vault, mon, number);
					first_find(ST_FF_BOOK8);
					break;
				}

				case 8:{

					add_stats(ST_9TH_BOOKS, vault, mon, number);
					first_find(ST_FF_BOOK9);
					break;
				}


			}
			break;
		}
	}
	/* check to see if we have an artifact */
	if (obj->artifact){

		/* add to artifact level total */
		art_total[lvl] += addval;

		/* add to the artifact iteration total */
		if (iter < TRIES_SIZE) art_it[iter]++;

		/* Obtain the artifact info */
		art = obj->artifact;

		//debugging, print out that we found the artifact
		//msg_format("Found artifact %s",art->name);

		/* artifact is shallow */
		if (art->alloc_min < (player->depth - 20)) art_shal[lvl] += addval;

		/* artifact is close to the player depth */
		if ((art->alloc_min >= player->depth - 20) &&
			(art->alloc_min <= player->depth )) art_ave[lvl] += addval;

		/* artifact is out of depth */
		if (art->alloc_min > (player->depth)) art_ood[lvl] += addval;

		/* check to see if it's a special artifact */
		if ((obj->tval == TV_LIGHT) || (obj->tval == TV_AMULET)
			|| (obj->tval == TV_RING)){

			/* increment special artifact counter */
			art_spec[lvl] += addval;
		} else {
			/* increment normal artifacts */
			art_norm[lvl] += addval;

			/* did it come from a monster? */
			if (mon) art_mon[lvl] += addval;

			/* did it come from a unique? */
			if (uniq) art_uniq[lvl] += addval;

			/* was it in a vault? */
			if (vault){

				/* did a monster drop it ?*/
				if ((mon) || (uniq)) art_mon_vault[lvl] += addval;
				else art_vault[lvl] += addval;
			} else {
				/* was it just lyin' on the floor? */
				if ((!uniq) && (!mon)) art_floor[lvl] += addval;
			}
		}
		/* preserve the artifact */
		if (!(clearing)) art->created = FALSE;
	}

	/* Get info on gold. */
	if (obj->tval == TV_GOLD){

		int temp = obj->pval;
		gold_temp = temp;
	    gold_total[lvl] += (gold_temp / tries);

		/*From a monster? */
		if ((mon) || (uniq)) gold_mon[lvl] += (gold_temp / tries);
		else gold_floor[lvl] += (gold_temp / tries);
	}

}