Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2007, 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: profile-aggregates.c,v 1.4 2007/11/18 12:27:45 ksb Exp $ 00032 */ 00033 00034 /** 00035 * \file 00036 * Compuation of aggregates for the Contiki profiling system 00037 * \author 00038 * Adam Dunkels <adam@sics.se> 00039 */ 00040 00041 #include "sys/profile.h" 00042 00043 #include <stdlib.h> 00044 #include <stdio.h> 00045 00046 struct aggregate { 00047 const char *ptr; 00048 unsigned short episodes; 00049 unsigned long cycles; 00050 }; 00051 00052 #define DETAILED_AGGREGATES 0 00053 00054 #define MAX_CATEGORIES 32 00055 #define LIST_LEN 100 00056 00057 static struct aggregate aggregates[LIST_LEN]; 00058 00059 static int aggregates_list_ptr = 0; 00060 00061 /*---------------------------------------------------------------------------*/ 00062 static struct aggregate * 00063 find_aggregate_category(const uint16_t cat) 00064 { 00065 int i; 00066 uint16_t acat; 00067 00068 /* printf("find_aggregate_category 0x%04x %c%c\n", */ 00069 /* cat, cat >> 8, cat & 0xff); */ 00070 00071 for(i = 0; i < aggregates_list_ptr; ++i) { 00072 acat = (aggregates[i].ptr[0] << 8) + aggregates[i].ptr[1]; 00073 00074 /* printf("acat 0x%04x %c%c\n", */ 00075 /* acat, acat >> 8, acat & 0xff); */ 00076 00077 if(acat == cat) { 00078 return &aggregates[i]; 00079 } 00080 } 00081 00082 if(i == LIST_LEN) { 00083 return NULL; 00084 } 00085 00086 aggregates[aggregates_list_ptr].ptr = NULL; 00087 return &aggregates[aggregates_list_ptr++]; 00088 } 00089 /*---------------------------------------------------------------------------*/ 00090 #if DETAILED_AGGREGATES 00091 static struct aggregate * 00092 find_aggregate(const unsigned char *ptr) 00093 { 00094 int i; 00095 for(i = 0; i < aggregates_list_ptr; ++i) { 00096 if(aggregates[i].ptr == ptr) { 00097 return &aggregates[i]; 00098 } 00099 } 00100 if(i == LIST_LEN) { 00101 return NULL; 00102 } 00103 00104 return &aggregates[aggregates_list_ptr++]; 00105 } 00106 #endif /* DETAILED_AGGREGATES */ 00107 /*---------------------------------------------------------------------------*/ 00108 void 00109 profile_aggregates_print(void) 00110 { 00111 int i; 00112 00113 #if DETAILED_AGGREGATES 00114 for(i = 0; i < aggregates_list_ptr; ++i) { 00115 printf("-- %s: %lu / %u = %lu\n", aggregates[i].ptr, 00116 aggregates[i].cycles, 00117 aggregates[i].episodes, 00118 aggregates[i].cycles / aggregates[i].episodes); 00119 } 00120 #else 00121 for(i = 0; i < aggregates_list_ptr; ++i) { 00122 printf("-- %c%c: %lu / %u = %lu\n", 00123 aggregates[i].ptr[0], aggregates[i].ptr[1], 00124 aggregates[i].cycles, 00125 aggregates[i].episodes, 00126 aggregates[i].cycles / aggregates[i].episodes); 00127 } 00128 #endif 00129 00130 printf("Memory for aggregates: %d * %d = %d\n", 00131 (int)sizeof(struct aggregate), aggregates_list_ptr, 00132 (int)sizeof(struct aggregate) * aggregates_list_ptr); 00133 } 00134 /*---------------------------------------------------------------------------*/ 00135 #if DETAILED_AGGREGATES 00136 static void 00137 detailed_profile_aggregates_compute(void) 00138 { 00139 int i; 00140 rtimer_clock_t t; 00141 /* const char *str = "profile_aggregates_compute"; 00142 00143 PROFILE_TIMESTAMP(str);*/ 00144 00145 t = profile_timestamps[0].time; 00146 00147 for(i = 1; i < PROFILE_TIMESTAMP_PTR; ++i) { 00148 struct aggregate *a; 00149 a = find_aggregate(profile_timestamps[i - 1].ptr); 00150 if(a == NULL) { 00151 /* The list is full, skip this entry */ 00152 printf("profile_aggregates_compute: list full\n"); 00153 } else if(a->ptr == NULL) { 00154 a->ptr = profile_timestamps[i - 1].ptr; 00155 a->cycles = (unsigned long)(profile_timestamps[i].time - t); 00156 a->episodes = 1; 00157 } else { 00158 a->cycles += (unsigned long)(profile_timestamps[i].time - t); 00159 a->episodes++; 00160 } 00161 t = profile_timestamps[i].time; 00162 } 00163 00164 /* PROFILE_TIMESTAMP(str);*/ 00165 00166 /*printf("Aggregating time %u, len %d, list len %d, overhead %d\n", 00167 profile_timediff(str, str), PROFILE_TIMESTAMP_PTR, 00168 aggregates_list_ptr, profile_timestamp_time);*/ 00169 00170 00171 /* print_aggregates();*/ 00172 } 00173 #endif /* DETAILED_AGGREGATES */ 00174 /*---------------------------------------------------------------------------*/ 00175 static void 00176 category_profile_aggregates_compute(void) 00177 { 00178 int i,j; 00179 rtimer_clock_t t; 00180 uint16_t categories[MAX_CATEGORIES]; 00181 int categories_ptr = 0; 00182 /* const char *str = "profile_aggregates_compute"; 00183 00184 PROFILE_TIMESTAMP(str);*/ 00185 00186 t = profile_timestamps[0].time; 00187 00188 for(i = 1; i < PROFILE_TIMESTAMP_PTR; ++i) { 00189 struct aggregate *a; 00190 uint16_t cat; 00191 00192 /* printf("category_profile_aggregates_compute %s\n", */ 00193 /* profile_timestamps[i - 1].ptr); */ 00194 cat = (profile_timestamps[i - 1].ptr[0] << 8) + 00195 (profile_timestamps[i - 1].ptr[1] & 0xff); 00196 a = find_aggregate_category(cat); 00197 if(a == NULL) { 00198 /* The list is full, skip this entry */ 00199 printf("profile_aggregates_compute: list full\n"); 00200 } else if(a->ptr == NULL) { 00201 a->ptr = profile_timestamps[i - 1].ptr; 00202 a->cycles = (unsigned long)(profile_timestamps[i].time - t - profile_timestamp_time); 00203 a->episodes = 1; 00204 } else { 00205 00206 a->cycles += (unsigned long)(profile_timestamps[i].time - t - profile_timestamp_time); 00207 00208 /* Make sure that we only update the episodes of each category 00209 once per run. We keep track of all updated categories in the 00210 "categories" array. If the category is already present in the 00211 array, we do not update it. Otherwise, we insert the category 00212 in the array and update the episodes counter of the 00213 category. */ 00214 00215 for(j = 0; j < categories_ptr; ++j) { 00216 if(categories[j] == cat) { 00217 break; 00218 } 00219 } 00220 if(j == categories_ptr) { 00221 categories[j] = cat; 00222 categories_ptr++; 00223 a->episodes++; 00224 } 00225 } 00226 t = profile_timestamps[i].time; 00227 } 00228 00229 /* PROFILE_TIMESTAMP(str);*/ 00230 00231 /*printf("Aggregating time %u, len %d, list len %d, overhead %d\n", 00232 profile_timediff(str, str), PROFILE_TIMESTAMP_PTR, 00233 aggregates_list_ptr, profile_timestamp_time);*/ 00234 00235 00236 /* print_aggregates();*/ 00237 } 00238 /*---------------------------------------------------------------------------*/ 00239 void 00240 profile_aggregates_compute(void) 00241 { 00242 #if DETAILED_AGGREGATES 00243 detailed_profile_aggregates_compute(); 00244 #else 00245 category_profile_aggregates_compute(); 00246 #endif 00247 } 00248 /*---------------------------------------------------------------------------*/