Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2008, Swedish Institute of Computer Science. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 * $Id: timetable-aggregate.c,v 1.2 2008/03/13 14:27:34 fros4943 Exp $ 00032 */ 00033 00034 /** 00035 * \file 00036 * A brief description of what this file is. 00037 * \author 00038 * Adam Dunkels <adam@sics.se> 00039 */ 00040 00041 #include "sys/timetable-aggregate.h" 00042 00043 #define XXX_HACK_MAX_CATEGORIES 32 00044 00045 #include <stdio.h> 00046 00047 /*---------------------------------------------------------------------------*/ 00048 /* 00049 * 00050 * Find an aggregation category in the list of aggregates. If the 00051 * category could not be found, the function returns a pointer to an 00052 * empty entry. If the list is full, the function returns NULL. 00053 * 00054 */ 00055 static struct timetable_aggregate_entry * 00056 find_aggregate_category(struct timetable_aggregate *a, 00057 const uint16_t cat) 00058 { 00059 int i; 00060 uint16_t acat; 00061 00062 for(i = 0; i < a->ptr; ++i) { 00063 acat = (a->entries[i].id[0] << 8) + a->entries[i].id[1]; 00064 if(acat == cat) { 00065 00066 return &a->entries[i]; 00067 } 00068 } 00069 00070 if(i == a->size) { 00071 return NULL; 00072 } 00073 00074 a->entries[a->ptr].id = NULL; 00075 return &a->entries[a->ptr++]; 00076 } 00077 /*---------------------------------------------------------------------------*/ 00078 /* 00079 * 00080 * Find a specific aggregate ID in the list of aggregates. 00081 * 00082 */ 00083 static struct timetable_aggregate_entry * 00084 find_aggregate(struct timetable_aggregate *a, 00085 const char *id) 00086 { 00087 int i; 00088 for(i = 0; i < a->ptr; ++i) { 00089 if(a->entries[i].id == id) { 00090 return &a->entries[i]; 00091 } 00092 } 00093 if(i == a->size) { 00094 return NULL; 00095 } 00096 a->entries[a->ptr].id = NULL; 00097 return &a->entries[a->ptr++]; 00098 } 00099 /*---------------------------------------------------------------------------*/ 00100 void 00101 timetable_aggregate_print_detailed(struct timetable_aggregate *a) 00102 { 00103 int i; 00104 /* printf("timetable_aggregate_print_detailed: a ptr %d\n", a->ptr);*/ 00105 for(i = 0; i < a->ptr; ++i) { 00106 printf("-- %s: %lu / %u = %lu\n", a->entries[i].id, 00107 a->entries[i].time, 00108 a->entries[i].episodes, 00109 a->entries[i].time / a->entries[i].episodes); 00110 } 00111 00112 printf("Memory for entries: %d * %d = %d\n", 00113 (int)sizeof(struct timetable_aggregate), a->ptr, 00114 (int)sizeof(struct timetable_aggregate) * a->ptr); 00115 } 00116 /*---------------------------------------------------------------------------*/ 00117 void 00118 timetable_aggregate_reset(struct timetable_aggregate *a) 00119 { 00120 int i; 00121 for(i = 0; i < a->ptr; ++i) { 00122 a->entries[i].time = 0; 00123 a->entries[i].episodes = 0; 00124 } 00125 } 00126 /*---------------------------------------------------------------------------*/ 00127 void 00128 timetable_aggregate_print_categories(struct timetable_aggregate *a) 00129 { 00130 int i; 00131 00132 /* printf("timetable_aggregate_print_categories: a ptr %d\n", a->ptr);*/ 00133 for(i = 0; i < a->ptr; ++i) { 00134 printf("-- %c%c: %lu / %u = %lu\n", 00135 a->entries[i].id[0], a->entries[i].id[1], 00136 a->entries[i].time, 00137 a->entries[i].episodes, 00138 a->entries[i].time / a->entries[i].episodes); 00139 } 00140 00141 printf("Memory for entries: %d * %d = %d\n", 00142 (int)sizeof(struct timetable_aggregate), a->ptr, 00143 (int)sizeof(struct timetable_aggregate) * a->ptr); 00144 } 00145 /*---------------------------------------------------------------------------*/ 00146 void 00147 timetable_aggregate_compute_detailed(struct timetable_aggregate *a, 00148 struct timetable *timetable) 00149 { 00150 unsigned int i; 00151 rtimer_clock_t t; 00152 00153 t = timetable->timestamps[0].time; 00154 00155 for(i = 1; i < *timetable->ptr; ++i) { 00156 struct timetable_aggregate_entry *entry; 00157 entry = find_aggregate(a, timetable->timestamps[i - 1].id); 00158 if(entry == NULL) { 00159 /* The list is full, skip this entry */ 00160 /* printf("detailed_timetable_aggregate_compute: list full\n");*/ 00161 } else if(entry->id == NULL) { 00162 /* The id was found in the list, so we add it. */ 00163 entry->id = timetable->timestamps[i - 1].id; 00164 entry->time = (unsigned long)(timetable->timestamps[i].time - t - 00165 timetable_timestamp_time); 00166 entry->episodes = 1; 00167 /* printf("New entry %s %lu\n", entry->id, entry->time);*/ 00168 } else { 00169 entry->time += (unsigned long)(timetable->timestamps[i].time - t - 00170 timetable_timestamp_time); 00171 entry->episodes++; 00172 } 00173 t = timetable->timestamps[i].time; 00174 /* printf("a ptr %d\n", a->ptr);*/ 00175 } 00176 } 00177 /*---------------------------------------------------------------------------*/ 00178 void 00179 timetable_aggregate_compute_categories(struct timetable_aggregate *a, 00180 struct timetable *timetable) 00181 { 00182 unsigned int i; 00183 int j; 00184 rtimer_clock_t t; 00185 uint16_t categories[XXX_HACK_MAX_CATEGORIES]; 00186 int categories_ptr = 0; 00187 00188 t = timetable->timestamps[0].time; 00189 00190 for(i = 1; i < *timetable->ptr; ++i) { 00191 struct timetable_aggregate_entry *entry; 00192 uint16_t cat; 00193 00194 /* printf("category_timetable_aggregate_compute %s %d\n", 00195 timetable->timestamps[i - 1].id, i);*/ 00196 cat = (timetable->timestamps[i - 1].id[0] << 8) + 00197 (timetable->timestamps[i - 1].id[1] & 0xff); 00198 entry = find_aggregate_category(a, cat); 00199 if(entry == NULL) { 00200 /* The list is full, skip this entry */ 00201 /* printf("category_timetable_aggregate_compute: list full\n");*/ 00202 } else if(entry->id == NULL) { 00203 /* The category was not found in the list, so we add it. */ 00204 entry->id = timetable->timestamps[i - 1].id; 00205 entry->time = (unsigned long)(timetable->timestamps[i].time - t - 00206 timetable_timestamp_time); 00207 entry->episodes = 1; 00208 /* printf("New category %c%c time %lu\n", 00209 timetable->timestamps[i - 1].id[0], 00210 timetable->timestamps[i - 1].id[1], entry->time);*/ 00211 } else { 00212 00213 entry->time += (unsigned long)(timetable->timestamps[i].time - t - 00214 timetable_timestamp_time); 00215 /* printf("Adding time to %c%c time %lu\n", 00216 timetable->timestamps[i - 1].id[0], 00217 timetable->timestamps[i - 1].id[1], entry->time);*/ 00218 00219 /* Make sure that we only update the episodes of each category 00220 once per run. We keep track of all updated categories in the 00221 "categories" array. If the category is already present in the 00222 array, we do not update it. Otherwise, we insert the category 00223 in the array and update the episodes counter of the 00224 category. */ 00225 00226 for(j = 0; j < categories_ptr; ++j) { 00227 if(categories[j] == cat) { 00228 break; 00229 } 00230 } 00231 if(j == categories_ptr) { 00232 categories[j] = cat; 00233 categories_ptr++; 00234 entry->episodes++; 00235 } 00236 } 00237 t = timetable->timestamps[i].time; 00238 } 00239 } 00240 /*---------------------------------------------------------------------------*/