Merge pull request #434 from adamdunkels/push/cleanup-sys
Remove old unused code from the core/sys/ directory
This commit is contained in:
commit
d183b87f4b
@ -60,8 +60,8 @@ CFLAGS += -DCONTIKI=1 -DCONTIKI_TARGET_$(TARGET_UPPERCASE)=1
|
||||
|
||||
include $(CONTIKI)/core/net/rime/Makefile.rime
|
||||
include $(CONTIKI)/core/net/mac/Makefile.mac
|
||||
SYSTEM = process.c procinit.c autostart.c elfloader.c profile.c \
|
||||
timetable.c timetable-aggregate.c compower.c serial-line.c
|
||||
SYSTEM = process.c procinit.c autostart.c elfloader.c \
|
||||
compower.c serial-line.c
|
||||
THREADS = mt.c
|
||||
LIBS = memb.c mmem.c timer.c list.c etimer.c ctimer.c energest.c rtimer.c stimer.c trickle-timer.c \
|
||||
print-stats.c ifft.c crc16.c random.c checkpoint.c ringbuf.c settings.c
|
||||
|
@ -50,8 +50,6 @@
|
||||
#include "net/rime/rimestats.h"
|
||||
#include "net/netstack.h"
|
||||
|
||||
#include "sys/timetable.h"
|
||||
|
||||
#define WITH_SEND_CCA 1
|
||||
|
||||
#define FOOTER_LEN 2
|
||||
@ -615,20 +613,11 @@ cc2420_set_pan_addr(unsigned pan,
|
||||
/*
|
||||
* Interrupt leaves frame intact in FIFO.
|
||||
*/
|
||||
#if CC2420_TIMETABLE_PROFILING
|
||||
#define cc2420_timetable_size 16
|
||||
TIMETABLE(cc2420_timetable);
|
||||
TIMETABLE_AGGREGATE(aggregate_time, 10);
|
||||
#endif /* CC2420_TIMETABLE_PROFILING */
|
||||
int
|
||||
cc2420_interrupt(void)
|
||||
{
|
||||
CC2420_CLEAR_FIFOP_INT();
|
||||
process_poll(&cc2420_process);
|
||||
#if CC2420_TIMETABLE_PROFILING
|
||||
timetable_clear(&cc2420_timetable);
|
||||
TIMETABLE_TIMESTAMP(cc2420_timetable, "interrupt");
|
||||
#endif /* CC2420_TIMETABLE_PROFILING */
|
||||
|
||||
last_packet_timestamp = cc2420_sfd_start_time;
|
||||
pending++;
|
||||
@ -645,9 +634,6 @@ PROCESS_THREAD(cc2420_process, ev, data)
|
||||
|
||||
while(1) {
|
||||
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
|
||||
#if CC2420_TIMETABLE_PROFILING
|
||||
TIMETABLE_TIMESTAMP(cc2420_timetable, "poll");
|
||||
#endif /* CC2420_TIMETABLE_PROFILING */
|
||||
|
||||
PRINTF("cc2420_process: calling receiver callback\n");
|
||||
|
||||
@ -658,12 +644,6 @@ PROCESS_THREAD(cc2420_process, ev, data)
|
||||
packetbuf_set_datalen(len);
|
||||
|
||||
NETSTACK_RDC.input();
|
||||
#if CC2420_TIMETABLE_PROFILING
|
||||
TIMETABLE_TIMESTAMP(cc2420_timetable, "end");
|
||||
timetable_aggregate_compute_detailed(&aggregate_time,
|
||||
&cc2420_timetable);
|
||||
timetable_clear(&cc2420_timetable);
|
||||
#endif /* CC2420_TIMETABLE_PROFILING */
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include "net/rime/rimestats.h"
|
||||
#include "net/netstack.h"
|
||||
|
||||
#include "sys/timetable.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef CC2520_CONF_AUTOACK
|
||||
@ -593,20 +592,11 @@ cc2520_set_pan_addr(unsigned pan,
|
||||
/*
|
||||
* Interrupt leaves frame intact in FIFO.
|
||||
*/
|
||||
#if CC2520_TIMETABLE_PROFILING
|
||||
#define cc2520_timetable_size 16
|
||||
TIMETABLE(cc2520_timetable);
|
||||
TIMETABLE_AGGREGATE(aggregate_time, 10);
|
||||
#endif /* CC2520_TIMETABLE_PROFILING */
|
||||
int
|
||||
cc2520_interrupt(void)
|
||||
{
|
||||
CC2520_CLEAR_FIFOP_INT();
|
||||
process_poll(&cc2520_process);
|
||||
#if CC2520_TIMETABLE_PROFILING
|
||||
timetable_clear(&cc2520_timetable);
|
||||
TIMETABLE_TIMESTAMP(cc2520_timetable, "interrupt");
|
||||
#endif /* CC2520_TIMETABLE_PROFILING */
|
||||
|
||||
last_packet_timestamp = cc2520_sfd_start_time;
|
||||
cc2520_packets_seen++;
|
||||
@ -622,9 +612,6 @@ PROCESS_THREAD(cc2520_process, ev, data)
|
||||
|
||||
while(1) {
|
||||
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
|
||||
#if CC2520_TIMETABLE_PROFILING
|
||||
TIMETABLE_TIMESTAMP(cc2520_timetable, "poll");
|
||||
#endif /* CC2520_TIMETABLE_PROFILING */
|
||||
|
||||
PRINTF("cc2520_process: calling receiver callback\n");
|
||||
|
||||
@ -635,12 +622,6 @@ PROCESS_THREAD(cc2520_process, ev, data)
|
||||
|
||||
NETSTACK_RDC.input();
|
||||
/* flushrx(); */
|
||||
#if CC2520_TIMETABLE_PROFILING
|
||||
TIMETABLE_TIMESTAMP(cc2520_timetable, "end");
|
||||
timetable_aggregate_compute_detailed(&aggregate_time,
|
||||
&cc2520_timetable);
|
||||
timetable_clear(&cc2520_timetable);
|
||||
#endif /* CC2520_TIMETABLE_PROFILING */
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
|
@ -50,8 +50,6 @@
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#endif
|
||||
|
||||
#include "sys/timetable.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
read_data(struct rucb_conn *c)
|
||||
@ -84,10 +82,6 @@ acked(struct runicast_conn *ruc, const rimeaddr_t *to, uint8_t retransmissions)
|
||||
runicast_send(&c->c, &c->receiver, MAX_TRANSMISSIONS);
|
||||
c->last_size = len;
|
||||
|
||||
/* {
|
||||
extern struct timetable cc2420_timetable;
|
||||
timetable_print(&cc2420_timetable);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Compuation of aggregates for the Contiki profiling system
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#include "sys/profile.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct aggregate {
|
||||
const char *ptr;
|
||||
unsigned short episodes;
|
||||
unsigned long cycles;
|
||||
};
|
||||
|
||||
#define DETAILED_AGGREGATES 0
|
||||
|
||||
#define MAX_CATEGORIES 32
|
||||
#define LIST_LEN 100
|
||||
|
||||
static struct aggregate aggregates[LIST_LEN];
|
||||
|
||||
static int aggregates_list_ptr = 0;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static struct aggregate *
|
||||
find_aggregate_category(const uint16_t cat)
|
||||
{
|
||||
int i;
|
||||
uint16_t acat;
|
||||
|
||||
/* printf("find_aggregate_category 0x%04x %c%c\n", */
|
||||
/* cat, cat >> 8, cat & 0xff); */
|
||||
|
||||
for(i = 0; i < aggregates_list_ptr; ++i) {
|
||||
acat = (aggregates[i].ptr[0] << 8) + aggregates[i].ptr[1];
|
||||
|
||||
/* printf("acat 0x%04x %c%c\n", */
|
||||
/* acat, acat >> 8, acat & 0xff); */
|
||||
|
||||
if(acat == cat) {
|
||||
return &aggregates[i];
|
||||
}
|
||||
}
|
||||
|
||||
if(i == LIST_LEN) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aggregates[aggregates_list_ptr].ptr = NULL;
|
||||
return &aggregates[aggregates_list_ptr++];
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if DETAILED_AGGREGATES
|
||||
static struct aggregate *
|
||||
find_aggregate(const unsigned char *ptr)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < aggregates_list_ptr; ++i) {
|
||||
if(aggregates[i].ptr == ptr) {
|
||||
return &aggregates[i];
|
||||
}
|
||||
}
|
||||
if(i == LIST_LEN) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &aggregates[aggregates_list_ptr++];
|
||||
}
|
||||
#endif /* DETAILED_AGGREGATES */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
profile_aggregates_print(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#if DETAILED_AGGREGATES
|
||||
for(i = 0; i < aggregates_list_ptr; ++i) {
|
||||
printf("-- %s: %lu / %u = %lu\n", aggregates[i].ptr,
|
||||
aggregates[i].cycles,
|
||||
aggregates[i].episodes,
|
||||
aggregates[i].cycles / aggregates[i].episodes);
|
||||
}
|
||||
#else
|
||||
for(i = 0; i < aggregates_list_ptr; ++i) {
|
||||
printf("-- %c%c: %lu / %u = %lu\n",
|
||||
aggregates[i].ptr[0], aggregates[i].ptr[1],
|
||||
aggregates[i].cycles,
|
||||
aggregates[i].episodes,
|
||||
aggregates[i].cycles / aggregates[i].episodes);
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("Memory for aggregates: %d * %d = %d\n",
|
||||
(int)sizeof(struct aggregate), aggregates_list_ptr,
|
||||
(int)sizeof(struct aggregate) * aggregates_list_ptr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if DETAILED_AGGREGATES
|
||||
static void
|
||||
detailed_profile_aggregates_compute(void)
|
||||
{
|
||||
int i;
|
||||
rtimer_clock_t t;
|
||||
/* const char *str = "profile_aggregates_compute";
|
||||
|
||||
PROFILE_TIMESTAMP(str);*/
|
||||
|
||||
t = profile_timestamps[0].time;
|
||||
|
||||
for(i = 1; i < PROFILE_TIMESTAMP_PTR; ++i) {
|
||||
struct aggregate *a;
|
||||
a = find_aggregate(profile_timestamps[i - 1].ptr);
|
||||
if(a == NULL) {
|
||||
/* The list is full, skip this entry */
|
||||
printf("profile_aggregates_compute: list full\n");
|
||||
} else if(a->ptr == NULL) {
|
||||
a->ptr = profile_timestamps[i - 1].ptr;
|
||||
a->cycles = (unsigned long)(profile_timestamps[i].time - t);
|
||||
a->episodes = 1;
|
||||
} else {
|
||||
a->cycles += (unsigned long)(profile_timestamps[i].time - t);
|
||||
a->episodes++;
|
||||
}
|
||||
t = profile_timestamps[i].time;
|
||||
}
|
||||
|
||||
/* PROFILE_TIMESTAMP(str);*/
|
||||
|
||||
/*printf("Aggregating time %u, len %d, list len %d, overhead %d\n",
|
||||
profile_timediff(str, str), PROFILE_TIMESTAMP_PTR,
|
||||
aggregates_list_ptr, profile_timestamp_time);*/
|
||||
|
||||
|
||||
/* print_aggregates();*/
|
||||
}
|
||||
#endif /* DETAILED_AGGREGATES */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
category_profile_aggregates_compute(void)
|
||||
{
|
||||
int i,j;
|
||||
rtimer_clock_t t;
|
||||
uint16_t categories[MAX_CATEGORIES];
|
||||
int categories_ptr = 0;
|
||||
/* const char *str = "profile_aggregates_compute";
|
||||
|
||||
PROFILE_TIMESTAMP(str);*/
|
||||
|
||||
t = profile_timestamps[0].time;
|
||||
|
||||
for(i = 1; i < PROFILE_TIMESTAMP_PTR; ++i) {
|
||||
struct aggregate *a;
|
||||
uint16_t cat;
|
||||
|
||||
/* printf("category_profile_aggregates_compute %s\n", */
|
||||
/* profile_timestamps[i - 1].ptr); */
|
||||
cat = (profile_timestamps[i - 1].ptr[0] << 8) +
|
||||
(profile_timestamps[i - 1].ptr[1] & 0xff);
|
||||
a = find_aggregate_category(cat);
|
||||
if(a == NULL) {
|
||||
/* The list is full, skip this entry */
|
||||
printf("profile_aggregates_compute: list full\n");
|
||||
} else if(a->ptr == NULL) {
|
||||
a->ptr = profile_timestamps[i - 1].ptr;
|
||||
a->cycles = (unsigned long)(profile_timestamps[i].time - t - profile_timestamp_time);
|
||||
a->episodes = 1;
|
||||
} else {
|
||||
|
||||
a->cycles += (unsigned long)(profile_timestamps[i].time - t - profile_timestamp_time);
|
||||
|
||||
/* Make sure that we only update the episodes of each category
|
||||
once per run. We keep track of all updated categories in the
|
||||
"categories" array. If the category is already present in the
|
||||
array, we do not update it. Otherwise, we insert the category
|
||||
in the array and update the episodes counter of the
|
||||
category. */
|
||||
|
||||
for(j = 0; j < categories_ptr; ++j) {
|
||||
if(categories[j] == cat) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(j == categories_ptr) {
|
||||
categories[j] = cat;
|
||||
categories_ptr++;
|
||||
a->episodes++;
|
||||
}
|
||||
}
|
||||
t = profile_timestamps[i].time;
|
||||
}
|
||||
|
||||
/* PROFILE_TIMESTAMP(str);*/
|
||||
|
||||
/*printf("Aggregating time %u, len %d, list len %d, overhead %d\n",
|
||||
profile_timediff(str, str), PROFILE_TIMESTAMP_PTR,
|
||||
aggregates_list_ptr, profile_timestamp_time);*/
|
||||
|
||||
|
||||
/* print_aggregates();*/
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
profile_aggregates_compute(void)
|
||||
{
|
||||
#if DETAILED_AGGREGATES
|
||||
detailed_profile_aggregates_compute();
|
||||
#else
|
||||
category_profile_aggregates_compute();
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Implementation of the Contiki profiling system
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#include "sys/profile.h"
|
||||
#include "sys/clock.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* XXX: the profiling code is under development and may not work at
|
||||
present. */
|
||||
|
||||
|
||||
TIMETABLE_NONSTATIC(profile_timetable);
|
||||
|
||||
TIMETABLE_NONSTATIC(profile_begin_timetable);
|
||||
TIMETABLE_NONSTATIC(profile_end_timetable);
|
||||
TIMETABLE_AGGREGATE(profile_aggregate, PROFILE_AGGREGATE_SIZE);
|
||||
|
||||
static rtimer_clock_t episode_start_time;
|
||||
static unsigned int invalid_episode_overflow, invalid_episode_toolong,
|
||||
max_queuelen;
|
||||
|
||||
/* The number of fine grained ticks per coarse grained ticks. We
|
||||
currently (MSP430) have 2457600 ticks per second for the fine
|
||||
grained timer, and 32678 / 8 ticks per second for the coarse. */
|
||||
#define XXX_HACK_FINE_TICKS_PER_COARSE_TICK (2457600/(32678/8))
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
profile_init(void)
|
||||
{
|
||||
timetable_init();
|
||||
timetable_clear(&profile_begin_timetable);
|
||||
timetable_clear(&profile_end_timetable);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
profile_episode_start(void)
|
||||
{
|
||||
struct timetable_timestamp *e;
|
||||
timetable_clear(&profile_begin_timetable);
|
||||
timetable_clear(&profile_end_timetable);
|
||||
episode_start_time = clock_time();
|
||||
|
||||
e = timetable_entry(&profile_begin_timetable,
|
||||
PROFILE_TIMETABLE_SIZE - 1);
|
||||
if(e != NULL) {
|
||||
e->id = NULL;
|
||||
}
|
||||
e = timetable_entry(&profile_end_timetable,
|
||||
PROFILE_TIMETABLE_SIZE - 1);
|
||||
if(e != NULL) {
|
||||
e->id = NULL;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
profile_episode_end(void)
|
||||
{
|
||||
struct timetable_timestamp *e;
|
||||
rtimer_clock_t episode_end_time = clock_time();
|
||||
|
||||
/* printf("timetable_episode_end start %u, end %u, max time %u\n", episode_start_time, episode_end_time, 65536/FINE_TICKS_PER_COARSE_TICK); */
|
||||
e = timetable_entry(&profile_begin_timetable,
|
||||
PROFILE_TIMETABLE_SIZE - 1);
|
||||
if(e != NULL && e->id != NULL) {
|
||||
/* Invalid episode because of list overflow. */
|
||||
invalid_episode_overflow++;
|
||||
max_queuelen = PROFILE_TIMETABLE_SIZE;
|
||||
} else if(episode_end_time - episode_start_time >
|
||||
65536/XXX_HACK_FINE_TICKS_PER_COARSE_TICK) {
|
||||
/* Invalid episode because of timer overflow. */
|
||||
invalid_episode_toolong++;
|
||||
} else {
|
||||
/* Compute aggregates. */
|
||||
if(timetable_ptr(&profile_begin_timetable) > max_queuelen) {
|
||||
max_queuelen = timetable_ptr(&profile_begin_timetable);
|
||||
}
|
||||
/* timetable_aggregates_compute();*/
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
*
|
||||
* Find a specific aggregate ID in the list of aggregates.
|
||||
*
|
||||
*/
|
||||
static struct timetable_aggregate_entry *
|
||||
find_aggregate(struct timetable_aggregate *a,
|
||||
const char *id)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < a->ptr; ++i) {
|
||||
if(a->entries[i].id == id) {
|
||||
return &a->entries[i];
|
||||
}
|
||||
}
|
||||
if(i == a->size) {
|
||||
return NULL;
|
||||
}
|
||||
a->entries[a->ptr].id = NULL;
|
||||
return &a->entries[a->ptr++];
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
profile_aggregate_print_detailed(void)
|
||||
{
|
||||
int i;
|
||||
struct timetable_aggregate *a = &profile_aggregate;
|
||||
|
||||
/* printf("timetable_aggregate_print_detailed: a ptr %d\n", a->ptr);*/
|
||||
for(i = 0; i < a->ptr; ++i) {
|
||||
printf("-- %s: %lu / %u = %lu\n", a->entries[i].id,
|
||||
a->entries[i].time,
|
||||
a->entries[i].episodes,
|
||||
a->entries[i].time / a->entries[i].episodes);
|
||||
}
|
||||
|
||||
printf("Memory for entries: %d * %d = %d\n",
|
||||
(int)sizeof(struct timetable_aggregate), a->ptr,
|
||||
(int)sizeof(struct timetable_aggregate) * a->ptr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
profile_aggregate_compute_detailed(void)
|
||||
{
|
||||
int i;
|
||||
int last;
|
||||
rtimer_clock_t t;
|
||||
struct timetable_aggregate *a = &profile_aggregate;
|
||||
struct timetable *timetable = &profile_timetable;
|
||||
struct timetable_aggregate_entry *entry;
|
||||
|
||||
last = timetable_ptr(&profile_begin_timetable);
|
||||
t = profile_begin_timetable.timestamps[0].time;
|
||||
for(i = 0; i < last; ++i) {
|
||||
|
||||
entry = find_aggregate(a, profile_begin_timetable.timestamps[i].id);
|
||||
if(entry == NULL) {
|
||||
/* The list is full, skip this entry */
|
||||
/* printf("detailed_timetable_aggregate_compute: list full\n");*/
|
||||
} else if(entry->id == NULL) {
|
||||
/* The id was found in the list, so we add it. */
|
||||
entry->id = timetable->timestamps[i - 1].id;
|
||||
entry->time = (unsigned long)(timetable->timestamps[i].time - t -
|
||||
timetable_timestamp_time);
|
||||
entry->episodes = 1;
|
||||
/* printf("New entry %s %lu\n", entry->id, entry->time);*/
|
||||
} else {
|
||||
entry->time += (unsigned long)(timetable->timestamps[i].time - t -
|
||||
timetable_timestamp_time);
|
||||
entry->episodes++;
|
||||
}
|
||||
t = timetable->timestamps[i].time;
|
||||
/* printf("a ptr %d\n", a->ptr);*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Header file for the Contiki profiling system
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#ifndef __PROFILE_H__
|
||||
#define __PROFILE_H__
|
||||
|
||||
/* XXX: the profiling code is under development and may not work at
|
||||
present. */
|
||||
|
||||
#define TIMETABLE_WITH_TYPE 1
|
||||
#include "sys/timetable.h"
|
||||
|
||||
#ifdef PROFILE_CONF_TIMETABLE_SIZE
|
||||
#define PROFILE_TIMETABLE_SIZE PROFILE_CONF_TIMETABLE_SIZE
|
||||
#else
|
||||
#define PROFILE_TIMETABLE_SIZE 128
|
||||
#endif
|
||||
|
||||
#ifdef PROFILE_CONF_AGGREGATE_SIZE
|
||||
#define PROFILE_AGGREGATE_SIZE PROFILE_CONF_AGGREGATE_SIZE
|
||||
#else
|
||||
#define PROFILE_AGGREGATE_SIZE 128
|
||||
#endif
|
||||
|
||||
#define PROFILE_BEGIN(id) TIMETABLE_TIMESTAMP_TYPE(profile_timetable, id, 1)
|
||||
#define PROFILE_END(id) TIMETABLE_TIMESTAMP_TYPE(profile_timetable, id, 2)
|
||||
|
||||
/*#define PROFILE_COND_BEGIN(cond, id) TIMETABLE_COND_TIMESTAMP(profile_begin_timetable, \
|
||||
cond, id)
|
||||
#define PROFILE_COND_END(cond, id) TIMETABLE_COND_TIMESTAMP(profile_end_timetable, \
|
||||
cond, id)
|
||||
*/
|
||||
|
||||
#define profile_begin_timetable_size PROFILE_TIMETABLE_SIZE
|
||||
TIMETABLE_DECLARE(profile_begin_timetable);
|
||||
#define profile_end_timetable_size PROFILE_TIMETABLE_SIZE
|
||||
TIMETABLE_DECLARE(profile_end_timetable);
|
||||
|
||||
#define profile_timetable_size PROFILE_TIMETABLE_SIZE
|
||||
TIMETABLE_DECLARE(profile_timetable);
|
||||
|
||||
void profile_init(void);
|
||||
|
||||
void profile_episode_start(void);
|
||||
void profile_episode_end(void);
|
||||
|
||||
void profile_aggregate_print_detailed(void);
|
||||
void profile_aggregate_compute_detailed(void);
|
||||
|
||||
|
||||
#endif /* __PROFILE_H__ */
|
@ -1,239 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A brief description of what this file is.
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#include "sys/timetable-aggregate.h"
|
||||
|
||||
#define XXX_HACK_MAX_CATEGORIES 32
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
*
|
||||
* Find an aggregation category in the list of aggregates. If the
|
||||
* category could not be found, the function returns a pointer to an
|
||||
* empty entry. If the list is full, the function returns NULL.
|
||||
*
|
||||
*/
|
||||
static struct timetable_aggregate_entry *
|
||||
find_aggregate_category(struct timetable_aggregate *a,
|
||||
const uint16_t cat)
|
||||
{
|
||||
int i;
|
||||
uint16_t acat;
|
||||
|
||||
for(i = 0; i < a->ptr; ++i) {
|
||||
acat = (a->entries[i].id[0] << 8) + a->entries[i].id[1];
|
||||
if(acat == cat) {
|
||||
|
||||
return &a->entries[i];
|
||||
}
|
||||
}
|
||||
|
||||
if(i == a->size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
a->entries[a->ptr].id = NULL;
|
||||
return &a->entries[a->ptr++];
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
*
|
||||
* Find a specific aggregate ID in the list of aggregates.
|
||||
*
|
||||
*/
|
||||
static struct timetable_aggregate_entry *
|
||||
find_aggregate(struct timetable_aggregate *a,
|
||||
const char *id)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < a->ptr; ++i) {
|
||||
if(a->entries[i].id == id) {
|
||||
return &a->entries[i];
|
||||
}
|
||||
}
|
||||
if(i == a->size) {
|
||||
return NULL;
|
||||
}
|
||||
a->entries[a->ptr].id = NULL;
|
||||
return &a->entries[a->ptr++];
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
timetable_aggregate_print_detailed(struct timetable_aggregate *a)
|
||||
{
|
||||
int i;
|
||||
/* printf("timetable_aggregate_print_detailed: a ptr %d\n", a->ptr);*/
|
||||
for(i = 0; i < a->ptr; ++i) {
|
||||
printf("-- %s: %lu / %u = %lu\n", a->entries[i].id,
|
||||
a->entries[i].time,
|
||||
a->entries[i].episodes,
|
||||
a->entries[i].time / a->entries[i].episodes);
|
||||
}
|
||||
|
||||
printf("Memory for entries: %d * %d = %d\n",
|
||||
(int)sizeof(struct timetable_aggregate), a->ptr,
|
||||
(int)sizeof(struct timetable_aggregate) * a->ptr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
timetable_aggregate_reset(struct timetable_aggregate *a)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < a->ptr; ++i) {
|
||||
a->entries[i].time = 0;
|
||||
a->entries[i].episodes = 0;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
timetable_aggregate_print_categories(struct timetable_aggregate *a)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* printf("timetable_aggregate_print_categories: a ptr %d\n", a->ptr);*/
|
||||
for(i = 0; i < a->ptr; ++i) {
|
||||
printf("-- %c%c: %lu / %u = %lu\n",
|
||||
a->entries[i].id[0], a->entries[i].id[1],
|
||||
a->entries[i].time,
|
||||
a->entries[i].episodes,
|
||||
a->entries[i].time / a->entries[i].episodes);
|
||||
}
|
||||
|
||||
printf("Memory for entries: %d * %d = %d\n",
|
||||
(int)sizeof(struct timetable_aggregate), a->ptr,
|
||||
(int)sizeof(struct timetable_aggregate) * a->ptr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
timetable_aggregate_compute_detailed(struct timetable_aggregate *a,
|
||||
struct timetable *timetable)
|
||||
{
|
||||
unsigned int i;
|
||||
rtimer_clock_t t;
|
||||
|
||||
t = timetable->timestamps[0].time;
|
||||
|
||||
for(i = 1; i < *timetable->ptr; ++i) {
|
||||
struct timetable_aggregate_entry *entry;
|
||||
entry = find_aggregate(a, timetable->timestamps[i - 1].id);
|
||||
if(entry == NULL) {
|
||||
/* The list is full, skip this entry */
|
||||
/* printf("detailed_timetable_aggregate_compute: list full\n");*/
|
||||
} else if(entry->id == NULL) {
|
||||
/* The id was found in the list, so we add it. */
|
||||
entry->id = timetable->timestamps[i - 1].id;
|
||||
entry->time = (unsigned long)(timetable->timestamps[i].time - t -
|
||||
timetable_timestamp_time);
|
||||
entry->episodes = 1;
|
||||
/* printf("New entry %s %lu\n", entry->id, entry->time);*/
|
||||
} else {
|
||||
entry->time += (unsigned long)(timetable->timestamps[i].time - t -
|
||||
timetable_timestamp_time);
|
||||
entry->episodes++;
|
||||
}
|
||||
t = timetable->timestamps[i].time;
|
||||
/* printf("a ptr %d\n", a->ptr);*/
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
timetable_aggregate_compute_categories(struct timetable_aggregate *a,
|
||||
struct timetable *timetable)
|
||||
{
|
||||
unsigned int i;
|
||||
int j;
|
||||
rtimer_clock_t t;
|
||||
uint16_t categories[XXX_HACK_MAX_CATEGORIES];
|
||||
int categories_ptr = 0;
|
||||
|
||||
t = timetable->timestamps[0].time;
|
||||
|
||||
for(i = 1; i < *timetable->ptr; ++i) {
|
||||
struct timetable_aggregate_entry *entry;
|
||||
uint16_t cat;
|
||||
|
||||
/* printf("category_timetable_aggregate_compute %s %d\n",
|
||||
timetable->timestamps[i - 1].id, i);*/
|
||||
cat = (timetable->timestamps[i - 1].id[0] << 8) +
|
||||
(timetable->timestamps[i - 1].id[1] & 0xff);
|
||||
entry = find_aggregate_category(a, cat);
|
||||
if(entry == NULL) {
|
||||
/* The list is full, skip this entry */
|
||||
/* printf("category_timetable_aggregate_compute: list full\n");*/
|
||||
} else if(entry->id == NULL) {
|
||||
/* The category was not found in the list, so we add it. */
|
||||
entry->id = timetable->timestamps[i - 1].id;
|
||||
entry->time = (unsigned long)(timetable->timestamps[i].time - t -
|
||||
timetable_timestamp_time);
|
||||
entry->episodes = 1;
|
||||
/* printf("New category %c%c time %lu\n",
|
||||
timetable->timestamps[i - 1].id[0],
|
||||
timetable->timestamps[i - 1].id[1], entry->time);*/
|
||||
} else {
|
||||
|
||||
entry->time += (unsigned long)(timetable->timestamps[i].time - t -
|
||||
timetable_timestamp_time);
|
||||
/* printf("Adding time to %c%c time %lu\n",
|
||||
timetable->timestamps[i - 1].id[0],
|
||||
timetable->timestamps[i - 1].id[1], entry->time);*/
|
||||
|
||||
/* Make sure that we only update the episodes of each category
|
||||
once per run. We keep track of all updated categories in the
|
||||
"categories" array. If the category is already present in the
|
||||
array, we do not update it. Otherwise, we insert the category
|
||||
in the array and update the episodes counter of the
|
||||
category. */
|
||||
|
||||
for(j = 0; j < categories_ptr; ++j) {
|
||||
if(categories[j] == cat) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(j == categories_ptr) {
|
||||
categories[j] = cat;
|
||||
categories_ptr++;
|
||||
entry->episodes++;
|
||||
}
|
||||
}
|
||||
t = timetable->timestamps[i].time;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A brief description of what this file is.
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#ifndef __TIMETABLE_AGGREGATE_H__
|
||||
#define __TIMETABLE_AGGREGATE_H__
|
||||
|
||||
#include "sys/timetable.h"
|
||||
#include "sys/cc.h"
|
||||
|
||||
struct timetable_aggregate_entry {
|
||||
const char *id;
|
||||
unsigned short episodes;
|
||||
unsigned long time;
|
||||
};
|
||||
|
||||
struct timetable_aggregate {
|
||||
struct timetable_aggregate_entry *entries;
|
||||
int ptr;
|
||||
const int size;
|
||||
};
|
||||
|
||||
|
||||
#define TIMETABLE_AGGREGATE_DECLARE(name) \
|
||||
struct timetable_aggregate name
|
||||
|
||||
|
||||
#define TIMETABLE_AGGREGATE(name, size) \
|
||||
static struct timetable_aggregate_entry CC_CONCAT(name,_entries)[size]; \
|
||||
static struct timetable_aggregate name = { \
|
||||
CC_CONCAT(name,_entries), \
|
||||
0, \
|
||||
size \
|
||||
}
|
||||
|
||||
#define TIMETABLE_AGGREGATE_NONSTATIC(name, size) \
|
||||
static struct timetable_aggregate_entry CC_CONCAT(name,_entries)[size]; \
|
||||
struct timetable_aggregate name = { \
|
||||
CC_CONCAT(name,_entries), \
|
||||
0, \
|
||||
size \
|
||||
}
|
||||
|
||||
void timetable_aggregate_print_detailed(struct timetable_aggregate *a);
|
||||
|
||||
void timetable_aggregate_print_categories(struct timetable_aggregate *a);
|
||||
|
||||
void timetable_aggregate_reset(struct timetable_aggregate *a);
|
||||
|
||||
void timetable_aggregate_compute_detailed(struct timetable_aggregate *a,
|
||||
struct timetable *timetable);
|
||||
void timetable_aggregate_compute_categories(struct timetable_aggregate *a,
|
||||
struct timetable *timetable);
|
||||
|
||||
|
||||
|
||||
#endif /* __TIMETABLE_AGGREGATE_H__ */
|
@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Implementation of timetable, a data structure containing timestamps for events
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
#include "sys/clock.h"
|
||||
#include "sys/timetable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
rtimer_clock_t timetable_timestamp_time;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct timetable_timestamp *
|
||||
timetable_entry(struct timetable *t, int num)
|
||||
{
|
||||
if(t == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return &(t->timestamps[num]);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
timetable_ptr(struct timetable *t)
|
||||
{
|
||||
return *t->ptr;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
timetable_clear(struct timetable *t)
|
||||
{
|
||||
*t->ptr = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rtimer_clock_t
|
||||
timetable_timediff(struct timetable *t,
|
||||
const char *id1, const char *id2)
|
||||
{
|
||||
#ifdef SDCC_mcs51
|
||||
char i; /* SDCC tracker 2982753 */
|
||||
#else
|
||||
int i;
|
||||
#endif
|
||||
int t1, t2;
|
||||
|
||||
t1 = t2 = t->size;
|
||||
|
||||
for(i = *t->ptr - 1; i >= 0; --i) {
|
||||
if(t->timestamps[i].id == id1) {
|
||||
t1 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = i - 1; i >= 0; --i) {
|
||||
if(t->timestamps[i].id == id2) {
|
||||
t2 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(t1 != t->size && t2 != t->size) {
|
||||
return t->timestamps[t1].time - t->timestamps[t2].time;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
timetable_init(void)
|
||||
{
|
||||
char dummy1, dummy2;
|
||||
#define temp_size 4
|
||||
TIMETABLE_STATIC(temp);
|
||||
|
||||
timetable_clear(&temp);
|
||||
|
||||
/* Measure the time for taking a timestamp. */
|
||||
TIMETABLE_TIMESTAMP(temp, &dummy1);
|
||||
TIMETABLE_TIMESTAMP(temp, &dummy2);
|
||||
timetable_timestamp_time = timetable_timediff(&temp, &dummy1, &dummy2);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
timetable_print(struct timetable *t)
|
||||
{
|
||||
unsigned int i;
|
||||
int time;
|
||||
|
||||
time = t->timestamps[0].time;
|
||||
|
||||
printf("---\n");
|
||||
for(i = 1; i < *t->ptr; ++i) {
|
||||
printf("%s: %u\n", t->timestamps[i - 1].id, t->timestamps[i].time - time);
|
||||
time = t->timestamps[i].time;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A brief description of what this file is.
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#ifndef __TIMETABLE_H__
|
||||
#define __TIMETABLE_H__
|
||||
|
||||
#include "sys/cc.h"
|
||||
#include "sys/rtimer.h"
|
||||
|
||||
|
||||
struct timetable_timestamp {
|
||||
const char *id;
|
||||
rtimer_clock_t time;
|
||||
#if TIMETABLE_WITH_TYPE
|
||||
uint8_t type;
|
||||
#endif /* TIMETABLE_WITH_TYPE */
|
||||
};
|
||||
struct timetable {
|
||||
struct timetable_timestamp *timestamps;
|
||||
const int size;
|
||||
unsigned int * const ptr;
|
||||
};
|
||||
|
||||
#define TIMETABLE_NONSTATIC(name) \
|
||||
struct timetable_timestamp CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_size)]; \
|
||||
unsigned int CC_CONCAT(name,_ptr); \
|
||||
struct timetable name = { \
|
||||
CC_CONCAT(name,_timestamps), \
|
||||
CC_CONCAT(name,_size), \
|
||||
&CC_CONCAT(name,_ptr)}
|
||||
|
||||
#define TIMETABLE_STATIC(name) \
|
||||
static struct timetable_timestamp CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_size)]; \
|
||||
static unsigned int CC_CONCAT(name,_ptr); \
|
||||
static struct timetable name = { \
|
||||
CC_CONCAT(name,_timestamps), \
|
||||
CC_CONCAT(name,_size), \
|
||||
&CC_CONCAT(name,_ptr)}
|
||||
|
||||
#define TIMETABLE_DECLARE(name) \
|
||||
extern unsigned int CC_CONCAT(name,_ptr); \
|
||||
extern struct timetable_timestamp CC_CONCAT(name, _timestamps)[CC_CONCAT(name,_size)]; \
|
||||
extern struct timetable name
|
||||
|
||||
#define TIMETABLE(name) TIMETABLE_STATIC(name)
|
||||
|
||||
#define TIMETABLE_TIMESTAMP(name, str) \
|
||||
do { \
|
||||
CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].id = str; \
|
||||
CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].time = RTIMER_NOW(); \
|
||||
CC_CONCAT(name,_ptr) = (CC_CONCAT(name,_ptr) + 1) % \
|
||||
CC_CONCAT(name,_size); \
|
||||
} while(0)
|
||||
|
||||
#if TIMETABLE_WITH_TYPE
|
||||
#define TIMETABLE_TIMESTAMP_TYPE(name, str, t) \
|
||||
do { \
|
||||
CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].id = str; \
|
||||
CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].type = t; \
|
||||
CC_CONCAT(name,_timestamps)[CC_CONCAT(name,_ptr)].time = RTIMER_NOW(); \
|
||||
CC_CONCAT(name,_ptr) = (CC_CONCAT(name,_ptr) + 1) % \
|
||||
CC_CONCAT(name,_size); \
|
||||
} while(0)
|
||||
#else /* TIMETABLE_WITH_TYPE */
|
||||
#define TIMETABLE_TIMESTAMP_TYPE(name, str, t) TIMETABLE_TIMESTAMP(name, str)
|
||||
#endif /* TIMETABLE_WITH_TYPE */
|
||||
|
||||
|
||||
#define TIMETABLE_RESUME(name,num) \
|
||||
TIMETABLE_TIMESTAMP(CC_CONCAT(name,_timestamps[num].id))
|
||||
|
||||
#define TIMETABLE_COND_TIMESTAMP(cond,name,id) \
|
||||
do { if(cond) { \
|
||||
TIMETABLE_TIMESTAMP(id); \
|
||||
} while(0)
|
||||
|
||||
#define TIMETABLE_COND_RESUME(cond,name,num) \
|
||||
TIMETABLE_COND_TIMESTAMP(cond,name, \
|
||||
CC_CONCAT(name,_timestamps[num].id))
|
||||
|
||||
#define TIMETABLE_ENTRY(name, num) CC_CONCAT(name,_timestamps)[num]
|
||||
#define TIMETABLE_PTR(name) CC_CONCAT(name,_ptr)
|
||||
|
||||
/**
|
||||
* The time for taking a timestamp.
|
||||
*/
|
||||
extern rtimer_clock_t timetable_timestamp_time;
|
||||
|
||||
|
||||
struct timetable_timestamp *timetable_entry(struct timetable *t,
|
||||
int num);
|
||||
int timetable_ptr(struct timetable *t);
|
||||
|
||||
void timetable_clear(struct timetable *t);
|
||||
rtimer_clock_t timetable_timediff(struct timetable *t,
|
||||
const char *id1, const char *id2);
|
||||
void timetable_init(void);
|
||||
|
||||
void timetable_print(struct timetable *t);
|
||||
|
||||
#include "sys/timetable-aggregate.h"
|
||||
|
||||
#endif /* __TIMETABLE_H__ */
|
@ -67,8 +67,6 @@
|
||||
#include "net/rime/rimestats.h"
|
||||
#include "net/netstack.h"
|
||||
|
||||
#include "sys/timetable.h"
|
||||
|
||||
#define WITH_SEND_CCA 0
|
||||
|
||||
/* Timestamps have not been tested */
|
||||
@ -1277,11 +1275,6 @@ rf230_set_pan_addr(unsigned pan,
|
||||
static volatile rtimer_clock_t interrupt_time;
|
||||
static volatile int interrupt_time_set;
|
||||
#endif /* RF230_CONF_TIMESTAMPS */
|
||||
#if RF230_TIMETABLE_PROFILING
|
||||
#define rf230_timetable_size 16
|
||||
TIMETABLE(rf230_timetable);
|
||||
TIMETABLE_AGGREGATE(aggregate_time, 10);
|
||||
#endif /* RF230_TIMETABLE_PROFILING */
|
||||
int
|
||||
rf230_interrupt(void)
|
||||
{
|
||||
@ -1297,11 +1290,6 @@ if (RF230_receive_on) {
|
||||
|
||||
process_poll(&rf230_process);
|
||||
|
||||
#if RF230_TIMETABLE_PROFILING
|
||||
timetable_clear(&rf230_timetable);
|
||||
TIMETABLE_TIMESTAMP(rf230_timetable, "interrupt");
|
||||
#endif /* RF230_TIMETABLE_PROFILING */
|
||||
|
||||
rf230_pending = 1;
|
||||
|
||||
#if RADIOSTATS //TODO:This will double count buffered packets
|
||||
@ -1339,9 +1327,6 @@ PROCESS_THREAD(rf230_process, ev, data)
|
||||
while(1) {
|
||||
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
|
||||
RF230PROCESSFLAG(42);
|
||||
#if RF230_TIMETABLE_PROFILING
|
||||
TIMETABLE_TIMESTAMP(rf230_timetable, "poll");
|
||||
#endif /* RF230_TIMETABLE_PROFILING */
|
||||
|
||||
packetbuf_clear();
|
||||
|
||||
@ -1369,12 +1354,6 @@ PROCESS_THREAD(rf230_process, ev, data)
|
||||
packetbuf_set_datalen(len);
|
||||
RF230PROCESSFLAG(2);
|
||||
NETSTACK_RDC.input();
|
||||
#if RF230_TIMETABLE_PROFILING
|
||||
TIMETABLE_TIMESTAMP(rf230_timetable, "end");
|
||||
timetable_aggregate_compute_detailed(&aggregate_time,
|
||||
&rf230_timetable);
|
||||
timetable_clear(&rf230_timetable);
|
||||
#endif /* RF230_TIMETABLE_PROFILING */
|
||||
} else {
|
||||
#if RADIOSTATS
|
||||
RF230_receivefail++;
|
||||
|
@ -46,7 +46,6 @@
|
||||
|
||||
#include "cfs/cfs.h"
|
||||
#include "lib/print-stats.h"
|
||||
#include "sys/profile.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@ -60,7 +59,6 @@
|
||||
static unsigned long bytecount;
|
||||
static clock_time_t start_time;
|
||||
|
||||
extern int profile_max_queuelen;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(example_rucb_process, "Rucb example");
|
||||
@ -92,8 +90,6 @@ read_chunk(struct rucb_conn *c, int offset, char *to, int maxsize)
|
||||
|
||||
if(bytecount == FILESIZE) {
|
||||
printf("Completion time %lu / %u\n", (unsigned long)clock_time() - start_time, CLOCK_SECOND);
|
||||
/* profile_aggregates_print(); */
|
||||
/* profile_print_stats(); */
|
||||
print_stats();
|
||||
}
|
||||
|
||||
|
@ -43,44 +43,12 @@
|
||||
|
||||
#include "net/rime/timesynch.h"
|
||||
|
||||
#include "sys/profile.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(test_shell_process, "Test Contiki shell");
|
||||
AUTOSTART_PROCESSES(&test_shell_process);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if 0
|
||||
PROCESS(shell_xmacprofile_process, "xmacprofile");
|
||||
SHELL_COMMAND(xmacprofile_command,
|
||||
"xmacprofile",
|
||||
"xmacprofile: show aggregate time",
|
||||
&shell_xmacprofile_process);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define xmac_timetable_size 256
|
||||
TIMETABLE_DECLARE(xmac_timetable);
|
||||
PROCESS_THREAD(shell_xmacprofile_process, ev, data)
|
||||
{
|
||||
int i;
|
||||
char buf[40];
|
||||
PROCESS_BEGIN();
|
||||
|
||||
for(i = 0; i < xmac_timetable_size; ++i) {
|
||||
if(xmac_timetable.timestamps[i].id != NULL) {
|
||||
snprintf(buf, sizeof(buf), "%u %u \"%s\"",
|
||||
xmac_timetable.timestamps[i].time + timesynch_offset(),
|
||||
(unsigned short)xmac_timetable.timestamps[i].id,
|
||||
xmac_timetable.timestamps[i].id);
|
||||
shell_output_str(&xmacprofile_command, buf, "");
|
||||
}
|
||||
}
|
||||
/* xmacprofile_aggregate_print_detailed();*/
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(test_shell_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
@ -96,10 +64,6 @@ PROCESS_THREAD(test_shell_process, ev, data)
|
||||
shell_rime_netcmd_init();
|
||||
shell_text_init();
|
||||
|
||||
#if 0
|
||||
shell_register_command(&xmacprofile_command);
|
||||
#endif
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include "net/netstack.h"
|
||||
#include "net/rime.h"
|
||||
#include "sys/autostart.h"
|
||||
#include "sys/profile.h"
|
||||
|
||||
#include "sys/node-id.h"
|
||||
#include "lcd.h"
|
||||
|
@ -58,7 +58,6 @@
|
||||
#include "net/rime.h"
|
||||
|
||||
#include "sys/autostart.h"
|
||||
#include "sys/profile.h"
|
||||
|
||||
/* from libmc1322x */
|
||||
#include "mc1322x.h"
|
||||
@ -427,10 +426,6 @@ main(void)
|
||||
RF_CHANNEL);
|
||||
#endif /* WITH_UIP6 */
|
||||
|
||||
#if PROFILE_CONF_ON
|
||||
profile_init();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
|
||||
#if TIMESYNCH_CONF_ENABLED
|
||||
timesynch_init();
|
||||
timesynch_set_authority_level(rimeaddr_node_addr.u8[0]);
|
||||
|
@ -59,7 +59,6 @@
|
||||
#include "net/rime.h"
|
||||
|
||||
#include "sys/autostart.h"
|
||||
#include "sys/profile.h"
|
||||
|
||||
/* from libmc1322x */
|
||||
#include "mc1322x.h"
|
||||
@ -491,10 +490,6 @@ uint32_t p=(uint32_t)&__heap_end__-4;
|
||||
set_prm_mode(AUTOACK);
|
||||
#endif
|
||||
|
||||
#if PROFILE_CONF_ON
|
||||
profile_init();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
|
||||
#if TIMESYNCH_CONF_ENABLED
|
||||
timesynch_init();
|
||||
timesynch_set_authority_level(rimeaddr_node_addr.u8[0]);
|
||||
|
@ -53,7 +53,6 @@
|
||||
#include "cfs-coffee-arch.h"
|
||||
#include "cfs/cfs-coffee.h"
|
||||
#include "sys/autostart.h"
|
||||
#include "sys/profile.h"
|
||||
|
||||
#if UIP_CONF_ROUTER
|
||||
|
||||
@ -347,10 +346,6 @@ main(int argc, char **argv)
|
||||
serial_line_init();
|
||||
#endif
|
||||
|
||||
#if PROFILE_CONF_ON
|
||||
profile_init();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
|
||||
leds_off(LEDS_GREEN);
|
||||
|
||||
#if TIMESYNCH_CONF_ENABLED
|
||||
@ -409,17 +404,11 @@ main(int argc, char **argv)
|
||||
/* watchdog_stop();*/
|
||||
while(1) {
|
||||
int r;
|
||||
#if PROFILE_CONF_ON
|
||||
profile_episode_start();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
do {
|
||||
/* Reset watchdog. */
|
||||
watchdog_periodic();
|
||||
r = process_run();
|
||||
} while(r > 0);
|
||||
#if PROFILE_CONF_ON
|
||||
profile_episode_end();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
|
||||
/*
|
||||
* Idle processing.
|
||||
|
@ -52,7 +52,6 @@
|
||||
|
||||
#include "sys/node-id.h"
|
||||
#include "sys/autostart.h"
|
||||
#include "sys/profile.h"
|
||||
|
||||
#if UIP_CONF_ROUTER
|
||||
|
||||
@ -352,10 +351,6 @@ main(int argc, char **argv)
|
||||
serial_line_init();
|
||||
#endif
|
||||
|
||||
#if PROFILE_CONF_ON
|
||||
profile_init();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
|
||||
leds_off(LEDS_GREEN);
|
||||
|
||||
#if TIMESYNCH_CONF_ENABLED
|
||||
@ -412,17 +407,11 @@ main(int argc, char **argv)
|
||||
while(1) {
|
||||
|
||||
int r;
|
||||
#if PROFILE_CONF_ON
|
||||
profile_episode_start();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
do {
|
||||
/* Reset watchdog. */
|
||||
watchdog_periodic();
|
||||
r = process_run();
|
||||
} while(r > 0);
|
||||
#if PROFILE_CONF_ON
|
||||
profile_episode_end();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
|
||||
/*
|
||||
* Idle processing.
|
||||
|
@ -57,8 +57,6 @@
|
||||
#include "cfs-coffee-arch.h"
|
||||
#include "cfs/cfs-coffee.h"
|
||||
#include "sys/autostart.h"
|
||||
#include "sys/profile.h"
|
||||
|
||||
|
||||
#include "dev/battery-sensor.h"
|
||||
#include "dev/button-sensor.h"
|
||||
@ -363,10 +361,6 @@ main(int argc, char **argv)
|
||||
serial_line_init();
|
||||
#endif
|
||||
|
||||
#if PROFILE_CONF_ON
|
||||
profile_init();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
|
||||
leds_off(LEDS_GREEN);
|
||||
|
||||
#if TIMESYNCH_CONF_ENABLED
|
||||
@ -419,17 +413,11 @@ main(int argc, char **argv)
|
||||
/* watchdog_stop();*/
|
||||
while(1) {
|
||||
int r;
|
||||
#if PROFILE_CONF_ON
|
||||
profile_episode_start();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
do {
|
||||
/* Reset watchdog. */
|
||||
watchdog_periodic();
|
||||
r = process_run();
|
||||
} while(r > 0);
|
||||
#if PROFILE_CONF_ON
|
||||
profile_episode_end();
|
||||
#endif /* PROFILE_CONF_ON */
|
||||
|
||||
/*
|
||||
* Idle processing.
|
||||
|
Loading…
Reference in New Issue
Block a user