Mercurial > ecos-v2_0-branch
comparison packages/infra/current/src/buffer.cxx @ 0:3111d98ba7b3 ecos-v1_1-release
Initial commit of eCos version 1.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 11:16:07 +0000 |
| parents | |
| children | 443894e2e912 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:3111d98ba7b3 |
|---|---|
| 1 //========================================================================== | |
| 2 // | |
| 3 // buffer.cxx | |
| 4 // | |
| 5 // Memory buffered trace and assert functions | |
| 6 // | |
| 7 //========================================================================== | |
| 8 //####COPYRIGHTBEGIN#### | |
| 9 // | |
| 10 // ------------------------------------------- | |
| 11 // The contents of this file are subject to the Cygnus eCos Public License | |
| 12 // Version 1.0 (the "License"); you may not use this file except in | |
| 13 // compliance with the License. You may obtain a copy of the License at | |
| 14 // http://sourceware.cygnus.com/ecos | |
| 15 // | |
| 16 // Software distributed under the License is distributed on an "AS IS" | |
| 17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the | |
| 18 // License for the specific language governing rights and limitations under | |
| 19 // the License. | |
| 20 // | |
| 21 // The Original Code is eCos - Embedded Cygnus Operating System, released | |
| 22 // September 30, 1998. | |
| 23 // | |
| 24 // The Initial Developer of the Original Code is Cygnus. Portions created | |
| 25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. | |
| 26 // ------------------------------------------- | |
| 27 // | |
| 28 //####COPYRIGHTEND#### | |
| 29 //========================================================================== | |
| 30 //#####DESCRIPTIONBEGIN#### | |
| 31 // | |
| 32 // Author(s): nickg | |
| 33 // Contributors: nickg | |
| 34 // Date: 1998-10-16 | |
| 35 // Purpose: Buffered Trace and assert functions | |
| 36 // Description: The functions in this file are a buffered implementation | |
| 37 // of the standard trace and assert functions. These store | |
| 38 // trace messages in a memory buffer and emit them when an | |
| 39 // assert is hit, or when requested to. | |
| 40 // | |
| 41 //####DESCRIPTIONEND#### | |
| 42 // | |
| 43 //========================================================================== | |
| 44 | |
| 45 #include <pkgconf/system.h> | |
| 46 #include <pkgconf/infra.h> | |
| 47 | |
| 48 #ifdef CYGDBG_INFRA_DEBUG_TRACE_ASSERT_BUFFER | |
| 49 | |
| 50 #include <cyg/infra/cyg_type.h> // base types | |
| 51 #include <cyg/infra/cyg_trac.h> // tracing macros | |
| 52 #include <cyg/infra/cyg_ass.h> // assertion macros | |
| 53 | |
| 54 #include <pkgconf/hal.h> // HAL configury | |
| 55 #include <cyg/infra/diag.h> // HAL polled output | |
| 56 #include <cyg/hal/hal_arch.h> // architectural stuff for... | |
| 57 #include <cyg/hal/hal_intr.h> // interrupt control | |
| 58 | |
| 59 #ifdef CYGPKG_KERNEL | |
| 60 #include <pkgconf/kernel.h> // kernel configury | |
| 61 #include <cyg/kernel/thread.hxx> // thread id to print | |
| 62 #include <cyg/kernel/sched.hxx> // ancillaries for above | |
| 63 #include <cyg/kernel/thread.inl> // ancillaries for above | |
| 64 #endif | |
| 65 | |
| 66 // ------------------------------------------------------------------------- | |
| 67 // Local Configuration: hack me! | |
| 68 | |
| 69 // these are generally: | |
| 70 // if 0, feature is disabled | |
| 71 // if 1, feature is enabled, printing is default width | |
| 72 // if >1, field is padded up to that width if necessary | |
| 73 // (not truncated ever) | |
| 74 | |
| 75 #define CYG_FILENAME 20 | |
| 76 #define CYG_THREADID 1 | |
| 77 #define CYG_LINENUM 4 | |
| 78 #define CYG_FUNCNAME 100 | |
| 79 #define CYG_DIAG_PRINTF 1 | |
| 80 #define CYG_FUNC_INDENT 2 | |
| 81 | |
| 82 #ifndef CYGPKG_KERNEL | |
| 83 # undef CYG_THREADID | |
| 84 # define CYG_THREADID 0 | |
| 85 #endif | |
| 86 | |
| 87 #if CYG_FUNCNAME == 1 | |
| 88 #define CYG_FBUF_SIZE 100 | |
| 89 #else | |
| 90 #define CYG_FBUF_SIZE (CYG_FUNCNAME+20) | |
| 91 #endif | |
| 92 | |
| 93 // ------------------------------------------------------------------------- | |
| 94 // Trace buffer | |
| 95 | |
| 96 #ifdef CYGDBG_USE_TRACING | |
| 97 | |
| 98 struct Cyg_TraceRecord | |
| 99 { | |
| 100 cyg_uint32 what; | |
| 101 cyg_uint32 tid; | |
| 102 char *function; | |
| 103 char *file; | |
| 104 char *message; | |
| 105 cyg_uint32 line; | |
| 106 cyg_uint32 narg; | |
| 107 CYG_ADDRWORD arg[8]; | |
| 108 }; | |
| 109 | |
| 110 Cyg_TraceRecord cyg_infra_trace_buffer[CYGDBG_INFRA_DEBUG_TRACE_BUFFER_SIZE]; | |
| 111 | |
| 112 static cyg_uint32 cyg_infra_trace_buffer_pos = 0; | |
| 113 | |
| 114 static cyg_bool cyg_infra_trace_buffer_enable = true; | |
| 115 | |
| 116 static cyg_bool cyg_infra_trace_buffer_wrap = false; | |
| 117 | |
| 118 // ------------------------------------------------------------------------- | |
| 119 // Functions to trim file names and function names down to printable lengths | |
| 120 // (these are shared between trace and assert functions) | |
| 121 | |
| 122 #if 0 | |
| 123 static char * tracepremsgs[] = { | |
| 124 " INFO:", | |
| 125 "ENTER :", | |
| 126 "ARGS :", | |
| 127 "RETURN:", | |
| 128 "bad code" | |
| 129 }; | |
| 130 #endif | |
| 131 | |
| 132 static char * tracepremsgs[] = { | |
| 133 "'", | |
| 134 "{{", | |
| 135 "((", | |
| 136 "}}", | |
| 137 "bad code" | |
| 138 }; | |
| 139 | |
| 140 static char * tracepostmsgs[] = { | |
| 141 "'", | |
| 142 "", | |
| 143 "))", | |
| 144 "", | |
| 145 "bad code" | |
| 146 }; | |
| 147 | |
| 148 static void | |
| 149 write_whattrace( cyg_uint32 what ) | |
| 150 { | |
| 151 #if CYG_FUNC_INDENT | |
| 152 static cyg_int32 cyg_indent = 0; | |
| 153 if ( 3 == what ) | |
| 154 cyg_indent -= CYG_FUNC_INDENT; | |
| 155 cyg_int32 i = cyg_indent; | |
| 156 for ( ; i > 0; i-- ) | |
| 157 diag_write_string( " " ); | |
| 158 #endif // CYG_FUNC_INDENT | |
| 159 diag_write_string( tracepremsgs[ what > 4 ? 4 : what ] ); | |
| 160 #if CYG_FUNC_INDENT | |
| 161 if ( 1 == what ) | |
| 162 cyg_indent += CYG_FUNC_INDENT; | |
| 163 #endif // CYG_FUNC_INDENT | |
| 164 } | |
| 165 | |
| 166 static void | |
| 167 write_whattracepost( cyg_uint32 what ) | |
| 168 { | |
| 169 diag_write_string( tracepostmsgs[ what > 4 ? 4 : what ] ); | |
| 170 } | |
| 171 | |
| 172 | |
| 173 #endif // CYGDBG_USE_TRACING | |
| 174 | |
| 175 // ------------------------------------------------------------------------- | |
| 176 | |
| 177 static char *trim_file(char *file) | |
| 178 { | |
| 179 #if CYG_FILENAME | |
| 180 if ( NULL == file ) | |
| 181 file = "<nofile>"; | |
| 182 | |
| 183 #if 1 == CYG_FILENAME | |
| 184 char *f = file; | |
| 185 while( *f ) f++; | |
| 186 while( *f != '/' && f != file ) f--; | |
| 187 return f==file?f:(f+1); | |
| 188 #else | |
| 189 static char fbuf2[100]; | |
| 190 char *f = file, *g = fbuf2; | |
| 191 while( *f ) f++; | |
| 192 while( *f != '/' && f != file ) f--; | |
| 193 if ( f > file ) f++; | |
| 194 while( *f ) *g++ = *f++; | |
| 195 while( CYG_FILENAME > (g - fbuf2) ) *g++ = ' '; | |
| 196 *g = 0; | |
| 197 return fbuf2; | |
| 198 #endif | |
| 199 #else | |
| 200 return ""; | |
| 201 #endif | |
| 202 } | |
| 203 | |
| 204 static char *trim_func(char *func) | |
| 205 { | |
| 206 #if CYG_FUNCNAME | |
| 207 static char fbuf[CYG_FBUF_SIZE]; | |
| 208 cyg_count32 i; | |
| 209 | |
| 210 if ( NULL == func ) | |
| 211 func = "<nofunc>"; | |
| 212 | |
| 213 for( i = 0; func[i] && func[i] != '(' && i < CYG_FBUF_SIZE-4 ; i++ ) | |
| 214 fbuf[i] = func[i]; | |
| 215 | |
| 216 fbuf[i++] = '('; | |
| 217 fbuf[i++] = ')'; | |
| 218 fbuf[i ] = 0; | |
| 219 while( i > 0 && fbuf[i] != ' ' ) i--; | |
| 220 if( i > 0 ) i++; | |
| 221 #if 1 == CYG_FUNCNAME | |
| 222 return &fbuf[i]; | |
| 223 #else | |
| 224 char *p = &fbuf[i]; | |
| 225 while ( *p ) p++; | |
| 226 while ( CYG_FUNCNAME > (p - (&fbuf[i])) ) *p++ = ' '; | |
| 227 *p = 0; | |
| 228 return &fbuf[i]; | |
| 229 #endif | |
| 230 #else | |
| 231 return ""; | |
| 232 #endif | |
| 233 } | |
| 234 | |
| 235 static void write_lnum( cyg_uint32 lnum) | |
| 236 { | |
| 237 #if CYG_LINENUM | |
| 238 diag_write_char('['); | |
| 239 #if 1 < CYG_LINENUM | |
| 240 cyg_uint32 i, j; | |
| 241 for ( i = 2, j = 100; i < CYG_LINENUM ; i++, j *= 10 ) | |
| 242 if ( lnum < j ) | |
| 243 diag_write_char(' '); | |
| 244 #endif | |
| 245 diag_write_dec(lnum); | |
| 246 diag_write_char(']'); | |
| 247 diag_write_char(' '); | |
| 248 #endif | |
| 249 } | |
| 250 | |
| 251 // ------------------------------------------------------------------------- | |
| 252 | |
| 253 #if CYG_THREADID | |
| 254 static cyg_uint32 get_tid(void) | |
| 255 { | |
| 256 | |
| 257 Cyg_Thread *t = Cyg_Thread::self(); | |
| 258 cyg_uint16 tid = 0xFFFF; | |
| 259 | |
| 260 if( t != NULL ) tid = t->get_unique_id(); | |
| 261 | |
| 262 return tid; | |
| 263 } | |
| 264 #else | |
| 265 # define get_tid() (0xFFFF) | |
| 266 #endif | |
| 267 | |
| 268 static void write_thread_id() | |
| 269 { | |
| 270 #if CYG_THREADID | |
| 271 cyg_uint16 tid = get_tid(); | |
| 272 | |
| 273 diag_write_char('<'); | |
| 274 diag_write_hex(tid); | |
| 275 diag_write_char('>'); | |
| 276 #endif | |
| 277 } | |
| 278 | |
| 279 // ------------------------------------------------------------------------- | |
| 280 // Trace functions: | |
| 281 | |
| 282 #ifdef CYGDBG_USE_TRACING | |
| 283 | |
| 284 static void print_trace_buffer(void) | |
| 285 { | |
| 286 cyg_count32 start = cyg_infra_trace_buffer_pos; | |
| 287 cyg_count32 end = start; | |
| 288 cyg_count32 i; | |
| 289 | |
| 290 // If the buffer has wrapped we want to display the records from | |
| 291 // the current pos and around back to the same place. If the buffer | |
| 292 // has not wrapped, we want to display from the start to pos. | |
| 293 | |
| 294 if( !cyg_infra_trace_buffer_wrap ) | |
| 295 start = 0; | |
| 296 | |
| 297 i = start; | |
| 298 do | |
| 299 { | |
| 300 Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[i]; | |
| 301 cyg_uint32 old_ints; | |
| 302 | |
| 303 char *psz_msg = rec->message; | |
| 304 | |
| 305 | |
| 306 HAL_DISABLE_INTERRUPTS(old_ints); | |
| 307 DIAG_DEVICE_START_SYNC(); | |
| 308 | |
| 309 if ( NULL == psz_msg ) | |
| 310 psz_msg = "<nomsg>"; | |
| 311 | |
| 312 diag_write_string( "TRACE: " ); | |
| 313 #if CYG_THREADID | |
| 314 diag_write_char('<'); | |
| 315 diag_write_hex(rec->tid); | |
| 316 diag_write_char('>'); | |
| 317 #endif | |
| 318 diag_write_string(trim_file(rec->file)); | |
| 319 write_lnum(rec->line); | |
| 320 diag_write_string(trim_func(rec->function)); | |
| 321 diag_write_char(' '); | |
| 322 write_whattrace( rec->what ); | |
| 323 #if CYG_DIAG_PRINTF | |
| 324 diag_printf( psz_msg, | |
| 325 rec->arg[0], rec->arg[1], | |
| 326 rec->arg[2], rec->arg[3], | |
| 327 rec->arg[4], rec->arg[5], | |
| 328 rec->arg[6], rec->arg[7] ); | |
| 329 #else | |
| 330 diag_write_string(psz_msg); | |
| 331 diag_write_char(' '); | |
| 332 | |
| 333 for( cyg_count8 j = 0; j < rec->narg ; j++ ) | |
| 334 { | |
| 335 diag_write_hex(rec->arg[j]); | |
| 336 diag_write_char(' '); | |
| 337 } | |
| 338 #endif | |
| 339 write_whattracepost( rec->what ); | |
| 340 diag_write_char('\n'); | |
| 341 | |
| 342 DIAG_DEVICE_END_SYNC(); | |
| 343 HAL_RESTORE_INTERRUPTS(old_ints); | |
| 344 | |
| 345 i++; | |
| 346 if( i == CYGDBG_INFRA_DEBUG_TRACE_BUFFER_SIZE ) | |
| 347 i = 0; | |
| 348 | |
| 349 } while( i != end ); | |
| 350 | |
| 351 } | |
| 352 | |
| 353 static void increment_buffer_pos() | |
| 354 { | |
| 355 cyg_infra_trace_buffer_pos++; | |
| 356 | |
| 357 if( cyg_infra_trace_buffer_pos == CYGDBG_INFRA_DEBUG_TRACE_BUFFER_SIZE ) | |
| 358 { | |
| 359 #if defined(CYGDBG_INFRA_DEBUG_TRACE_BUFFER_WRAP) | |
| 360 cyg_infra_trace_buffer_pos = 0; | |
| 361 cyg_infra_trace_buffer_wrap = true; | |
| 362 #elif defined(CYGDBG_INFRA_DEBUG_TRACE_BUFFER_HALT) | |
| 363 cyg_infra_trace_buffer_enable = false; | |
| 364 #elif defined(CYGDBG_INFRA_DEBUG_TRACE_BUFFER_PRINT) | |
| 365 print_trace_buffer(); | |
| 366 cyg_infra_trace_buffer_pos = 0; | |
| 367 cyg_infra_trace_buffer_wrap = false; | |
| 368 #else | |
| 369 #error No trace buffer full mode set | |
| 370 #endif | |
| 371 } | |
| 372 | |
| 373 } | |
| 374 | |
| 375 // ------------------------------------------------------------------------- | |
| 376 | |
| 377 externC void | |
| 378 cyg_tracenomsg( char *psz_func, char *psz_file, cyg_uint32 linenum ) | |
| 379 { | |
| 380 cyg_uint32 old_ints; | |
| 381 | |
| 382 if( !cyg_infra_trace_buffer_enable ) return; | |
| 383 | |
| 384 HAL_DISABLE_INTERRUPTS(old_ints); | |
| 385 | |
| 386 Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos]; | |
| 387 | |
| 388 rec->what = 0; | |
| 389 rec->tid = get_tid(); | |
| 390 rec->function = psz_func; | |
| 391 rec->file = psz_file; | |
| 392 rec->line = linenum; | |
| 393 rec->message = 0; | |
| 394 rec->narg = 0; | |
| 395 | |
| 396 increment_buffer_pos(); | |
| 397 | |
| 398 HAL_RESTORE_INTERRUPTS(old_ints); | |
| 399 | |
| 400 }; | |
| 401 | |
| 402 // provide every other one of these as a space/caller bloat compromise. | |
| 403 | |
| 404 externC void | |
| 405 cyg_tracemsg( cyg_uint32 what, | |
| 406 char *psz_func, char *psz_file, cyg_uint32 linenum, | |
| 407 char *psz_msg ) | |
| 408 { | |
| 409 cyg_uint32 old_ints; | |
| 410 | |
| 411 if( !cyg_infra_trace_buffer_enable ) return; | |
| 412 | |
| 413 HAL_DISABLE_INTERRUPTS(old_ints); | |
| 414 | |
| 415 Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos]; | |
| 416 | |
| 417 rec->what = what; | |
| 418 rec->tid = get_tid(); | |
| 419 rec->function = psz_func; | |
| 420 rec->file = psz_file; | |
| 421 rec->line = linenum; | |
| 422 rec->message = psz_msg; | |
| 423 rec->narg = 0; | |
| 424 | |
| 425 increment_buffer_pos(); | |
| 426 | |
| 427 HAL_RESTORE_INTERRUPTS(old_ints); | |
| 428 | |
| 429 }; | |
| 430 | |
| 431 externC void | |
| 432 cyg_tracemsg2( cyg_uint32 what, | |
| 433 char *psz_func, char *psz_file, cyg_uint32 linenum, | |
| 434 char *psz_msg, | |
| 435 CYG_ADDRWORD arg0, CYG_ADDRWORD arg1 ) | |
| 436 { | |
| 437 cyg_uint32 old_ints; | |
| 438 | |
| 439 if( !cyg_infra_trace_buffer_enable ) return; | |
| 440 | |
| 441 HAL_DISABLE_INTERRUPTS(old_ints); | |
| 442 | |
| 443 Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos]; | |
| 444 | |
| 445 rec->what = what; | |
| 446 rec->tid = get_tid(); | |
| 447 rec->function = psz_func; | |
| 448 rec->file = psz_file; | |
| 449 rec->line = linenum; | |
| 450 rec->message = psz_msg; | |
| 451 rec->narg = 2; | |
| 452 | |
| 453 rec->arg[0] = arg0; | |
| 454 rec->arg[1] = arg1; | |
| 455 | |
| 456 increment_buffer_pos(); | |
| 457 | |
| 458 HAL_RESTORE_INTERRUPTS(old_ints); | |
| 459 }; | |
| 460 | |
| 461 externC void | |
| 462 cyg_tracemsg4( cyg_uint32 what, | |
| 463 char *psz_func, char *psz_file, cyg_uint32 linenum, | |
| 464 char *psz_msg, | |
| 465 CYG_ADDRWORD arg0, CYG_ADDRWORD arg1, | |
| 466 CYG_ADDRWORD arg2, CYG_ADDRWORD arg3 ) | |
| 467 { | |
| 468 cyg_uint32 old_ints; | |
| 469 | |
| 470 if( !cyg_infra_trace_buffer_enable ) return; | |
| 471 | |
| 472 HAL_DISABLE_INTERRUPTS(old_ints); | |
| 473 | |
| 474 Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos]; | |
| 475 | |
| 476 rec->what = what; | |
| 477 rec->tid = get_tid(); | |
| 478 rec->function = psz_func; | |
| 479 rec->file = psz_file; | |
| 480 rec->line = linenum; | |
| 481 rec->message = psz_msg; | |
| 482 rec->narg = 4; | |
| 483 | |
| 484 rec->arg[0] = arg0; | |
| 485 rec->arg[1] = arg1; | |
| 486 rec->arg[2] = arg2; | |
| 487 rec->arg[3] = arg3; | |
| 488 | |
| 489 increment_buffer_pos(); | |
| 490 | |
| 491 HAL_RESTORE_INTERRUPTS(old_ints); | |
| 492 }; | |
| 493 | |
| 494 externC void | |
| 495 cyg_tracemsg6( cyg_uint32 what, | |
| 496 char *psz_func, char *psz_file, cyg_uint32 linenum, | |
| 497 char *psz_msg, | |
| 498 CYG_ADDRWORD arg0, CYG_ADDRWORD arg1, | |
| 499 CYG_ADDRWORD arg2, CYG_ADDRWORD arg3, | |
| 500 CYG_ADDRWORD arg4, CYG_ADDRWORD arg5 ) | |
| 501 { | |
| 502 cyg_uint32 old_ints; | |
| 503 | |
| 504 if( !cyg_infra_trace_buffer_enable ) return; | |
| 505 | |
| 506 HAL_DISABLE_INTERRUPTS(old_ints); | |
| 507 | |
| 508 Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos]; | |
| 509 | |
| 510 rec->what = what; | |
| 511 rec->tid = get_tid(); | |
| 512 rec->function = psz_func; | |
| 513 rec->file = psz_file; | |
| 514 rec->line = linenum; | |
| 515 rec->message = psz_msg; | |
| 516 rec->narg = 6; | |
| 517 | |
| 518 rec->arg[0] = arg0; | |
| 519 rec->arg[1] = arg1; | |
| 520 rec->arg[2] = arg2; | |
| 521 rec->arg[3] = arg3; | |
| 522 rec->arg[4] = arg4; | |
| 523 rec->arg[5] = arg5; | |
| 524 | |
| 525 increment_buffer_pos(); | |
| 526 | |
| 527 HAL_RESTORE_INTERRUPTS(old_ints); | |
| 528 }; | |
| 529 | |
| 530 externC void | |
| 531 cyg_tracemsg8( cyg_uint32 what, | |
| 532 char *psz_func, char *psz_file, cyg_uint32 linenum, | |
| 533 char *psz_msg, | |
| 534 CYG_ADDRWORD arg0, CYG_ADDRWORD arg1, | |
| 535 CYG_ADDRWORD arg2, CYG_ADDRWORD arg3, | |
| 536 CYG_ADDRWORD arg4, CYG_ADDRWORD arg5, | |
| 537 CYG_ADDRWORD arg6, CYG_ADDRWORD arg7 ) | |
| 538 { | |
| 539 cyg_uint32 old_ints; | |
| 540 | |
| 541 if( !cyg_infra_trace_buffer_enable ) return; | |
| 542 | |
| 543 HAL_DISABLE_INTERRUPTS(old_ints); | |
| 544 | |
| 545 Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos]; | |
| 546 | |
| 547 rec->what = what; | |
| 548 rec->tid = get_tid(); | |
| 549 rec->function = psz_func; | |
| 550 rec->file = psz_file; | |
| 551 rec->line = linenum; | |
| 552 rec->message = psz_msg; | |
| 553 rec->narg = 6; | |
| 554 | |
| 555 rec->arg[0] = arg0; | |
| 556 rec->arg[1] = arg1; | |
| 557 rec->arg[2] = arg2; | |
| 558 rec->arg[3] = arg3; | |
| 559 rec->arg[4] = arg4; | |
| 560 rec->arg[5] = arg5; | |
| 561 rec->arg[6] = arg6; | |
| 562 rec->arg[7] = arg7; | |
| 563 | |
| 564 increment_buffer_pos(); | |
| 565 | |
| 566 HAL_RESTORE_INTERRUPTS(old_ints); | |
| 567 }; | |
| 568 | |
| 569 // ------------------------------------------------------------------------- | |
| 570 | |
| 571 externC void | |
| 572 cyg_trace_print(void) | |
| 573 { | |
| 574 cyg_bool old_enable = cyg_infra_trace_buffer_enable; | |
| 575 cyg_infra_trace_buffer_enable = false; | |
| 576 print_trace_buffer(); | |
| 577 cyg_infra_trace_buffer_pos = 0; | |
| 578 cyg_infra_trace_buffer_wrap = false; | |
| 579 cyg_infra_trace_buffer_enable = old_enable; | |
| 580 } | |
| 581 | |
| 582 | |
| 583 // ------------------------------------------------------------------------- | |
| 584 | |
| 585 externC void | |
| 586 cyg_trace_dump(void) | |
| 587 { | |
| 588 #if defined(CYGPKG_KERNEL) && defined(CYG_DIAG_PRINTF) | |
| 589 | |
| 590 { | |
| 591 diag_printf("\nScheduler:\n\n"); | |
| 592 | |
| 593 Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler; | |
| 594 | |
| 595 diag_printf("Lock: %d\n",sched->get_sched_lock() ); | |
| 596 | |
| 597 # ifdef CYGVAR_KERNEL_THREADS_NAME | |
| 598 | |
| 599 diag_printf("Current Thread: %s\n",sched->get_current_thread()->get_name()); | |
| 600 | |
| 601 # else | |
| 602 | |
| 603 diag_printf("Current Thread: %d\n",sched->get_current_thread()->get_unique_id()); | |
| 604 | |
| 605 # endif | |
| 606 | |
| 607 } | |
| 608 | |
| 609 # ifdef CYGVAR_KERNEL_THREADS_LIST | |
| 610 | |
| 611 { | |
| 612 Cyg_Thread *t = Cyg_Thread::get_list_head(); | |
| 613 | |
| 614 diag_printf("\nThreads:\n\n"); | |
| 615 | |
| 616 while( NULL != t ) | |
| 617 { | |
| 618 cyg_uint32 state = t->get_state(); | |
| 619 char tstate[7]; | |
| 620 char *tstate1 = "SCUKX"; | |
| 621 static char *(reasons[8]) = | |
| 622 { | |
| 623 "NONE", // No recorded reason | |
| 624 "WAIT", // Wait with no timeout | |
| 625 "DELAY", // Simple time delay | |
| 626 "TIMEOUT", // Wait with timeout/timeout expired | |
| 627 "BREAK", // forced break out of sleep | |
| 628 "DESTRUCT", // wait object destroyed[note] | |
| 629 "EXIT", // forced termination | |
| 630 "DONE" // Wait/delay complete | |
| 631 }; | |
| 632 | |
| 633 if( 0 != state ) | |
| 634 { | |
| 635 // Knock out chars that do not correspond to set bits. | |
| 636 for( int i = 0; i < 6 ; i++ ) | |
| 637 if( 0 == (state & (1<<i)) ) | |
| 638 tstate[i] = ' '; | |
| 639 else tstate[i] = tstate1[i]; | |
| 640 tstate[6] = 0; | |
| 641 } | |
| 642 else tstate[0] = 'R', tstate[1] = 0; | |
| 643 | |
| 644 # ifdef CYGVAR_KERNEL_THREADS_NAME | |
| 645 | |
| 646 diag_printf( "%20s pri = %3d state = %6s id = %3d\n", | |
| 647 t->get_name(), | |
| 648 t->get_priority(), | |
| 649 tstate, | |
| 650 t->get_unique_id() | |
| 651 ); | |
| 652 # else | |
| 653 | |
| 654 diag_printf( "Thread %3d pri = %3d state = %6s\n", | |
| 655 t->get_unique_id(), | |
| 656 t->get_priority(), | |
| 657 tstate | |
| 658 ); | |
| 659 | |
| 660 # endif | |
| 661 diag_printf( "%20s stack base = %08x ptr = %08x size = %08x\n", | |
| 662 "", | |
| 663 t->get_stack_base(), | |
| 664 #ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT | |
| 665 t->get_saved_context(), | |
| 666 #else | |
| 667 0, | |
| 668 #endif | |
| 669 t->get_stack_size() | |
| 670 ); | |
| 671 | |
| 672 diag_printf( "%20s sleep reason %8s wake reason %8s\n", | |
| 673 "", | |
| 674 reasons[t->get_sleep_reason()], | |
| 675 reasons[t->get_wake_reason()] | |
| 676 ); | |
| 677 | |
| 678 diag_printf( "%20s queue = %08x wait info = %08x\n", | |
| 679 "", | |
| 680 t->get_current_queue(), | |
| 681 t->get_wait_info() | |
| 682 ); | |
| 683 | |
| 684 diag_printf("\n"); | |
| 685 t = t->get_list_next(); | |
| 686 } | |
| 687 | |
| 688 } | |
| 689 # endif // CYGVAR_KERNEL_THREADS_LIST | |
| 690 | |
| 691 #endif // CYG_DIAG_PRINTF | |
| 692 } | |
| 693 | |
| 694 #endif // CYGDBG_USE_TRACING | |
| 695 | |
| 696 // ------------------------------------------------------------------------- | |
| 697 // Assert functions: | |
| 698 | |
| 699 #ifdef CYGDBG_USE_ASSERTS | |
| 700 | |
| 701 externC void | |
| 702 cyg_assert_fail( char *psz_func, char *psz_file, cyg_uint32 linenum, | |
| 703 char *psz_msg ) | |
| 704 { | |
| 705 cyg_uint32 old_ints; | |
| 706 | |
| 707 HAL_DISABLE_INTERRUPTS(old_ints); | |
| 708 DIAG_DEVICE_START_SYNC(); | |
| 709 | |
| 710 diag_write_string("ASSERT FAIL: "); | |
| 711 write_thread_id(); | |
| 712 diag_write_string(trim_file(psz_file)); | |
| 713 write_lnum(linenum); | |
| 714 diag_write_string(trim_func(psz_func)); | |
| 715 diag_write_char(' '); | |
| 716 diag_write_string(psz_msg); | |
| 717 diag_write_char('\n'); | |
| 718 | |
| 719 #ifdef CYGDBG_INFRA_DEBUG_TRACE_BUFFER_PRINT_ON_ASSERT | |
| 720 | |
| 721 cyg_trace_print(); | |
| 722 cyg_trace_dump(); | |
| 723 | |
| 724 #endif | |
| 725 | |
| 726 for(;;); | |
| 727 | |
| 728 // DIAG_DEVICE_END_SYNC(); | |
| 729 // HAL_RESTORE_INTERRUPTS(old_ints); | |
| 730 }; | |
| 731 | |
| 732 extern "C" | |
| 733 { | |
| 734 extern unsigned long CYG_LABEL_NAME(stext); | |
| 735 extern unsigned long CYG_LABEL_NAME(etext); | |
| 736 | |
| 737 unsigned long stext_addr = (unsigned long)&CYG_LABEL_NAME(stext); | |
| 738 unsigned long etext_addr = (unsigned long)&CYG_LABEL_NAME(etext); | |
| 739 }; | |
| 740 | |
| 741 externC cyg_bool cyg_check_data_ptr(void *ptr) | |
| 742 { | |
| 743 unsigned long p = (unsigned long)ptr; | |
| 744 | |
| 745 if( p == 0 ) return false; | |
| 746 | |
| 747 if( p > stext_addr && p < etext_addr ) return false; | |
| 748 | |
| 749 return true; | |
| 750 } | |
| 751 | |
| 752 externC cyg_bool cyg_check_func_ptr(void (*ptr)(void)) | |
| 753 { | |
| 754 unsigned long p = (unsigned long)ptr; | |
| 755 | |
| 756 if( p == 0 ) return false; | |
| 757 | |
| 758 if( p < stext_addr && p > etext_addr ) return false; | |
| 759 | |
| 760 return true; | |
| 761 } | |
| 762 | |
| 763 #endif // CYGDBG_USE_ASSERTS | |
| 764 | |
| 765 #endif // CYGDBG_INFRA_DEBUG_TRACE_ASSERT_BUFFER | |
| 766 | |
| 767 // ------------------------------------------------------------------------- | |
| 768 // EOF buffer.cxx |
