1 //==========================================================================
3 // instrmnt/meminst.cxx
5 // Memory buffer instrumentation functions
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: nickg, andrew.lunn@ascom.ch
46 // Purpose: Instrumentation functions
47 // Description: The functions in this file are implementations of the
48 // standard instrumentation functions that place records
49 // into a memory buffer.
51 //####DESCRIPTIONEND####
53 //==========================================================================
55 #include <pkgconf/kernel.h>
57 #include <cyg/kernel/ktypes.h> // base kernel types
58 #include <cyg/infra/cyg_trac.h> // tracing macros
59 #include <cyg/infra/cyg_ass.h> // assertion macros
60 #include <cyg/kernel/instrmnt.h> // instrumentation
62 #include <cyg/kernel/intr.hxx> // interrupt control
63 #include <cyg/kernel/sched.hxx> // scheduler defines
65 #include <cyg/kernel/sched.inl> // scheduler inlines
66 #include <cyg/kernel/clock.inl> // clock inlines
68 #ifdef CYGPKG_KERNEL_INSTRUMENT
70 // -------------------------------------------------------------------------
71 // Instrumentation record.
73 struct Instrument_Record
75 CYG_WORD16 type; // record type
76 CYG_WORD16 thread; // current thread id
77 CYG_WORD timestamp; // 32 bit timestamp
78 CYG_WORD arg1; // first arg
79 CYG_WORD arg2; // second arg
82 // -------------------------------------------------------------------------
83 // Buffer base and end. This buffer must be a whole number of
85 #ifdef CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER
87 externC Instrument_Record instrument_buffer[];
88 externC cyg_uint32 instrument_buffer_size;
95 Instrument_Record instrument_buffer[CYGNUM_KERNEL_INSTRUMENT_BUFFER_SIZE];
97 cyg_uint32 instrument_buffer_size = CYGNUM_KERNEL_INSTRUMENT_BUFFER_SIZE;
106 #define instrument_buffer_start instrument_buffer[0]
107 #define instrument_buffer_end instrument_buffer[instrument_buffer_size]
111 Instrument_Record *instrument_buffer_pointer = &instrument_buffer_start;
114 #ifdef CYGDBG_KERNEL_INSTRUMENT_FLAGS
116 // This array contains a 32 bit word for each event class. The
117 // bits in the word correspond to events. By setting or clearing
118 // the appropriate bit, the selected instrumentation event may
119 // be enabled or disabled dynamically.
121 cyg_uint32 instrument_flags[(CYG_INSTRUMENT_CLASS_MAX>>8)+1];
127 // -------------------------------------------------------------------------
129 #ifdef CYGPKG_KERNEL_SMP_SUPPORT
131 HAL_SPINLOCK_TYPE instrument_lock = HAL_SPINLOCK_INIT_CLEAR;
135 #define HAL_SPINLOCK_SPIN( __lock )
137 #define HAL_SPINLOCK_CLEAR( __lock )
141 // -------------------------------------------------------------------------
143 void cyg_instrument( cyg_uint32 type, CYG_ADDRWORD arg1, CYG_ADDRWORD arg2 )
148 #ifdef CYGDBG_KERNEL_INSTRUMENT_FLAGS
150 cyg_ucount8 cl = (type>>8)&0xff;
151 cyg_ucount8 event = type&0xff;
153 if( instrument_flags[cl] & (1<<event) )
156 HAL_DISABLE_INTERRUPTS(old_ints);
157 HAL_SPINLOCK_SPIN( instrument_lock );
159 Instrument_Record *p = instrument_buffer_pointer;
160 Cyg_Thread *t = Cyg_Scheduler::get_current_thread();
162 p->thread = (t==0)?0x0FFF:t->get_unique_id();
163 #ifdef CYGPKG_KERNEL_SMP_SUPPORT
164 // Add CPU id to in top 4 bytes of thread id
165 p->thread = (p->thread&0x0FFF)|(CYG_KERNEL_CPU_THIS()<<12);
167 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
168 // p->timestamp = Cyg_Clock::real_time_clock->current_value_lo();
169 HAL_CLOCK_READ( &p->timestamp );
177 #ifdef CYGDBG_KERNEL_INSTRUMENT_BUFFER_WRAP
178 if( p == &instrument_buffer_end )
179 instrument_buffer_pointer = &instrument_buffer_start;
180 else instrument_buffer_pointer = p;
182 // when not wrapping, just continue to put further entries
184 if( p != &instrument_buffer_end )
185 instrument_buffer_pointer = p;
187 HAL_SPINLOCK_CLEAR( instrument_lock );
188 HAL_RESTORE_INTERRUPTS(old_ints);
194 // -------------------------------------------------------------------------
195 // Functions to enable and disable selected instrumentation events
196 // when the flags are enabled.
198 #ifdef CYGDBG_KERNEL_INSTRUMENT_FLAGS
200 externC void cyg_instrument_enable( cyg_uint32 cl, cyg_uint32 event)
203 instrument_flags[cl>>8] |= 1<<event;
205 instrument_flags[cl>>8] = ~0;
208 externC void cyg_instrument_disable( cyg_uint32 cl, cyg_uint32 event)
211 instrument_flags[cl>>8] &= ~(1<<event);
213 instrument_flags[cl>>8] = 0;
217 externC cyg_bool cyg_instrument_state( cyg_uint32 cl, cyg_uint32 event)
219 return (instrument_flags[cl>>8] & (1<<event)) != 0;
224 // -------------------------------------------------------------------------
226 #ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS
227 #define CYGDBG_KERNEL_INSTRUMENT_MSGS_DEFINE_TABLE
228 #include <cyg/kernel/instrument_desc.h>
229 #define NELEM(x) (sizeof(x)/sizeof*(x))
230 externC char * cyg_instrument_msg(CYG_WORD16 type) {
232 struct instrument_desc_s *record;
233 struct instrument_desc_s *end_record;
236 record = instrument_desc;
237 end_record = &instrument_desc[NELEM(instrument_desc)-1];
239 event = type & 0x00ff;
241 while ((record != end_record) && (record->num != cl)) {
245 if (record->num == cl) {
247 while ((record != end_record) && (record->num != event) &&
248 (record->num < 0xff)) {
252 if (record->num == event) {
253 return (record->msg);
256 return("Unknown event");
258 #endif // CYGDBG_KERNEL_INSTRUMENT_MSGS
259 #endif // CYGPKG_KERNEL_INSTRUMENT
261 // EOF instrmnt/meminst.cxx