summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score')
-rw-r--r--cpukit/score/Makefile.am3
-rw-r--r--cpukit/score/include/rtems/score/thread.h37
-rw-r--r--cpukit/score/include/rtems/score/timespec.h23
-rw-r--r--cpukit/score/src/threaddispatch.c19
-rw-r--r--cpukit/score/src/threadinitialize.c27
-rw-r--r--cpukit/score/src/threadtickletimeslice.c11
-rw-r--r--cpukit/score/src/timespecdivide.c31
-rw-r--r--cpukit/score/src/timespecdividebyinteger.c52
8 files changed, 169 insertions, 34 deletions
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 2b1c25e513..ad3c68e87e 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -148,7 +148,8 @@ libscore_a_SOURCES += src/threadq.c src/threadqdequeue.c \
## TIMESPEC_C_FILES
libscore_a_SOURCES += src/timespecaddto.c src/timespecfromticks.c \
src/timespecisvalid.c src/timespeclessthan.c src/timespecgreaterthan.c \
- src/timespecsubtract.c src/timespectoticks.c src/timespecdivide.c
+ src/timespecsubtract.c src/timespectoticks.c src/timespecdivide.c \
+ src/timespecdividebyinteger.c
## TOD_C_FILES
libscore_a_SOURCES += src/coretod.c src/coretodset.c src/coretodget.c \
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index c23f9cf05c..1d8ba50705 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -31,6 +31,20 @@
extern "C" {
#endif
+/*
+ * The user can define this at configure time and go back to ticks
+ * resolution.
+ */
+#ifndef __RTEMS_USE_TICKS_CPU_USAGE_STATISTICS__
+ /*
+ * Enable the nanosecond accurate statistics
+ *
+ * When not defined, the older style tick accurate granularity
+ * is used.
+ */
+ #define RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+#endif
+
#include <rtems/score/context.h>
#include <rtems/score/cpu.h>
#if defined(RTEMS_MULTIPROCESSING)
@@ -44,6 +58,10 @@ extern "C" {
#include <rtems/score/tqdata.h>
#include <rtems/score/watchdog.h>
+#ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ /* XXX include something for timespec */
+#endif
+
/**
* The following defines the "return type" of a thread.
*
@@ -318,10 +336,14 @@ struct Thread_Control_struct {
/** This field is the method invoked with the budgeted time is consumed. */
Thread_CPU_budget_algorithm_callout budget_callout;
- /** This field is the number of clock ticks executed by this thread
+ /** This field is the amount of CPU time consumed by this thread
* since it was created.
*/
- uint32_t ticks_executed;
+ #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ struct timespec cpu_time_used;
+ #else
+ uint32_t ticks_executed;
+ #endif
/** This field points to the Ready FIFO for this priority. */
Chain_Control *ready;
/** This field contains precalculated priority map indices. */
@@ -435,6 +457,17 @@ SCORE_EXTERN Thread_Control *_Thread_Allocated_fp;
*/
SCORE_EXTERN struct _reent **_Thread_libc_reent;
+#ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+
+ /**
+ * This contains the time since boot when the last context switch occurred.
+ * By placing it in the BSS, it will automatically be zeroed out at
+ * system initialization and does not need to be known outside this
+ * file.
+ */
+ SCORE_EXTERN struct timespec _Thread_Time_of_last_context_switch;
+#endif
+
/**
* This routine performs the initialization necessary for this handler.
*/
diff --git a/cpukit/score/include/rtems/score/timespec.h b/cpukit/score/include/rtems/score/timespec.h
index 2ffde63fc2..cc65e4084a 100644
--- a/cpukit/score/include/rtems/score/timespec.h
+++ b/cpukit/score/include/rtems/score/timespec.h
@@ -135,7 +135,7 @@ void _Timespec_Subtract(
struct timespec *result
);
-/** @brief Divide Timespec
+/** @brief Divide Timespec By Integet
*
* This routine divides a timespec by an integer value. The expected
* use is to assist in benchmark calculations where you typically
@@ -147,12 +147,31 @@ void _Timespec_Subtract(
*
* @return This method fills in @a result.
*/
-void _Timespec_Divide(
+void _Timespec_Divide_by_integer(
const struct timespec *time,
uint32_t iterations,
struct timespec *result
);
+/** @brief Divide Timespec
+ *
+ * This routine divides a timespec by another timespec. The
+ * intended use is for calculating percentages to three decimal points.
+ *
+ * @param[in] lhs is the left hand number
+ * @param[in] rhs is the righ hand number
+ * @param[in] ival_percentage is the integer portion of the average
+ * @param[in] fval_percentage is the thousandths of percentage
+ *
+ * @return This method fills in @a result.
+ */
+void _Timespec_Divide(
+ const struct timespec *lhs,
+ const struct timespec *rhs,
+ uint32_t *ival_percentage,
+ uint32_t *fval_percentage
+);
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/src/threaddispatch.c b/cpukit/score/src/threaddispatch.c
index 136433be17..4c903b6c2a 100644
--- a/cpukit/score/src/threaddispatch.c
+++ b/cpukit/score/src/threaddispatch.c
@@ -2,7 +2,7 @@
* Thread Handler
*
*
- * COPYRIGHT (c) 1989-1999.
+ * COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -30,6 +30,11 @@
#include <rtems/score/userext.h>
#include <rtems/score/wkspace.h>
+#ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+
+ #include <rtems/score/timespec.h>
+#endif
+
/*PAGE
*
* _Thread_Dispatch
@@ -78,7 +83,17 @@ void _Thread_Dispatch( void )
heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
_ISR_Enable( level );
- heir->ticks_executed++;
+ #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ {
+ struct timespec uptime, ran;
+ _TOD_Get_uptime( &uptime );
+ _Timespec_Subtract(&_Thread_Time_of_last_context_switch, &uptime, &ran);
+ _Timespec_Add_to( &executing->cpu_time_used, &ran );
+ _Thread_Time_of_last_context_switch = uptime;
+ }
+ #else
+ heir->ticks_executed++;
+ #endif
/*
* Switch libc's task specific data.
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index e61cbac19a..f3e13a4944 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -187,17 +187,26 @@ boolean _Thread_Initialize(
break;
}
- the_thread->Start.isr_level = isr_level;
+ the_thread->Start.isr_level = isr_level;
+
+ the_thread->current_state = STATES_DORMANT;
+ the_thread->Wait.queue = NULL;
+ the_thread->resource_count = 0;
+ the_thread->suspend_count = 0;
+ the_thread->real_priority = priority;
+ the_thread->Start.initial_priority = priority;
+ _Thread_Set_priority( the_thread, priority );
- the_thread->current_state = STATES_DORMANT;
- the_thread->Wait.queue = NULL;
- the_thread->resource_count = 0;
- the_thread->suspend_count = 0;
- the_thread->real_priority = priority;
- the_thread->Start.initial_priority = priority;
- the_thread->ticks_executed = 0;
+ /*
+ * Initialize the CPU usage statistics
+ */
- _Thread_Set_priority( the_thread, priority );
+ #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ the_thread->cpu_time_used.tv_sec = 0;
+ the_thread->cpu_time_used.tv_nsec = 0;
+ #else
+ the_thread->ticks_executed = 0;
+ #endif
/*
* Open the object
diff --git a/cpukit/score/src/threadtickletimeslice.c b/cpukit/score/src/threadtickletimeslice.c
index 0666066b28..41f08aa8d0 100644
--- a/cpukit/score/src/threadtickletimeslice.c
+++ b/cpukit/score/src/threadtickletimeslice.c
@@ -49,11 +49,12 @@ void _Thread_Tickle_timeslice( void )
executing = _Thread_Executing;
- /*
- * Increment the number of ticks this thread has been executing
- */
-
- executing->ticks_executed++;
+ #ifndef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ /*
+ * Increment the number of ticks this thread has been executing
+ */
+ executing->ticks_executed++;
+ #endif
/*
* If the thread is not preemptible or is not ready, then
diff --git a/cpukit/score/src/timespecdivide.c b/cpukit/score/src/timespecdivide.c
index 0535c22e11..74d6cdbc78 100644
--- a/cpukit/score/src/timespecdivide.c
+++ b/cpukit/score/src/timespecdivide.c
@@ -23,30 +23,35 @@
#include <rtems/score/tod.h>
void _Timespec_Divide(
- const struct timespec *time,
- uint32_t iterations,
- struct timespec *result
+ const struct timespec *lhs,
+ const struct timespec *rhs,
+ uint32_t *ival_percentage,
+ uint32_t *fval_percentage
)
{
- uint64_t t;
+ uint64_t left, right, answer;
/*
* For math simplicity just convert the timespec to nanoseconds
* in a 64-bit integer.
*/
- t = time->tv_sec * TOD_NANOSECONDS_PER_SECOND;
- t += time->tv_nsec;
+ left = lhs->tv_sec * (uint64_t)TOD_NANOSECONDS_PER_SECOND;
+ left += lhs->tv_nsec;
+ right = rhs->tv_sec * (uint64_t)TOD_NANOSECONDS_PER_SECOND;
+ right += rhs->tv_nsec;
- /*
- * Divide to get nanoseconds per iteration
- */
-
- t /= iterations;
+ if ( rhs == 0 ) {
+ *ival_percentage = 0;
+ *ival_percentage = 0;
+ return;
+ }
/*
* Put it back in the timespec result
*/
- result->tv_sec = t / TOD_NANOSECONDS_PER_SECOND;
- result->tv_nsec = t % TOD_NANOSECONDS_PER_SECOND;
+ answer = (left * 1000) / right;
+
+ *fval_percentage = answer % 1000;
+ *ival_percentage = answer / 1000;
}
diff --git a/cpukit/score/src/timespecdividebyinteger.c b/cpukit/score/src/timespecdividebyinteger.c
new file mode 100644
index 0000000000..eecd7c4e30
--- /dev/null
+++ b/cpukit/score/src/timespecdividebyinteger.c
@@ -0,0 +1,52 @@
+/**
+ * @file score/src/timespecdividebyinteger.c
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2007.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <sys/types.h>
+#include <rtems/score/timespec.h>
+#include <rtems/score/tod.h>
+
+void _Timespec_Divide_by_integer(
+ const struct timespec *time,
+ uint32_t iterations,
+ struct timespec *result
+)
+{
+ uint64_t t;
+
+ /*
+ * For math simplicity just convert the timespec to nanoseconds
+ * in a 64-bit integer.
+ */
+ t = time->tv_sec * TOD_NANOSECONDS_PER_SECOND;
+ t += time->tv_nsec;
+
+ /*
+ * Divide to get nanoseconds per iteration
+ */
+
+ t /= iterations;
+
+ /*
+ * Put it back in the timespec result
+ */
+
+ result->tv_sec = t / TOD_NANOSECONDS_PER_SECOND;
+ result->tv_nsec = t % TOD_NANOSECONDS_PER_SECOND;
+}