2 * Copyright (c) 2007, Swedish Institute of Computer Science.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * This file is part of the Contiki operating system.
31 * $Id: profile.c,v 1.4 2008/01/17 12:19:26 adamdunkels Exp $
36 * Implementation of the Contiki profiling system
38 * Adam Dunkels <adam@sics.se>
41 #include "sys/profile.h"
42 #include "sys/clock.h"
46 /* XXX: the profiling code is under development and may not work at
50 TIMETABLE_NONSTATIC(profile_timetable
);
52 TIMETABLE_NONSTATIC(profile_begin_timetable
);
53 TIMETABLE_NONSTATIC(profile_end_timetable
);
54 TIMETABLE_AGGREGATE(profile_aggregate
, PROFILE_AGGREGATE_SIZE
);
56 static rtimer_clock_t episode_start_time
;
57 static unsigned int invalid_episode_overflow
, invalid_episode_toolong
,
60 /* The number of fine grained ticks per coarse grained ticks. We
61 currently (MSP430) have 2457600 ticks per second for the fine
62 grained timer, and 32678 / 8 ticks per second for the coarse. */
63 #define XXX_HACK_FINE_TICKS_PER_COARSE_TICK (2457600/(32678/8))
65 /*---------------------------------------------------------------------------*/
70 timetable_clear(&profile_begin_timetable
);
71 timetable_clear(&profile_end_timetable
);
73 /*---------------------------------------------------------------------------*/
75 profile_episode_start(void)
77 struct timetable_timestamp
*e
;
78 timetable_clear(&profile_begin_timetable
);
79 timetable_clear(&profile_end_timetable
);
80 episode_start_time
= clock_time();
82 e
= timetable_entry(&profile_begin_timetable
,
83 PROFILE_TIMETABLE_SIZE
- 1);
87 e
= timetable_entry(&profile_end_timetable
,
88 PROFILE_TIMETABLE_SIZE
- 1);
93 /*---------------------------------------------------------------------------*/
95 profile_episode_end(void)
97 struct timetable_timestamp
*e
;
98 rtimer_clock_t episode_end_time
= clock_time();
100 /* printf("timetable_episode_end start %u, end %u, max time %u\n", episode_start_time, episode_end_time, 65536/FINE_TICKS_PER_COARSE_TICK); */
101 e
= timetable_entry(&profile_begin_timetable
,
102 PROFILE_TIMETABLE_SIZE
- 1);
103 if(e
!= NULL
&& e
->id
!= NULL
) {
104 /* Invalid episode because of list overflow. */
105 invalid_episode_overflow
++;
106 max_queuelen
= PROFILE_TIMETABLE_SIZE
;
107 } else if(episode_end_time
- episode_start_time
>
108 65536/XXX_HACK_FINE_TICKS_PER_COARSE_TICK
) {
109 /* Invalid episode because of timer overflow. */
110 invalid_episode_toolong
++;
112 /* Compute aggregates. */
113 if(timetable_ptr(&profile_begin_timetable
) > max_queuelen
) {
114 max_queuelen
= timetable_ptr(&profile_begin_timetable
);
116 /* timetable_aggregates_compute();*/
119 /*---------------------------------------------------------------------------*/
122 * Find a specific aggregate ID in the list of aggregates.
125 static struct timetable_aggregate_entry
*
126 find_aggregate(struct timetable_aggregate
*a
,
130 for(i
= 0; i
< a
->ptr
; ++i
) {
131 if(a
->entries
[i
].id
== id
) {
132 return &a
->entries
[i
];
138 a
->entries
[a
->ptr
].id
= NULL
;
139 return &a
->entries
[a
->ptr
++];
141 /*---------------------------------------------------------------------------*/
143 profile_aggregate_print_detailed(void)
146 struct timetable_aggregate
*a
= &profile_aggregate
;
148 /* printf("timetable_aggregate_print_detailed: a ptr %d\n", a->ptr);*/
149 for(i
= 0; i
< a
->ptr
; ++i
) {
150 printf("-- %s: %lu / %u = %lu\n", a
->entries
[i
].id
,
152 a
->entries
[i
].episodes
,
153 a
->entries
[i
].time
/ a
->entries
[i
].episodes
);
156 printf("Memory for entries: %d * %d = %d\n",
157 (int)sizeof(struct timetable_aggregate
), a
->ptr
,
158 (int)sizeof(struct timetable_aggregate
) * a
->ptr
);
160 /*---------------------------------------------------------------------------*/
162 profile_aggregate_compute_detailed(void)
167 struct timetable_aggregate
*a
= &profile_aggregate
;
168 struct timetable
*timetable
= &profile_timetable
;
169 struct timetable_aggregate_entry
*entry
;
171 last
= timetable_ptr(&profile_begin_timetable
);
172 t
= profile_begin_timetable
.timestamps
[0].time
;
173 for(i
= 0; i
< last
; ++i
) {
175 entry
= find_aggregate(a
, profile_begin_timetable
.timestamps
[i
].id
);
177 /* The list is full, skip this entry */
178 /* printf("detailed_timetable_aggregate_compute: list full\n");*/
179 } else if(entry
->id
== NULL
) {
180 /* The id was found in the list, so we add it. */
181 entry
->id
= timetable
->timestamps
[i
- 1].id
;
182 entry
->time
= (unsigned long)(timetable
->timestamps
[i
].time
- t
-
183 timetable_timestamp_time
);
185 /* printf("New entry %s %lu\n", entry->id, entry->time);*/
187 entry
->time
+= (unsigned long)(timetable
->timestamps
[i
].time
- t
-
188 timetable_timestamp_time
);
191 t
= timetable
->timestamps
[i
].time
;
192 /* printf("a ptr %d\n", a->ptr);*/
197 /*---------------------------------------------------------------------------*/