(file) Return to StatisticsM.nc CVS log (file) Jump to this file's LXR Page (dir) Up to [CENS] / tos-contrib / StatisticsTracker

File: [CENS] / tos-contrib / StatisticsTracker / StatisticsM.nc (download) / (as text)
Revision: 1.1, Wed Sep 22 17:51:26 2004 UTC (5 years, 2 months ago) by nithya
Branch: MAIN
CVS Tags: rdd_alpha_version_1, pregeonet, acoustic-05-18-06, PRE_TOSNIC_FIX, PRE_NOMEGA_MOTENIC, PRE_CEILING_FIX, PRE_64BIT, MOTENIC_PRE_BUGFIX_20050415, LAURA_CALIBRATION_EXPERIMENTS, HOSTMOTE_PROTOCOL_VERSION_7, HEAD, ESS_RELEASE_3_5, ESS_RELEASE_3_4, ESS_RELEASE_3_3, ESS_RELEASE_3_2, ESS_RELEASE_3_1, ESS_RELEASE_3_0, ESS_RELEASE_2_0, ESS_CONNECTIVITY, ESS_CENTROUTE_TESTING, ESS2-CMS-V1_5_pretest, ESS2-CMS-V1_4cMergeSympathy_2, ESS2-CMS-V1_4c, ESS2-CMS-V1_4b, ESS2-CMS-V1_4a, ESS2-CMS-V1_3, ESS2-CMS-V1_2, ESS2-CMS-V1_1, ESS2-CMS-V1_0, EMSTAR_RELEASE_2_5, EMSTAR_RELEASE_2_1_BRANCH, EMSTAR_RELEASE_2_1, EMSTAR_PRE_HTML, CYCLOPS_RELEASE_CANDIDATE_2_0, CYCLOPS_PRERELEASE_STABLE, CENTROUTE_EMSTAR_SOCKETS, BG_1_0, BANGLADESH_ARSENIC_1_2, BANGLADESH_ARSENIC_1_1, AMARSS_JR_DEPLOYMENT_6_05_07
This module can be used to track various power-related statistics (e.g.
time the radio is on, number of packets sent, time spent transmitting).

It is very easy to use - in order to indicate the start/stop of an
event, the ReportPacketEvent interface is used. n order to retreive
the latest snapshot, or to reset the stats, the RetreiveStatistics interface
is used.

StatisticsC/M provide both of these interfaces.

I implemented a milli-second granularity clock as well in order to
get ms times (o/w the options were micro-second, or 32 millisecond granularities).

/*
 * Copyright (c) 2002-2003 Intel Corporation
 * All rights reserved.
 */
                                                                                
/*
 * Authors:             Nithya Ramanathan
 *
 *
 */
                                                                                
/**
 * Generic Interface to report a countable event to the counter component
 */

includes PacketTypes;

module StatisticsM
{
  provides {
    interface StdControl;
    interface RetreiveStatistics;
    interface ReportPacketEvent;
  }
  uses {
    interface SysTime; //fixme - assuming SysTime procides time in msec!!
  }
}

implementation
{
  Statistics_t stats;
  Statistics_t stats_start; // Records when an event starts
  Statistics_t stats_on; // Indicates if an event's start time is valid!
  uint32_t start_time_msec;

  command result_t RetreiveStatistics.ResetStatistics()
  {
    memset(&stats, 0, sizeof(Statistics_t));
    memset(&stats_start, 0, sizeof(Statistics_t));
    memset(&stats_on, 0, sizeof(Statistics_t));
    start_time_msec = call SysTime.getTime32();
    return SUCCESS;
  }

  command result_t RetreiveStatistics.Retreive(Statistics_t* statistics)
  {
    uint32_t t = call SysTime.getTime32();
    atomic stats.time_total_sec = (t - start_time_msec) / 1000;
  
    // For the time related ones, we want to get the current
    // snap shot, so we just signal each to go off and then on again
    // if they were initially on.
    atomic {
      if (stats_on.time_mote_on_msec == 1) {
        call ReportPacketEvent.PacketEvent(MOTE_OFF, 0);
        call ReportPacketEvent.PacketEvent(MOTE_ON, 0);
      }
    }
    atomic {
      if (stats_on.time_radio_on_msec == 1) {
        call ReportPacketEvent.PacketEvent(RADIO_OFF, 0);
        call ReportPacketEvent.PacketEvent(RADIO_ON, 0);
      }
    }
    atomic {
      if (stats_on.time_radio_tx_msec == 1) {
        call ReportPacketEvent.PacketEvent(RADIO_STOP_SEND, 0);
        call ReportPacketEvent.PacketEvent(RADIO_START_SEND, 0);
      }
    }
    atomic {
      if (stats_on.time_sensor_on_msec == 1) {
        call ReportPacketEvent.PacketEvent(SENSOR_OFF, 0);
        call ReportPacketEvent.PacketEvent(SENSOR_ON, 0);
      }
    }
    atomic {
      if (stats_on.time_analog_sensor_on_msec == 1) {
        call ReportPacketEvent.PacketEvent(ANALOG_SENSOR_OFF, 0);
        call ReportPacketEvent.PacketEvent(ANALOG_SENSOR_ON, 0);
      }
    }

    atomic *statistics = stats;
    return SUCCESS;
  }

  command result_t StdControl.init()
  {
    return SUCCESS;
  }

  command result_t StdControl.start()
  {
    call RetreiveStatistics.ResetStatistics();
    return SUCCESS;
  }

  command result_t StdControl.stop()
  {
    return SUCCESS;
  }

  void task CallStopSend()
  {
    call ReportPacketEvent.PacketEvent(RADIO_STOP_SEND, 0);
  }

  async command result_t ReportPacketEvent.PacketEvent(uint16_t type, uint32_t seqno)
  {
    uint32_t t = 0;
    uint32_t time_diff;
                                                                                
    switch(type) {
      case(RT_SEND_DATA):
        atomic stats.num_packets_send_total++;
        atomic stats.num_rt_send_data++;
        break;
      case(RT_RECV_DATA):
        atomic stats.num_packets_recv_total++;
        atomic stats.num_rt_recv_data++;
        break;
      case(RT_SEND_NACK): 
        atomic stats.num_packets_send_total++;
        atomic stats.num_rt_send_nack++;
        break;
      case(RT_RECV_NACK):
        atomic stats.num_packets_recv_total++;
        atomic stats.num_rt_recv_nack++;
        break;
      case(DSDV_MSG_SEND ):
        atomic stats.num_packets_send_total++;
        atomic stats.num_dsdv_sent++;
        break;
      case(DSDV_MSG_RECV ):
        atomic stats.num_packets_recv_total++;
        atomic stats.num_dsdv_recv++;
        break;
      case(CONTROL_POWERSAVE_PACKETS_SEND):  
        atomic stats.num_packets_send_total++;
        atomic stats.num_ps_send_ctrl++;
        break;
      case(CONTROL_POWERSAVE_PACKETS_RECV ):
        atomic stats.num_packets_recv_total++;
        atomic stats.num_ps_recv_ctrl++;
        break;
      case(CONTROL_DATASCHEDULER_PACKETS_SEND): 
        atomic stats.num_packets_send_total++;
        atomic stats.num_ds_send_ctrl++;
        break;
      case(CONTROL_DATASCHEDULER_PACKETS_RECV): 
        atomic stats.num_packets_recv_total++;
        atomic stats.num_ds_recv_ctrl++;
        break;
      case(MISC_PACKET_RX ):
        atomic stats.num_packets_recv_total++;
        break;
      case(MISC_PACKET_TX ):
        atomic stats.num_packets_send_total++;
        break;

      // The remainder are time-based
      default:
        t = call SysTime.getTime32();
        switch(type) {
	  case(MOTE_ON):  
            atomic {
            if (stats_on.time_mote_on_msec == 0) {
              stats_start.time_mote_on_msec = t;
              stats_on.time_mote_on_msec = 1;
            }
            }
	    break;
          case(MOTE_OFF): 
            atomic {
              if (stats_on.time_mote_on_msec == 1) {
                time_diff = t - stats_start.time_mote_on_msec;
                stats.time_mote_on_msec += time_diff;
                stats_on.time_mote_on_msec = 0;
              }
            }
	    break;
	  case(RADIO_ON):  // includes idle mode and Receive mode
            atomic {
            if (stats_on.time_radio_on_msec == 0) {
              stats.num_ds_recv_ctrl++; // fixme DEBUGGING! Take this out
              atomic stats_start.time_radio_on_msec = t;
              atomic stats_on.time_radio_on_msec = 1;
            }
            }
	    break;
	  case(RADIO_OFF):  
            atomic {
              if (stats_on.time_radio_on_msec == 1) {
              stats.num_ds_send_ctrl++; // fixme DEBUGGING! Take this out
                time_diff = t - stats_start.time_radio_on_msec;
	        stats.time_radio_on_msec += time_diff;
	        stats_on.time_radio_on_msec = 0;

                // If the radio was sending, and not turned off, then we know
                // it stopped sending!
	        if (stats_on.time_radio_tx_msec == 1) { 
                  post CallStopSend();
                }
              }
            }
	    break;
	  case(RADIO_START_SEND): 
            atomic {
              if (stats_on.time_radio_tx_msec == 0) {
                stats_start.time_radio_tx_msec = t;
                stats_on.time_radio_tx_msec = 1;
              }
            }
	    break;
	  case(RADIO_STOP_SEND): 
            atomic {
              if (stats_on.time_radio_tx_msec == 1) {
                time_diff = t - stats_start.time_radio_tx_msec;
                stats.time_radio_tx_msec += time_diff;
                stats_on.time_radio_tx_msec = 0;
              }
            }
	    break;
	  case(SENSOR_ON): 
            atomic {
            if (stats_on.time_sensor_on_msec == 0) {
              stats_start.time_sensor_on_msec = t;
              stats_on.time_sensor_on_msec = 1;
            }
            }
	    break;
	  case(SENSOR_OFF):
            atomic {
              if (stats_on.time_sensor_on_msec == 1) {
	        time_diff = t - stats_start.time_sensor_on_msec;
	        stats.time_sensor_on_msec += time_diff;
	        stats_on.time_sensor_on_msec = 0;
              }
            }
	    break;
	  case(ANALOG_SENSOR_ON ):
            atomic {
              if (stats_on.time_analog_sensor_on_msec == 0) {
	        stats_start.time_analog_sensor_on_msec = t;
                stats_on.time_analog_sensor_on_msec = 1;
              }
            }
	    break;
	  case(ANALOG_SENSOR_OFF ):
            atomic {
              if (stats_on.time_analog_sensor_on_msec == 1) {
	        time_diff = t - stats_start.time_analog_sensor_on_msec;
	        stats.time_analog_sensor_on_msec += time_diff;
	        stats_on.time_analog_sensor_on_msec = 0;
              }
            }
	    break;
        }
        break;
    }
    return SUCCESS;
  }
}

CENS CVS Mailing List
Powered by
ViewCVS 0.9.2