Mercurial > ecos-v2_0-branch
changeset 460:a65a4055f146
* src/common/kapi.cxx:
* include/kapi.h:
Added function cyg_thread_get_next(), cyg_thread_find() and
cyg_thread_get_info() to allow the current set of threads to be
enumerated, and per-thread information to be retrieved safely.
* doc/kernel.sgml: Documented new KAPI calls.
* src/common/thread.cxx: Zero unique_id in thread destructor so
that a stale thread pointer can be checked for validity.
* include/instrmnt.h:
Added cyg_instrument_state() to report the current state of an
instrumentation flag.
Moved ifdef for CYGDBG_KERNEL_INSTRUMENT_MSGS out of within FLAGS
ifdef. We can have messages without flags.
* src/instrmnt/meminst.cxx:
Added cyg_instrument_state() to report the current state of an
instrumentation flag.
Modified cyg_instrument_msg() in line with header and table
changes.
* host/instr/dump_instr.c:
* host/instr/instrument.sh:
* include/instrument_desc.h:
Added a final NULL element to the generated table in
instrument_desc.h to mark its end. Otherwise code that does not
have access to the table definition cannot find its end. Also
added ifdefs to allow instrument_desc.h to be used to acquire the
structure definition and table pointer.
| author | nickg |
|---|---|
| date | Thu, 12 Dec 2002 18:31:34 +0000 |
| parents | a6cede66ea36 |
| children | aae52574f8c5 |
| files | packages/kernel/current/ChangeLog packages/kernel/current/doc/kernel.sgml packages/kernel/current/host/instr/dump_instr.c packages/kernel/current/host/instr/instrument.sh packages/kernel/current/include/instrmnt.h packages/kernel/current/include/instrument_desc.h packages/kernel/current/include/kapi.h packages/kernel/current/src/common/kapi.cxx packages/kernel/current/src/common/thread.cxx packages/kernel/current/src/instrmnt/meminst.cxx |
| diffstat | 10 files changed, 256 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/kernel/current/ChangeLog +++ b/packages/kernel/current/ChangeLog @@ -1,3 +1,37 @@ +2002-12-12 Nick Garnett <nickg@ecoscentric.com> + + * src/common/kapi.cxx: + * include/kapi.h: + Added function cyg_thread_get_next(), cyg_thread_find() and + cyg_thread_get_info() to allow the current set of threads to be + enumerated, and per-thread information to be retrieved safely. + + * doc/kernel.sgml: Documented new KAPI calls. + + * src/common/thread.cxx: Zero unique_id in thread destructor so + that a stale thread pointer can be checked for validity. + + * include/instrmnt.h: + Added cyg_instrument_state() to report the current state of an + instrumentation flag. + Moved ifdef for CYGDBG_KERNEL_INSTRUMENT_MSGS out of within FLAGS + ifdef. We can have messages without flags. + + * src/instrmnt/meminst.cxx: + Added cyg_instrument_state() to report the current state of an + instrumentation flag. + Modified cyg_instrument_msg() in line with header and table + changes. + + * host/instr/dump_instr.c: + * host/instr/instrument.sh: + * include/instrument_desc.h: + Added a final NULL element to the generated table in + instrument_desc.h to mark its end. Otherwise code that does not + have access to the table definition cannot find its end. Also + added ifdefs to allow instrument_desc.h to be used to acquire the + structure definition and table pointer. + 2002-12-03 Gary Thomas <gthomas@ecoscentric.com> * tests/tm_basic.cxx: Add tests of 'flag' synchronizers.
--- a/packages/kernel/current/doc/kernel.sgml +++ b/packages/kernel/current/doc/kernel.sgml @@ -1276,6 +1276,9 @@ be achieved when programming in C++ is l <refname>cyg_thread_get_stack_base</refname> <refname>cyg_thread_get_stack_size</refname> <refname>cyg_thread_measure_stack_usage</refname> + <refname>cyg_thread_get_next</refname> + <refname>cyg_thread_get_info</refname> + <refname>cyg_thread_find</refname> <refpurpose>Get basic thread information</refpurpose> </refnamediv> @@ -1304,6 +1307,21 @@ be achieved when programming in C++ is l <funcdef>cyg_uint32 <function>cyg_thread_measure_stack_usage</function></funcdef> <paramdef>cyg_handle_t <parameter>thread</parameter></paramdef> </funcprototype> + <funcprototype> + <funcdef>cyg_bool <function>cyg_thread_get_next</function></funcdef> + <paramdef>cyg_handle_t *<parameter>thread</parameter></paramdef> + <paramdef>cyg_uint16 *<parameter>id</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>cyg_bool <function>cyg_thread_get_info</function></funcdef> + <paramdef>cyg_handle_t <parameter>thread</parameter></paramdef> + <paramdef>cyg_uint16 <parameter>id</parameter></paramdef> + <paramdef>cyg_thread_info *<parameter>info</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>cyg_handle_t <function>cyg_thread_find</function></funcdef> + <paramdef>cyg_uint16 <parameter>id</parameter></paramdef> + </funcprototype> </funcsynopsis> </refsynopsisdiv> @@ -1344,6 +1362,31 @@ run the specified thread has not yet bee point in the function call graph. Never the less the value returned can give some useful indication of the thread's stack requirements. </para> + <para> +<function>cyg_thread_get_next</function> is used to enumerate all the +current threads in the system. It should be called intially with the +locations pointed to by <parameter>thread</parameter> and +<parameter>id</parameter> set to zero. On return these will be set to +the handle and ID of the first thread. On subsequent calls, these +parameters should be left set to the values returned by the previous +call. The handle and ID of the next thread in the system will be +installed each time, until a <literal>false</literal> return value +indicates the end of the list. + </para> + <para> +<function>cyg_thread_get_info</function> fills in the +<type>cyg_thread_info</type> structure with information about the +thread described by the <parameter>thread</parameter> and +<parameter>id</parameter> arguments. The information returned includes +the thread's handle and id, its state and name, priorities and stack +parameters. If the thread does not exist the function returns +<literal>false</literal>. + </para> + <para> +<function>cyg_thread_find</function> returns a handle for the thread +whose ID is <parameter>id</parameter>. If no such thread exists, a +zero handle is returned. + </para> </refsect1> <refsect1 id="kernel-thread-info-context"><title>Valid contexts</title> @@ -1359,6 +1402,38 @@ stack usage involves looping over at lea so this should normally only be done from thread context. </para> </refsect1> + + <refsect1 id="kernel-thread-info-examples"><title>Examples</title> + <para> +A simple example of the use of the +<function>cyg_thread_get_next</function> and +<function>cyg_thread_get_info</function> follows: + </para> + <programlisting width=72> + +#include <cyg/kernel/kapi.h> +#include <stdio.h> + +void show_threads(void) +{ + cyg_handle_t thread = 0; + cyg_uint16 id = 0; + + while( cyg_thread_get_next( &thread, &id ) ) + { + cyg_thread_info info; + + if( !cyg_thread_get_info( thread, id, &info ) ) + break; + + printf("ID: %04x name: %10s pri: %d\n", + info.id, info.name?info.name:"----", info.set_pri ); + } +} + + </programlisting> + </refsect1> + </refentry> <!-- }}} -->
--- a/packages/kernel/current/host/instr/dump_instr.c +++ b/packages/kernel/current/host/instr/dump_instr.c @@ -21,6 +21,7 @@ struct Instrument_Record // ------------------------------------------------------------------------- #ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS +#define CYGDBG_KERNEL_INSTRUMENT_MSGS_DEFINE_TABLE #include <cyg/kernel/instrument_desc.h> #define NELEM(x) (sizeof(x)/sizeof*(x)) externC char * cyg_instrument_msg(CYG_WORD16 type) { @@ -30,7 +31,7 @@ externC char * cyg_instrument_msg(CYG_WO CYG_WORD cl, event; record = instrument_desc; - end_record = &instrument_desc[NELEM(instrument_desc)]; + end_record = &instrument_desc[NELEM(instrument_desc)-1]; cl = type & 0xff00; event = type & 0x00ff;
--- a/packages/kernel/current/host/instr/instrument.sh +++ b/packages/kernel/current/host/instr/instrument.sh @@ -8,11 +8,16 @@ echo " char * msg; echo " CYG_WORD num; " echo "}; " echo +echo "#ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS_DEFINE_TABLE " echo struct instrument_desc_s instrument_desc[] = { grep -e \#define.CYG_INSTRUMENT_EVENT -e \#define.CYG_INSTRUMENT_CLASS $1 | grep -v MAX | cut -d " " -f 2- | cut -d "_" -f 4- | sort | awk '{ print("{\""$1"\", " $2 "},") }' +echo { 0, 0 } echo }\; +echo "#else /* CYGDBG_KERNEL_INSTRUMENT_MSGS_DEFINE_TABLE */ " +echo "extern struct instrument_desc_s instrument_desc[]; " +echo "#endif /* CYGDBG_KERNEL_INSTRUMENT_MSGS_DEFINE_TABLE */ " echo echo "/* EOF instrument_desc.h */"
--- a/packages/kernel/current/include/instrmnt.h +++ b/packages/kernel/current/include/instrmnt.h @@ -82,10 +82,13 @@ externC void cyg_instrument_enable( cyg_ externC void cyg_instrument_disable( cyg_uint32 cl, cyg_uint32 event ); +externC cyg_bool cyg_instrument_state( cyg_uint32 cl, cyg_uint32 event ); + +#endif + #ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS externC char * cyg_instrument_msg(CYG_WORD16 type); #endif -#endif // ------------------------------------------------------------------------- // Instrumentation macros
--- a/packages/kernel/current/include/instrument_desc.h +++ b/packages/kernel/current/include/instrument_desc.h @@ -7,6 +7,7 @@ struct instrument_desc_s { CYG_WORD num; }; +#ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS_DEFINE_TABLE struct instrument_desc_s instrument_desc[] = { {"ALARM", 0x0900}, {"ALARM_ADD", 1}, @@ -133,6 +134,10 @@ struct instrument_desc_s instrument_desc {"USER_7", 7}, {"USER_8", 8}, {"USER_9", 9}, +{ 0, 0 } }; +#else /* CYGDBG_KERNEL_INSTRUMENT_MSGS_DEFINE_TABLE */ +extern struct instrument_desc_s instrument_desc[]; +#endif /* CYGDBG_KERNEL_INSTRUMENT_MSGS_DEFINE_TABLE */ /* EOF instrument_desc.h */
--- a/packages/kernel/current/include/kapi.h +++ b/packages/kernel/current/include/kapi.h @@ -12,6 +12,7 @@ // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. // Copyright (C) 2002 Bart Veer +// Copyright (C) 2002 Nick Garnett // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. // // eCos is free software; you can redistribute it and/or modify it under @@ -207,6 +208,30 @@ cyg_uint32 cyg_thread_measure_stack_usag #endif /*---------------------------------------------------------------------------*/ +/* Thread enumeration and information */ + +typedef struct +{ + cyg_handle_t handle; + cyg_uint16 id; + cyg_uint32 state; + char *name; + cyg_priority_t set_pri; + cyg_priority_t cur_pri; + cyg_addrword_t stack_base; + cyg_uint32 stack_size; + cyg_uint32 stack_used; +} cyg_thread_info; + +cyg_bool_t cyg_thread_get_next( cyg_handle_t *thread, cyg_uint16 *id ); + +cyg_bool_t cyg_thread_get_info( cyg_handle_t thread, + cyg_uint16 id, + cyg_thread_info *info ); + +cyg_handle_t cyg_thread_find( cyg_uint16 id ); + +/*---------------------------------------------------------------------------*/ /* Per-thread Data */ #ifdef CYGVAR_KERNEL_THREADS_DATA
--- a/packages/kernel/current/src/common/kapi.cxx +++ b/packages/kernel/current/src/common/kapi.cxx @@ -9,6 +9,7 @@ // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// Copyright (C) 2002 Nick Garnett // // eCos is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free @@ -309,6 +310,101 @@ externC cyg_uint32 cyg_thread_measure_st #endif /*---------------------------------------------------------------------------*/ +/* Thread enumeration and information */ + +#ifdef CYGVAR_KERNEL_THREADS_LIST + +cyg_bool_t cyg_thread_get_next( cyg_handle_t *current, cyg_uint16 *id ) +{ + cyg_bool_t result = true; + + Cyg_Scheduler::lock(); + + Cyg_Thread *thread = (Cyg_Thread *)*current; + + if( *current == 0 ) + { + thread = Cyg_Thread::get_list_head(); + *current = (cyg_handle_t)thread; + *id = thread->get_unique_id(); + } + else if( (thread->get_unique_id() == *id) && + (thread = thread->get_list_next()) != NULL ) + { + *current = (cyg_handle_t)thread; + *id = thread->get_unique_id(); + } + else + { + *current = 0; + *id = 0; + result = false; + } + + Cyg_Scheduler::unlock(); + + return result; +} + +cyg_handle_t cyg_thread_find( cyg_uint16 id ) +{ + Cyg_Scheduler::lock(); + + Cyg_Thread *thread = Cyg_Thread::get_list_head(); + + while( thread != NULL ) + { + if( thread->get_unique_id() == id ) + break; + + thread = thread->get_list_next(); + } + + Cyg_Scheduler::unlock(); + + return (cyg_handle_t)thread; +} + +#endif + +cyg_bool_t cyg_thread_get_info( cyg_handle_t threadh, + cyg_uint16 id, + cyg_thread_info *info ) +{ + cyg_bool_t result = true; + Cyg_Thread *thread = (Cyg_Thread *)threadh; + + Cyg_Scheduler::lock(); + + if( thread->get_unique_id() == id && info != NULL ) + { + info->handle = threadh; + info->id = id; + info->state = thread->get_state(); +#ifdef CYGVAR_KERNEL_THREADS_NAME + info->name = thread->get_name(); +#else + info->name = NULL; +#endif + info->set_pri = thread->get_priority(); + info->cur_pri = thread->get_current_priority(); + info->stack_base = thread->get_stack_base(); + info->stack_size = thread->get_stack_size(); + +#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT + info->stack_used = thread->measure_stack_usage(); +#else + info->stack_used = 0; +#endif + } + else result = false; + + Cyg_Scheduler::unlock(); + + return result; +} + +/*---------------------------------------------------------------------------*/ /* Per-thread data */ #ifdef CYGVAR_KERNEL_THREADS_DATA
--- a/packages/kernel/current/src/common/thread.cxx +++ b/packages/kernel/current/src/common/thread.cxx @@ -295,6 +295,9 @@ Cyg_Thread::~Cyg_Thread() remove_from_list(); #endif + // Zero the unique_id to render this thread inconsistent. + unique_id = 0; + CYG_REPORT_RETURN(); }
--- a/packages/kernel/current/src/instrmnt/meminst.cxx +++ b/packages/kernel/current/src/instrmnt/meminst.cxx @@ -214,11 +214,17 @@ externC void cyg_instrument_disable( cyg } +externC cyg_bool cyg_instrument_state( cyg_uint32 cl, cyg_uint32 event) +{ + return (instrument_flags[cl>>8] & (1<<event)) != 0; +} + #endif // ------------------------------------------------------------------------- #ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS +#define CYGDBG_KERNEL_INSTRUMENT_MSGS_DEFINE_TABLE #include <cyg/kernel/instrument_desc.h> #define NELEM(x) (sizeof(x)/sizeof*(x)) externC char * cyg_instrument_msg(CYG_WORD16 type) { @@ -228,7 +234,7 @@ externC char * cyg_instrument_msg(CYG_WO CYG_WORD cl, event; record = instrument_desc; - end_record = &instrument_desc[NELEM(instrument_desc)]; + end_record = &instrument_desc[NELEM(instrument_desc)-1]; cl = type & 0xff00; event = type & 0x00ff;
