├── .gitignore ├── .gitmodules ├── deadlock-break ├── wscript ├── deadlock-break.adoc └── deadlock-break.c ├── task-switch ├── wscript ├── task-switch.adoc └── task-switch.c ├── task-preempt ├── wscript ├── task-preempt.adoc └── task-preempt.c ├── message-latency ├── wscript ├── message-latency.adoc └── message-latency.c ├── interrupt-latency ├── wscript ├── interrupt-latency.adoc └── interrupt-latency.c ├── semaphore-shuffle ├── wscript ├── semaphore-shuffle.adoc └── semaphore-shuffle.c ├── LICENSE ├── README.md ├── wscript ├── support ├── timesys.h ├── buffer_test_io.h └── tmacros.h └── INSTALL.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .lock-waf_* 3 | *~ 4 | build/* 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "rtems_waf"] 2 | path = rtems_waf 3 | url = git://git.rtems.org/chrisj/rtems_waf.git 4 | -------------------------------------------------------------------------------- /deadlock-break/wscript: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Daniel Ramirez 2 | # 3 | # This file's license is 2-clause BSD as in this distribution's LICENSE file. 4 | # 5 | 6 | # Waf build script for an RTEMS Hello 7 | import rtems_waf.rtems as rtems 8 | 9 | def build(bld): 10 | rtems.build(bld) 11 | bld.includes = ['../support'] 12 | bld(features = 'c cprogram', 13 | target = 'deadlock-break.exe', 14 | includes = bld.includes, 15 | source = ['deadlock-break.c']) 16 | -------------------------------------------------------------------------------- /task-switch/wscript: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Daniel Ramirez (javamonn@gmail.com) 2 | # 3 | # This file's license is 2-clause BSD as in this distribution's LICENSE file. 4 | # 5 | 6 | # Waf build script for an RTEMS Hello 7 | import rtems_waf.rtems as rtems 8 | 9 | def build(bld): 10 | rtems.build(bld) 11 | bld.includes = ['../support'] 12 | bld(features = 'c cprogram', 13 | target = 'task-switch.exe', 14 | includes = bld.includes, 15 | source = ['task-switch.c']) 16 | -------------------------------------------------------------------------------- /task-preempt/wscript: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Daniel Ramirez (javamonn@gmail.com) 2 | # 3 | # This file's license is 2-clause BSD as in this distribution's LICENSE file. 4 | # 5 | 6 | # Waf build script for an RTEMS Hello 7 | import rtems_waf.rtems as rtems 8 | 9 | def build(bld): 10 | rtems.build(bld) 11 | bld.includes = ['../support'] 12 | bld(features = 'c cprogram', 13 | target = 'task-preempt.exe', 14 | includes = bld.includes, 15 | source = ['task-preempt.c']) 16 | -------------------------------------------------------------------------------- /message-latency/wscript: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Daniel Ramirez (javamonn@gmail.com) 2 | # 3 | # This file's license is 2-clause BSD as in this distribution's LICENSE file. 4 | # 5 | 6 | # Waf build script for an RTEMS Hello 7 | import rtems_waf.rtems as rtems 8 | 9 | def build(bld): 10 | rtems.build(bld) 11 | bld.includes = ['../support'] 12 | bld(features = 'c cprogram', 13 | target = 'message-latency.exe', 14 | includes = bld.includes, 15 | source = ['message-latency.c']) 16 | -------------------------------------------------------------------------------- /interrupt-latency/wscript: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Daniel Ramirez (javamonn@gmail.com) 2 | # 3 | # This file's license is 2-clause BSD as in this distribution's LICENSE file. 4 | # 5 | 6 | # Waf build script for an RTEMS Hello 7 | import rtems_waf.rtems as rtems 8 | 9 | def build(bld): 10 | rtems.build(bld) 11 | bld.includes = ['../support'] 12 | bld(features = 'c cprogram', 13 | target = 'interrupt-latency.exe', 14 | includes = bld.includes, 15 | source = ['interrupt-latency.c']) 16 | -------------------------------------------------------------------------------- /semaphore-shuffle/wscript: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Daniel Ramirez (javamonn@gmail.com) 2 | # 3 | # This file's license is 2-clause BSD as in this distribution's LICENSE file. 4 | # 5 | 6 | # Waf build script for an RTEMS Hello 7 | import rtems_waf.rtems as rtems 8 | 9 | def build(bld): 10 | rtems.build(bld) 11 | bld.includes = ['../support'] 12 | bld(features = 'c cprogram', 13 | target = 'semaphore-shuffle.exe', 14 | includes = bld.includes, 15 | source = ['semaphore-shuffle.c']) 16 | -------------------------------------------------------------------------------- /interrupt-latency/interrupt-latency.adoc: -------------------------------------------------------------------------------- 1 | = Interrupt Latency Benchmark 2 | 3 | This benchmark measures the time between the CPU's receipt of an interrupt 4 | request and the execution of the first intruction in that interrupt service 5 | routine. 6 | 7 | == Directives 8 | 9 | * Intall_tm27_vector 10 | * Cause_tm27_intr 11 | 12 | 13 | == Methodology 14 | 15 | This benchmark takes advantage of the existing tm27 test support implemented 16 | by most BSP's to achieve as much hardware independence as possible. Most BSPs 17 | have an instruction to install an interrupt vector, and then provide code for 18 | the ISR. rtems/testsuites/tmtests/tm27 uses this to test a variety of interrupt 19 | related concepts. The benchmark is simple, the vector is installed, the time 20 | is started, the interrupt is caused, and the time is ended in the first 21 | instruction of the ISR. This is the only Rhealstone that is not an average. 22 | -------------------------------------------------------------------------------- /message-latency/message-latency.adoc: -------------------------------------------------------------------------------- 1 | = Message Latency Benchmark 2 | 3 | This benchmark measures the intertask message latency. This is the delay within 4 | RTEMS between a running task using the rtems_message_queue to send a message to 5 | a waiting task and that task waking up and receiving the message. 6 | 7 | == Directives 8 | 9 | * rtems_message_queue_send 10 | * rtems_message_queue_receive 11 | 12 | 13 | == Methodology 14 | 15 | This benchmark consists of a high priority task and a low priority task. The 16 | benchmark starts in the high priority task, which blocks on a call to rtems_ 17 | message_queue recieve. By accounting for the overhead of the task switch from 18 | the high priority task to the low priority task, and the actual time to recieve 19 | the message, the intertask message latency is found. 20 | 21 | The average is found and the overhead (the time of the first run) is subtracted 22 | out in the call to put_time. 23 | -------------------------------------------------------------------------------- /task-switch/task-switch.adoc: -------------------------------------------------------------------------------- 1 | = Task Switch Benchmark 2 | 3 | This benchmark measures the average time it takes the system to switch between 4 | two independent and active tasks of equal priority. Task switching is synchronous 5 | and non-preemptive. 6 | 7 | == Directives 8 | 9 | * rtems_task_wake_after 10 | 11 | 12 | == Methodology 13 | 14 | This benchmark utilizes rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ) to 15 | achieve a synchronous, non-preemptive task switch. rtems_task_wake_after 16 | used in this context is essentially just a yield. 17 | 18 | As this is an average, we structure the benchmark code in a way that results 19 | in some overhead being included that inflates the total elapsed time. This 20 | overhead includes: 21 | * the time it takes to iterate through the for loops (minimal 22 | * overhead code in rtems_task_wake_after 23 | 24 | We instantiate two tasks, and time how long it takes for them to switch back 25 | and forth between themselves a total of BENCHMARKS * 2 times. We then use 26 | the put_time call to divide this total elapsed time by BENCHMARKS * 2, giving 27 | an average, and subtract out the overhead time we found earlier. 28 | -------------------------------------------------------------------------------- /semaphore-shuffle/semaphore-shuffle.adoc: -------------------------------------------------------------------------------- 1 | = Semaphore Shuffle Benchmark 2 | 3 | This benchmark measures the average delay between a task's release of a 4 | semaphore and the activation of another task blocked on that semaphore. 5 | 6 | == Directives 7 | 8 | * rtems_semaphore_obtain 9 | * rtems_semaphore_release 10 | * rtems_task_wake_after 11 | 12 | 13 | == Methodology 14 | 15 | This benchmark has two equal priority tasks switch between themselves a total 16 | of BENCHMARKS * 2 times. This is timed, and then execute the same code but 17 | having the tasks pass a semphore between themselves. A task obtains the 18 | semphore, then yields to the other task, which blocks on the semaphore. The 19 | task owning the semaphore then releases it and yields. This process is 20 | repeated by the other task. 21 | 22 | This benchmark has overhead, especially in the time it takes to switch between 23 | the two tasks, which happens a total of 2 times per semaphore shuffle. By first 24 | timing how long it takes the tasks to switch between themselves without any 25 | semaphore related calls, the overhead time is found. This time is then subtracted 26 | from the total time of the benchmark, with semaphore shuffling occuring. 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions are met: 3 | 4 | 1. Redistributions of source code must retain the above copyright notice, this 5 | list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, 8 | this list of conditions and the following disclaimer in the documentation 9 | and/or other materials provided with the distribution. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 12 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 13 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 14 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 15 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 17 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 18 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 19 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 20 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Rhealstone Benchmark For RTEMS 2 | 3 | This is an implementation of the Rhealstone benchmarks for RTEMS. 4 | 5 | The Rhealstone metric is a set of benchmarks that aim to provide an independently 6 | verifiable objective measure of real-time performance in different systems. The 7 | Rhealstone metric is composed of six independent benchmarks, each of which measure 8 | an activity that is critical in real time systems: 9 | + [Task switching time](/task-switch/task-switch.c) 10 | + [Task preemption time](/task-preempt/task-preempt.c) 11 | + [Interrupt latency time](/interrupt-latency/interrupt-latency.c) 12 | + [Semaphore shuffling time](/semaphore-shuffle/semaphore-shuffle.c) 13 | + [Deadlock breaking time](/deadlock-break/deadlock-break.c) 14 | + [Intertask message latency](/message-latency/message-latency.c) 15 | 16 | See the [build](/INSTALL.md) instructions for directions on building and running 17 | the Rhealstone benchmarks. 18 | 19 | The original proposal outlining the Rhealstone benchmark can be found [here](http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/DDJ/1989/8902/8902a/8902a.htm). 20 | 21 | Some other implementations can be seen on [FreeRTOS](http://timsengineeringblog.weebly.com/masters-thesis.html) and [iRMX](http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/DDJ/1990/9004/9004d/9004d.htm). 22 | -------------------------------------------------------------------------------- /wscript: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Daniel Ramirez (javamonn@gmail.com) 2 | # 3 | # This file's license is 2-clause BSD as in this distribution's LICENSE.2 file. 4 | # 5 | 6 | # Waf build script for RTEMS examples 7 | # 8 | # To configure, build and run do: 9 | # 10 | # $ waf configure --rtems=/Users/chris/Development/rtems/build/4.11 \ 11 | # --rtems-tools=/Users/chris/Development/rtems/4.11 \ 12 | # --rtems-bsps=sparc/sis 13 | # $ waf 14 | # $ /Users/chris/Development/rtems/4.11/bin/sparc-rtems4.11-run ./build/sparc-rtems4.11-sis/hello 15 | # 16 | # You can use '--rtems-archs=sparc,i386' or '--rtems-bsps=sparc/sis,i386/pc586' 17 | # to build for more than BSP at a time. 18 | # 19 | 20 | try: 21 | import rtems_waf.rtems as rtems 22 | except: 23 | print 'error: no rtems_waf git submodule; see README.waf' 24 | import sys 25 | sys.exit(1) 26 | 27 | def init(ctx): 28 | rtems.init(ctx) 29 | 30 | def options(opt): 31 | rtems.options(opt) 32 | 33 | def configure(conf): 34 | rtems.configure(conf) 35 | 36 | def build(bld): 37 | rtems.build(bld) 38 | bld.env.CFLAGS += ['-O2','-g'] 39 | bld.recurse('task-switch') 40 | bld.recurse('task-preempt') 41 | bld.recurse('interrupt-latency') 42 | bld.recurse('semaphore-shuffle') 43 | bld.recurse('message-latency') 44 | bld.recurse('deadlock-break') 45 | 46 | def rebuild(ctx): 47 | import waflib.Options 48 | waflib.Options.commands.extend(['clean', 'build']) 49 | 50 | def tags(ctx): 51 | ctx.exec_command('etags $(find . -name \*.[sSch])', shell = True) 52 | -------------------------------------------------------------------------------- /task-preempt/task-preempt.adoc: -------------------------------------------------------------------------------- 1 | = Task Preemption Benchmark 2 | 3 | This benchmark measures the average time it takes the system to recognize 4 | a ready higher priority task and switch to it from a lower priority task. 5 | This differs from a task-switch in the sense that there is no explicit 6 | yield, the system forces the context switch. 7 | 8 | == Directives 9 | 10 | * rtems_task_suspend 11 | * rtems_task_resume 12 | 13 | == Methodology 14 | 15 | Preemption usually occurs in a program when a high priority task moves from 16 | a suspended or idle state to a ready state in response to an event. This is 17 | achieved in the benchmark by using rtems_task_suspend and rtems_task_resume 18 | to move the high priority task in between states. 19 | 20 | As this is an average, we structure the benchmark code in a way that results 21 | in some overhead being included that inflates the total elapsed time. This 22 | overhead includes: 23 | * loop overhead (minimal) 24 | * the time it takes to task-switch from the high priority task back to 25 | the low priority task. 26 | * The time it takes to change the state of a task (suspend/resume). 27 | 28 | We instantiate two tasks, one with a higher priority than the other. The 29 | benchmark starts with the high priority task suspended. The benchmark code 30 | has the lower priority task resume the high priority task, at which point 31 | the preemption we are seeking to time occurs. The high priority task, now 32 | executing, suspends it self, and a non-preemptive task switch back to the 33 | low priority task occurs. This is repeated a total of BENCHMARKS times. 34 | 35 | The average time is found by using put_time to divide the total elapsed time 36 | by the number of benchmarks, and subtracting out the overhead found earlier. 37 | -------------------------------------------------------------------------------- /deadlock-break/deadlock-break.adoc: -------------------------------------------------------------------------------- 1 | = Deadlock Break Benchmark 2 | 3 | This benchmark measures the average time to break a deadlock that occurs 4 | when a high priority task preempts a low priority task that is holding a 5 | resource that the high priority task needs. In RTEMS, these situations 6 | are mitigated through use of a semaphore with priority inheritance. A 7 | task holding a semaphore with priority inheritance enabled has its 8 | priority boosted to match that of the highest priority task blocked on 9 | that semaphore. 10 | 11 | == Directives 12 | 13 | * rtems_semaphore_obtain 14 | * rtems_semaphore_release 15 | * rtems_task_suspend 16 | * rtems_task_resume 17 | 18 | 19 | == Methodology 20 | 21 | This benchmark is structured in a way that is very similar to the semaphore- 22 | shuffle benchmark, but instead uses three tasks of differing priorities and 23 | suspend/resume instead of yield directives. 24 | 25 | The benchmark is run and timed once with no semaphore operations. This is the 26 | overhead time. The benchmark starts with the high priority task, which suspends 27 | itself, passing control to the mid priority task. The mid priority task then 28 | suspends itself, passing control to the low priority task. The low priority task 29 | resumes the mid priority task, which then resumes the high priority task. The 30 | process is repeated a total of BENCHMARKS times. This process is then executed 31 | with the low priority task holding a semaphore that the high priority task blocks 32 | on when trying to obtain. Due to priority inheritance (the deadlock break 33 | mechanism) the low priority task will execute instead of the mid priority task. 34 | The same system of suspend/resumes then occurs. 35 | 36 | The average is found and the overhead (the time of the first run) is subtracted 37 | out in the call to put_time. 38 | -------------------------------------------------------------------------------- /support/timesys.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @brief Timing Test Support 4 | * 5 | * This header file contains supporting definitions for the 6 | * Timing Test Suites. 7 | */ 8 | 9 | /* 10 | * COPYRIGHT (c) 1989-2013. 11 | * On-Line Applications Research Corporation (OAR). 12 | * 13 | * The license and distribution terms for this file may be 14 | * found in the file LICENSE in this distribution or at 15 | * http://www.rtems.com/license/LICENSE. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | /* 22 | * This constant determines the maximum number of a resource 23 | * that will be created. For example, some test create multiple 24 | * blocking tasks to determine the execution time of blocking 25 | * services. By default, the blocking time of 100 tasks will 26 | * be measured. Small targets often do not have enough memory 27 | * to create 100 tasks. By overriding the default OPERATION_COUNT 28 | * with a lower number (typically 10 or less), all of the time tests 29 | * can usually be run. This is stil not very fine-grained but 30 | * is enough to significantly reduce memory consumption. 31 | */ 32 | 33 | #ifndef OPERATION_COUNT 34 | #define OPERATION_COUNT 100 35 | #endif 36 | 37 | /* functions */ 38 | 39 | #define put_time( _message, _total_time, \ 40 | _iterations, _loop_overhead, _overhead ) \ 41 | printf( \ 42 | "%s - %" PRId32 "\n", \ 43 | (_message), \ 44 | (((_total_time) - (_loop_overhead)) / (_iterations)) - (_overhead) \ 45 | ) 46 | 47 | #if defined(CONFIGURE_STACK_CHECKER_ENABLED) || defined(RTEMS_DEBUG) 48 | #define Print_Warning() \ 49 | do { \ 50 | puts( \ 51 | "\n" \ 52 | "THE TIMES REPORTED BY THIS TEST INCLUDE DEBUG CODE!\n" \ 53 | "\n" \ 54 | ); \ 55 | } while (0) 56 | 57 | #else 58 | #define Print_Warning() 59 | #endif 60 | 61 | /* variables */ 62 | 63 | TEST_EXTERN volatile uint32_t end_time; /* ending time variable */ 64 | TEST_EXTERN volatile uint32_t overhead; /* loop overhead variable */ 65 | 66 | /* end of include file */ 67 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | RTEMS Waf 2 | ~~~~~~~~~ 3 | 4 | You can find the Waf project here: 5 | 6 | http://code.google.com/p/waf/ 7 | 8 | Simple instructions on How to set up Waf is here: 9 | 10 | http://www.rtems.org/ftp/pub/rtems/people/chrisj/rtl/rtems-linker/waf.html 11 | 12 | Steps 13 | ----- 14 | 15 | 1. Build or install the tools. In this example the path is 16 | /opt/rtems-4.11/bin/tools. 17 | 18 | 2. Build and install the RTEMS Board Support Packages you want to use. In this 19 | example the path is /opt/rtems-4.11/bin/build. 20 | 21 | 3. Unpack this package somewhere, anywhere on your disk and change into the top 22 | level directory. 23 | 24 | 4. Populate the git submodule: 25 | 26 | $ git submodule init 27 | $ git submodule update 28 | 29 | 5. Configure with your specific settings. In this case the path to the tools 30 | and RTEMS and provided on the command line and so do not need to be in your 31 | path or environment [1] and we limit the build to 'sparc/sis' BSP: 32 | 33 | $ waf configure --rtems=/opt/rtems-4.11/bin/build \ 34 | --rtems-tools=/opt/rtems-4.11/bin/tools \ 35 | --rtems-bsps=sparc/sis 36 | 37 | You can use '--rtems-archs=sparc,i386' or 38 | '--rtems-bsps=sparc/sis,i386/pc586' to build for more than BSP at a time. 39 | 40 | 6. Build: 41 | 42 | $ waf 43 | 44 | 7. Run the benchmarks using the simulator: 45 | 46 | $ /opt/rtems-4.11/bin/build/sparc-rtems4.11-run \ 47 | ./build/sparc-rtems4.11-sis/task-switch/task-switch.exe 48 | 49 | $ /opt/rtems-4.11/bin/build/sparc-rtems4.11-run \ 50 | ./build/sparc-rtems4.11-sis/task-preempt/task-preempt.exe 51 | 52 | $ /opt/rtems-4.11/bin/build/sparc-rtems4.11-run \ 53 | ./build/sparc-rtems4.11-sis/interrupt-latency/interrupt-latency.exe 54 | 55 | $ /opt/rtems-4.11/bin/build/sparc-rtems4.11-run \ 56 | ./build/sparc-rtems4.11-sis/semaphore-shuffle/semaphore-shuffle.exe 57 | 58 | $ /opt/rtems-4.11/bin/build/sparc-rtems4.11-run \ 59 | ./build/sparc-rtems4.11-sis/deadlock-break/deadlock-break.exe 60 | 61 | $ /opt/rtems-4.11/bin/build/sparc-rtems4.11-run \ 62 | ./build/sparc-rtems4.11-sis/message-latency/message-latency.exe 63 | 64 | -------------------------------------------------------------------------------- /interrupt-latency/interrupt-latency.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2014 Daniel Ramirez (javamonn@gmail.com) 2 | * 3 | * This file's license is 2-clause BSD as in this distribution's LICENSE.2 file. 4 | */ 5 | 6 | /* 7 | * WARNING!!!!!!!!! 8 | * 9 | * THIS TEST USES INTERNAL RTEMS VARIABLES!!! 10 | */ 11 | 12 | #ifdef HAVE_CONFIG_H 13 | #include "config.h" 14 | #endif 15 | 16 | #define CONFIGURE_INIT 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | /* configuration information */ 23 | #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER 24 | #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER 25 | #define CONFIGURE_MAXIMUM_TASKS 2 26 | #define CONFIGURE_TICKS_PER_TIMESLICE 0 27 | #define CONFIGURE_RTEMS_INIT_TASKS_TABLE 28 | #define CONFIGURE_SCHEDULER_PRIORITY 29 | 30 | #include 31 | 32 | #include 33 | 34 | #define _RTEMS_TMTEST27 35 | #include 36 | 37 | #define BENCHMARKS 50000 38 | 39 | rtems_task Task_1( 40 | rtems_task_argument argument 41 | ); 42 | 43 | uint32_t Interrupt_nest; 44 | uint32_t timer_overhead; 45 | uint32_t Interrupt_enter_time; 46 | 47 | rtems_isr Isr_handler( 48 | rtems_vector_number vector 49 | ); 50 | 51 | rtems_task Init( 52 | rtems_task_argument argument 53 | ) 54 | { 55 | rtems_status_code status; 56 | rtems_id Task_id 57 | 58 | Print_Warning(); 59 | 60 | if (_Scheduler.Operations.initialize != _Scheduler_priority_Initialize) { 61 | puts( " Error ==> " ); 62 | puts( "Test only supported for deterministic priority scheduler\n" ); 63 | rtems_test_exit( 0 ); 64 | } 65 | 66 | #define LOW_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 1u) 67 | status = rtems_task_create( 68 | rtems_build_name( 'T', 'A', '1', ' ' ), 69 | LOW_PRIORITY, 70 | RTEMS_MINIMUM_STACK_SIZE, 71 | RTEMS_DEFAULT_MODES, 72 | RTEMS_DEFAULT_ATTRIBUTES, 73 | &Task_id 74 | ); 75 | directive_failed( status, "rtems_task_create Task_1" ); 76 | 77 | status = rtems_task_start( Task_id, Task_1, 0 ); 78 | directive_failed( status, "rtems_task_start Task_1" ); 79 | 80 | benchmark_timer_initialize(); 81 | benchmark_timer_read(); 82 | benchmark_timer_initialize(); 83 | timer_overhead = benchmark_timer_read(); 84 | 85 | status = rtems_task_delete( RTEMS_SELF ); 86 | directive_failed( status, "rtems_task_delete of RTEMS_SELF" ); 87 | } 88 | 89 | rtems_task Task_1( 90 | rtems_task_argument argument 91 | ) 92 | { 93 | Chain_Control *ready_queues; 94 | 95 | Install_tm27_vector( Isr_handler ) ; 96 | Interrupt_nest = 0; 97 | _Thread_Dispatch_set_disable_level( 0 ); 98 | 99 | /* Benchmark code */ 100 | benchmark_timer_initialize(); 101 | /* goes to Isr_handler */ 102 | Cause_tm27_intr(); 103 | 104 | put_time( 105 | "Rhealstone: Interrupt Latency", 106 | Interrupt_enter_time, 107 | 1, /* Only Rhealstone that isn't an average */ 108 | timer_overhead, 109 | 0 110 | ); 111 | 112 | rtems_test_exit( 0 ); 113 | } 114 | 115 | rtems_isr Isr_handler( 116 | rtems_vector_number vector 117 | ) 118 | { 119 | /* See how long it took system to recognize interrupt */ 120 | Interrupt_enter_time = benchmark_timer_read(); 121 | Clear_tm27_intr(); 122 | } 123 | -------------------------------------------------------------------------------- /task-switch/task-switch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Daniel Ramirez. (javamonn@gmail.com) 3 | * 4 | * This file's license is 2-clause BSD as in this distribution's LICENSE file. 5 | */ 6 | 7 | #include 8 | #include "tmacros.h" 9 | #include "timesys.h" 10 | 11 | #define BENCHMARKS 50000 12 | 13 | rtems_task Task02(rtems_task_argument ignored); 14 | rtems_task Init(rtems_task_argument ignored); 15 | 16 | rtems_id Task_id[2]; 17 | rtems_name Task_name[2]; 18 | uint32_t loop_overhead; 19 | uint32_t dir_overhead; 20 | unsigned long count1, count2; 21 | rtems_status_code status; 22 | 23 | rtems_task Task02( rtems_task_argument ignored ) 24 | { 25 | uint32_t telapsed; 26 | 27 | /* All overhead accounted for now, we can begin benchmark */ 28 | benchmark_timer_initialize(); 29 | 30 | for ( count1 = 0; count1 < BENCHMARKS - 1; count1++ ) { 31 | rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); 32 | } 33 | 34 | telapsed = benchmark_timer_read(); 35 | put_time( 36 | "Rhealstone: Task switch", 37 | telapsed, 38 | ( BENCHMARKS * 2 ) - 1, /* ( BENCHMARKS * 2 ) - 1 total benchmarks */ 39 | loop_overhead, /* Overhead of loop */ 40 | dir_overhead /* Overhead of rtems_task_wake_after directive */ 41 | ); 42 | 43 | rtems_test_exit( 0 ); 44 | } 45 | 46 | rtems_task Task01( rtems_task_argument ignored ) 47 | { 48 | status = rtems_task_start( Task_id[1], Task02, 0 ); 49 | directive_failed( status, "rtems_task_start of TA02" ); 50 | 51 | /* Yield processor so second task can startup and run */ 52 | rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); 53 | 54 | for ( count2 = 0; count2 < BENCHMARKS; count2++ ) { 55 | rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); 56 | } 57 | 58 | /* Should never reach here */ 59 | rtems_test_assert( false ); 60 | 61 | } 62 | 63 | rtems_task Init( rtems_task_argument ignored ) 64 | { 65 | Task_name[0] = rtems_build_name( 'T','A','0','1' ); 66 | status = rtems_task_create( 67 | Task_name[0], 68 | 30, 69 | RTEMS_MINIMUM_STACK_SIZE, 70 | RTEMS_DEFAULT_MODES, 71 | RTEMS_DEFAULT_ATTRIBUTES, 72 | &Task_id[0] 73 | ); 74 | directive_failed( status, "rtems_task_create of TA01" ); 75 | 76 | Task_name[1] = rtems_build_name( 'T','A','0','2' ); 77 | status = rtems_task_create( 78 | Task_name[1], 79 | 30, 80 | RTEMS_MINIMUM_STACK_SIZE, 81 | RTEMS_DEFAULT_MODES, 82 | RTEMS_DEFAULT_ATTRIBUTES, 83 | &Task_id[1] 84 | ); 85 | directive_failed( status, "rtems_task_create of TA02" ); 86 | 87 | /* find overhead of routine (no task switches) */ 88 | benchmark_timer_initialize(); 89 | for ( count1 = 0; count1 < BENCHMARKS - 1; count1++ ) { 90 | /* rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ) */ 91 | } 92 | for ( count2 = 0; count2 < BENCHMARKS; count2++ ) { 93 | /* rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ) */ 94 | } 95 | loop_overhead = benchmark_timer_read(); 96 | 97 | /* find overhead of rtems_task_wake_after call (no task switches) */ 98 | benchmark_timer_initialize(); 99 | rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); 100 | dir_overhead = benchmark_timer_read(); 101 | 102 | status = rtems_task_start( Task_id[0], Task01, 0); 103 | directive_failed( status, "rtems_task_start of TA01" ); 104 | 105 | status = rtems_task_delete( RTEMS_SELF); 106 | directive_failed( status, "rtems_task_delete of INIT" ); 107 | } 108 | 109 | /* configuration information */ 110 | #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER 111 | #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER 112 | #define CONFIGURE_TICKS_PER_TIMESLICE 0 113 | #define CONFIGURE_RTEMS_INIT_TASKS_TABLE 114 | #define CONFIGURE_MAXIMUM_TASKS 3 115 | #define CONFIGURE_INIT 116 | #include 117 | -------------------------------------------------------------------------------- /task-preempt/task-preempt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Daniel Ramirez. (javamonn@gmail.com) 3 | * 4 | * This file's license is 2-clause BSD as in this distribution's LICENSE file. 5 | */ 6 | 7 | #include "tmacros.h" 8 | #include "timesys.h" 9 | #include 10 | #define BENCHMARKS 50000 /* Number of benchmarks to run and average over */ 11 | 12 | rtems_task Task02( rtems_task_argument ignored ); 13 | rtems_task Task01( rtems_task_argument ignored ); 14 | rtems_task Init( rtems_task_argument ignored ); 15 | 16 | rtems_id Task_id[2]; 17 | rtems_name Task_name[2]; 18 | 19 | uint32_t telapsed; /* total time elapsed during benchmark */ 20 | uint32_t tloop_overhead; /* overhead of loops */ 21 | uint32_t tswitch_overhead; /* overhead of time it takes to switch 22 | * from TA02 to TA01, includes rtems_suspend 23 | * overhead 24 | */ 25 | unsigned long count1; 26 | rtems_status_code status; 27 | 28 | rtems_task Task01( rtems_task_argument ignored ) 29 | { 30 | /* Start up TA02, get preempted */ 31 | status = rtems_task_start( Task_id[1], Task02, 0); 32 | directive_failed( status, "rtems_task_start of TA02"); 33 | 34 | tswitch_overhead = benchmark_timer_read(); 35 | 36 | benchmark_timer_initialize(); 37 | /* Benchmark code */ 38 | for ( count1 = 0; count1 < BENCHMARKS; count1++ ) { 39 | rtems_task_resume( Task_id[1] ); /* Awaken TA02, preemption occurs */ 40 | } 41 | 42 | /* Should never reach here */ 43 | rtems_test_assert( false ); 44 | } 45 | 46 | rtems_task Task02( rtems_task_argument ignored ) 47 | { 48 | /* Find overhead of task switch back to TA01 (not a preemption) */ 49 | benchmark_timer_initialize(); 50 | rtems_task_suspend( RTEMS_SELF ); 51 | 52 | /* Benchmark code */ 53 | for ( ; count1 < BENCHMARKS - 1; ) { 54 | rtems_task_suspend( RTEMS_SELF ); 55 | } 56 | 57 | telapsed = benchmark_timer_read(); 58 | put_time( 59 | "Rhealstone: Task Preempt", 60 | telapsed, /* Total time of all benchmarks */ 61 | BENCHMARKS - 1, /* BENCHMARKS - 1 total preemptions */ 62 | tloop_overhead, /* Overhead of loops */ 63 | tswitch_overhead /* Overhead of task switch back to TA01 */ 64 | ); 65 | 66 | rtems_test_exit( 0 ); 67 | } 68 | 69 | rtems_task Init( rtems_task_argument ignored ) 70 | { 71 | Task_name[0] = rtems_build_name( 'T','A','0','1' ); 72 | status = rtems_task_create( 73 | Task_name[0], 74 | 30, /* TA01 is low priority task */ 75 | RTEMS_MINIMUM_STACK_SIZE, 76 | RTEMS_DEFAULT_MODES, 77 | RTEMS_DEFAULT_ATTRIBUTES, 78 | &Task_id[0] 79 | ); 80 | directive_failed( status, "rtems_task_create of TA01"); 81 | 82 | Task_name[1] = rtems_build_name( 'T','A','0','2' ); 83 | status = rtems_task_create( 84 | Task_name[1], 85 | 28, /* TA02 is high priority task */ 86 | RTEMS_MINIMUM_STACK_SIZE, 87 | RTEMS_DEFAULT_MODES, 88 | RTEMS_DEFAULT_ATTRIBUTES, 89 | &Task_id[1] 90 | ); 91 | directive_failed( status, "rtems_task_create of TA02"); 92 | 93 | /* Find loop overhead */ 94 | benchmark_timer_initialize(); 95 | for ( count1 = 0; count1 < ( BENCHMARKS * 2 ) - 1; count1++ ); { 96 | /* rtems_task_resume( Task_id[1] ); */ 97 | } 98 | tloop_overhead = benchmark_timer_read(); 99 | 100 | status = rtems_task_start( Task_id[0], Task01, 0 ); 101 | directive_failed( status, "rtems_task_start of TA01"); 102 | 103 | status = rtems_task_delete( RTEMS_SELF ); 104 | directive_failed( status, "rtems_task_delete of INIT"); 105 | } 106 | 107 | /* configuration information */ 108 | #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER 109 | #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER 110 | #define CONFIGURE_TICKS_PER_TIMESLICE 0 111 | #define CONFIGURE_RTEMS_INIT_TASKS_TABLE 112 | #define CONFIGURE_MAXIMUM_TASKS 3 113 | #define CONFIGURE_INIT 114 | #include 115 | -------------------------------------------------------------------------------- /support/buffer_test_io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Support for running the test output through a buffer 3 | */ 4 | 5 | #ifndef __BUFFER_TEST_IO_h 6 | #define __BUFFER_TEST_IO_h 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /* 13 | * Uncomment this to get buffered test output. When commented out, 14 | * test output behaves as it always has and is printed using stdio. 15 | */ 16 | 17 | /* #define TESTS_BUFFER_OUTPUT */ 18 | #if defined(__AVR__) 19 | #define TESTS_USE_PRINTK 20 | #endif 21 | 22 | /* 23 | * USE PRINTK TO MINIMIZE SIZE 24 | */ 25 | #if defined(TESTS_USE_PRINTK) 26 | 27 | #include 28 | 29 | #undef printf 30 | #define printf(...) \ 31 | do { \ 32 | printk( __VA_ARGS__); \ 33 | } while (0) 34 | 35 | #undef puts 36 | #define puts(_s) \ 37 | do { \ 38 | printk( "%s\n", _s); \ 39 | } while (0) 40 | 41 | #undef putchar 42 | #define putchar(_c) \ 43 | do { \ 44 | printk( "%c", _c ); \ 45 | } while (0) 46 | 47 | /* Do not call exit() since it closes stdin, etc and pulls in stdio code */ 48 | #define rtems_test_exit(_s) \ 49 | do { \ 50 | rtems_shutdown_executive(0); \ 51 | } while (0) 52 | 53 | #define FLUSH_OUTPUT() \ 54 | do { \ 55 | } while (0) 56 | 57 | /* 58 | * BUFFER TEST OUTPUT 59 | */ 60 | #elif defined(TESTS_BUFFER_OUTPUT) 61 | 62 | #include 63 | #include 64 | 65 | #define _TEST_OUTPUT_BUFFER_SIZE 2048 66 | extern char _test_output_buffer[_TEST_OUTPUT_BUFFER_SIZE]; 67 | void _test_output_append(char *); 68 | void _test_output_flush(void); 69 | 70 | #define rtems_test_exit(_s) \ 71 | do { \ 72 | _test_output_flush(); \ 73 | exit(_s); \ 74 | } while (0) 75 | 76 | #undef printf 77 | #define printf(...) \ 78 | do { \ 79 | char _buffer[128]; \ 80 | sprintf( _buffer, __VA_ARGS__); \ 81 | _test_output_append( _buffer ); \ 82 | } while (0) 83 | 84 | #undef puts 85 | #define puts(_string) \ 86 | do { \ 87 | char _buffer[128]; \ 88 | sprintf( _buffer, "%s\n", _string ); \ 89 | _test_output_append( _buffer ); \ 90 | } while (0) 91 | 92 | #undef putchar 93 | #define putchar(_c) \ 94 | do { \ 95 | char _buffer[2]; \ 96 | _buffer[0] = _c; \ 97 | _buffer[1] = '\0'; \ 98 | _test_output_append( _buffer ); \ 99 | } while (0) 100 | 101 | /* we write to stderr when there is a pause() */ 102 | #define FLUSH_OUTPUT() _test_output_flush() 103 | 104 | #if defined(TEST_INIT) || defined(CONFIGURE_INIT) 105 | 106 | char _test_output_buffer[_TEST_OUTPUT_BUFFER_SIZE]; 107 | int _test_output_buffer_index = 0; 108 | 109 | void _test_output_append(char *_buffer) 110 | { 111 | char *p; 112 | 113 | for ( p=_buffer ; *p ; p++ ) { 114 | _test_output_buffer[_test_output_buffer_index++] = *p; 115 | _test_output_buffer[_test_output_buffer_index] = '\0'; 116 | #if 0 117 | if ( *p == '\n' ) { 118 | fprintf( stderr, "BUFFER -- %s", _test_output_buffer ); 119 | _test_output_buffer_index = 0; 120 | _test_output_buffer[0] = '\0'; 121 | } 122 | #endif 123 | if ( _test_output_buffer_index >= (_TEST_OUTPUT_BUFFER_SIZE - 80) ) 124 | _test_output_flush(); 125 | } 126 | } 127 | 128 | #include 129 | #include 130 | 131 | void _test_output_flush(void) 132 | { 133 | fprintf( stderr, "%s", _test_output_buffer ); 134 | _test_output_buffer_index = 0; 135 | tcdrain( 2 ); 136 | } 137 | 138 | #endif 139 | /* 140 | * USE IPRINT 141 | */ 142 | #else 143 | 144 | #include 145 | #include 146 | 147 | /* do not use iprintf if strict ansi mode */ 148 | #if defined(_NEWLIB_VERSION) && !defined(__STRICT_ANSI__) 149 | #undef printf 150 | #define printf(...) \ 151 | do { \ 152 | fiprintf( stderr, __VA_ARGS__ ); \ 153 | } while (0) 154 | #else 155 | #undef printf 156 | #define printf(...) \ 157 | do { \ 158 | fprintf( stderr, __VA_ARGS__ ); \ 159 | } while (0) 160 | #endif 161 | 162 | #undef puts 163 | #define puts(_s) \ 164 | do { \ 165 | printf( "%s\n", _s ); \ 166 | } while (0) 167 | 168 | #undef putchar 169 | #define putchar(_c) \ 170 | do { \ 171 | printf( "%c", _c ); \ 172 | } while (0) 173 | 174 | #define rtems_test_exit(_s) \ 175 | do { \ 176 | exit(_s); \ 177 | } while (0) 178 | 179 | #define FLUSH_OUTPUT() \ 180 | do { \ 181 | fflush(stdout); \ 182 | } while (0) 183 | 184 | #endif 185 | 186 | #ifdef __cplusplus 187 | }; 188 | #endif 189 | 190 | #endif 191 | -------------------------------------------------------------------------------- /message-latency/message-latency.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Daniel Ramirez. (javamonn@gmail.com) 3 | * 4 | * This file's license is 2-clause BSD as in this distribution's LICENSE file. 5 | */ 6 | 7 | #ifdef HAVE_CONFIG_H 8 | #include "config.h" 9 | #endif 10 | 11 | #include "tmacros.h" 12 | #include "timesys.h" 13 | #include 14 | 15 | #define MESSAGE_SIZE (sizeof(long) * 4) 16 | #define BENCHMARKS 50000 17 | 18 | rtems_task Init( rtems_task_argument ignored ); 19 | rtems_task Task01( rtems_task_argument ignored ); 20 | rtems_task Task02( rtems_task_argument ignored ); 21 | 22 | uint32_t telapsed; 23 | uint32_t tloop_overhead; 24 | uint32_t treceive_overhead; 25 | uint32_t count; 26 | rtems_id Task_id[2]; 27 | rtems_name Task_name[2]; 28 | rtems_id Queue_id; 29 | long Buffer[4]; 30 | 31 | void Init( 32 | rtems_task_argument argument 33 | ) 34 | { 35 | rtems_status_code status; 36 | 37 | status = rtems_message_queue_create( 38 | rtems_build_name( 'M', 'Q', '1', ' ' ), 39 | 1, 40 | MESSAGE_SIZE, 41 | RTEMS_DEFAULT_ATTRIBUTES, 42 | &Queue_id 43 | ); 44 | directive_failed( status, "rtems_message_queue_create" ); 45 | 46 | Task_name[0] = rtems_build_name( 'T','A','0','1' ); 47 | status = rtems_task_create( 48 | Task_name[0], 49 | 30, /* TA01 is low priority task */ 50 | RTEMS_MINIMUM_STACK_SIZE, 51 | RTEMS_DEFAULT_MODES, 52 | RTEMS_DEFAULT_ATTRIBUTES, 53 | &Task_id[0] 54 | ); 55 | directive_failed( status, "rtems_task_create of TA01"); 56 | 57 | Task_name[1] = rtems_build_name( 'T','A','0','2' ); 58 | status = rtems_task_create( 59 | Task_name[1], 60 | 28, /* High priority task */ 61 | RTEMS_MINIMUM_STACK_SIZE, 62 | RTEMS_DEFAULT_MODES, 63 | RTEMS_DEFAULT_ATTRIBUTES, 64 | &Task_id[1] 65 | ); 66 | directive_failed( status, "rtems_task_create of TA01" ); 67 | 68 | benchmark_timer_initialize(); 69 | for ( count = 0; count < BENCHMARKS - 1; count++ ) { 70 | /* message send/recieve */ 71 | } 72 | tloop_overhead = benchmark_timer_read(); 73 | 74 | status = rtems_task_start( Task_id[0], Task01, 0 ); 75 | directive_failed( status, "rtems_task_start of TA01" ); 76 | 77 | status = rtems_task_delete( RTEMS_SELF ); 78 | directive_failed( status, "rtems_task_delete of RTEMS_SELF" ); 79 | } 80 | 81 | rtems_task Task01( rtems_task_argument ignored ) 82 | { 83 | rtems_status_code status; 84 | 85 | /* Put a message in the queue so recieve overhead can be found. */ 86 | (void) rtems_message_queue_send( Queue_id, Buffer, MESSAGE_SIZE ); 87 | 88 | /* Start up second task, get preempted */ 89 | status = rtems_task_start( Task_id[1], Task02, 0 ); 90 | directive_failed( status, "rtems_task_start" ); 91 | 92 | for ( ; count < BENCHMARKS; count++ ) { 93 | (void) rtems_message_queue_send( Queue_id, Buffer, MESSAGE_SIZE ); 94 | } 95 | 96 | /* Should never reach here */ 97 | rtems_test_assert( false ); 98 | 99 | } 100 | 101 | rtems_task Task02( rtems_task_argument ignored ) 102 | { 103 | size_t size; 104 | 105 | /* find recieve overhead - no preempt or task switch */ 106 | benchmark_timer_initialize(); 107 | (void) rtems_message_queue_receive( 108 | Queue_id, 109 | (long (*)[4]) Buffer, 110 | &size, 111 | RTEMS_DEFAULT_OPTIONS, 112 | RTEMS_NO_TIMEOUT 113 | ); 114 | treceive_overhead = benchmark_timer_read(); 115 | 116 | /* Benchmark code */ 117 | benchmark_timer_initialize(); 118 | for ( count = 0; count < BENCHMARKS - 1; count++ ) { 119 | (void) rtems_message_queue_receive( 120 | Queue_id, 121 | (long (*)[4]) Buffer, 122 | &size, 123 | RTEMS_DEFAULT_OPTIONS, 124 | RTEMS_NO_TIMEOUT 125 | ); 126 | } 127 | telapsed = benchmark_timer_read(); 128 | 129 | put_time( 130 | "Rhealstone: Intertask Message Latency", 131 | telapsed, /* Total time of all benchmarks */ 132 | BENCHMARKS - 1, /* Total benchmarks */ 133 | tloop_overhead, /* Overhead of loops */ 134 | treceive_overhead /* Overhead of recieve call and task switch */ 135 | ); 136 | 137 | rtems_test_exit( 0 ); 138 | } 139 | 140 | /* configuration information */ 141 | 142 | #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER 143 | #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER 144 | 145 | #define CONFIGURE_MAXIMUM_TASKS 3 146 | #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 1 147 | #define CONFIGURE_TICKS_PER_TIMESLICE 0 148 | #define CONFIGURE_INIT 149 | #define CONFIGURE_RTEMS_INIT_TASKS_TABLE 150 | 151 | #include 152 | -------------------------------------------------------------------------------- /semaphore-shuffle/semaphore-shuffle.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Daniel Ramirez. (javamonn@gmail.com) 3 | * 4 | * This file's license is 2-clause BSD as in this distribution's LICENSE file. 5 | */ 6 | 7 | #include "tmacros.h" 8 | #include "timesys.h" 9 | 10 | #define BENCHMARKS 50000 11 | 12 | rtems_task Task01( rtems_task_argument ignored ); 13 | rtems_task Task02( rtems_task_argument ignored ); 14 | rtems_task Init( rtems_task_argument ignored ); 15 | 16 | rtems_id Task_id[2]; 17 | rtems_name Task_name[2]; 18 | rtems_id sem_id; 19 | rtems_name sem_name; 20 | 21 | uint32_t telapsed; 22 | uint32_t tswitch_overhead; 23 | uint32_t count; 24 | uint32_t sem_exe; 25 | 26 | rtems_task Init( rtems_task_argument ignored ) 27 | { 28 | rtems_status_code status; 29 | rtems_attribute sem_attr; 30 | rtems_task_priority pri; 31 | rtems_mode prev_mode; 32 | 33 | sem_attr = RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY; 34 | 35 | sem_name = rtems_build_name( 'S','0',' ',' ' ); 36 | status = rtems_semaphore_create( 37 | sem_name, 38 | 1, 39 | sem_attr, 40 | 0, 41 | &sem_id 42 | ); 43 | directive_failed( status, "rtems_semaphore_create of S0" ); 44 | 45 | Task_name[0] = rtems_build_name( 'T','A','0','1' ); 46 | status = rtems_task_create( 47 | Task_name[0], 48 | 30, 49 | RTEMS_MINIMUM_STACK_SIZE, 50 | RTEMS_DEFAULT_MODES, 51 | RTEMS_DEFAULT_ATTRIBUTES, 52 | &Task_id[0] 53 | ); 54 | directive_failed( status, "rtems_task_create of TA01" ); 55 | 56 | Task_name[1] = rtems_build_name( 'T','A','0','2' ); 57 | status = rtems_task_create( 58 | Task_name[1], 59 | 30, 60 | RTEMS_MINIMUM_STACK_SIZE, 61 | RTEMS_DEFAULT_MODES, 62 | RTEMS_DEFAULT_ATTRIBUTES, 63 | &Task_id[1] 64 | ); 65 | directive_failed( status , "rtems_task_create of TA02\n" ); 66 | 67 | rtems_task_mode( RTEMS_PREEMPT, RTEMS_PREEMPT_MASK, &prev_mode ); 68 | /* Lower own priority so TA01 can start up and run */ 69 | rtems_task_set_priority( RTEMS_SELF, 40, &pri); 70 | 71 | /* Get time of benchmark with no semaphore shuffling */ 72 | sem_exe = 0; 73 | status = rtems_task_start( Task_id[0], Task01, 0 ); 74 | directive_failed( status, "rtems_task_start of TA01" ); 75 | 76 | /* Get time of benchmark with semaphore shuffling */ 77 | sem_exe = 1; 78 | status = rtems_task_restart( Task_id[0], 0 ); 79 | directive_failed( status, "rtems_task_restart of TA01" ); 80 | 81 | /* Should never reach here */ 82 | rtems_test_assert( false ); 83 | } 84 | 85 | rtems_task Task01( rtems_task_argument ignored ) 86 | { 87 | rtems_status_code status; 88 | 89 | /* Start up TA02, yield so it can run */ 90 | if ( sem_exe == 0 ) { 91 | status = rtems_task_start( Task_id[1], Task02, 0 ); 92 | directive_failed( status, "rtems_task_start of TA02" ); 93 | } else { 94 | status = rtems_task_restart( Task_id[1], 0 ); 95 | directive_failed( status, "rtems_task_restart of TA02" ); 96 | } 97 | rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); 98 | 99 | /* Benchmark code */ 100 | for ( ; count < BENCHMARKS ; ) { 101 | if ( sem_exe == 1 ) { 102 | rtems_semaphore_obtain( sem_id, RTEMS_WAIT, 0 ); 103 | } 104 | rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); 105 | 106 | if ( sem_exe == 1 ) { 107 | rtems_semaphore_release( sem_id ); 108 | } 109 | rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); 110 | } 111 | 112 | /* Should never reach here */ 113 | rtems_test_assert( false ); 114 | } 115 | 116 | rtems_task Task02( rtems_task_argument ignored ) 117 | { 118 | 119 | /* Benchmark code */ 120 | benchmark_timer_initialize(); 121 | for ( count = 0; count < BENCHMARKS; count++ ) { 122 | if ( sem_exe == 1 ) { 123 | rtems_semaphore_obtain( sem_id, RTEMS_WAIT, 0 ); 124 | } 125 | rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); 126 | 127 | if ( sem_exe == 1 ) { 128 | rtems_semaphore_release( sem_id ); 129 | } 130 | rtems_task_wake_after( RTEMS_YIELD_PROCESSOR ); 131 | } 132 | telapsed = benchmark_timer_read(); 133 | 134 | /* Check which run this was */ 135 | if (sem_exe == 0) { 136 | tswitch_overhead = telapsed; 137 | rtems_task_suspend( Task_id[0] ); 138 | rtems_task_suspend( RTEMS_SELF ); 139 | } else { 140 | put_time( 141 | "Rhealstone: Semaphore Shuffle", 142 | telapsed, 143 | (BENCHMARKS * 2), /* Total number of semaphore-shuffles*/ 144 | tswitch_overhead, /* Overhead of loop and task switches */ 145 | 0 146 | ); 147 | rtems_test_exit( 0 ); 148 | } 149 | } 150 | 151 | /* configuration information */ 152 | #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER 153 | #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER 154 | #define CONFIGURE_RTEMS_INIT_TASKS_TABLE 155 | #define CONFIGURE_MAXIMUM_TASKS 3 156 | #define CONFIGURE_MAXIMUM_SEMAPHORES 1 157 | #define CONFIGURE_INIT 158 | #include 159 | -------------------------------------------------------------------------------- /deadlock-break/deadlock-break.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Daniel Ramirez. (javamonn@gmail.com) 3 | * 4 | * This file's license is 2-clause BSD as in this distribution's LICENSE file. 5 | */ 6 | 7 | #include 8 | #include "tmacros.h" 9 | #include "timesys.h" 10 | 11 | #define BENCHMARKS 20000 12 | 13 | rtems_task Task01( rtems_task_argument ignored ); 14 | rtems_task Task02( rtems_task_argument ignored ); 15 | rtems_task Task03( rtems_task_argument ignored ); 16 | rtems_task Init( rtems_task_argument ignored ); 17 | 18 | rtems_id Task_id[3]; 19 | rtems_name Task_name[3]; 20 | rtems_id sem_id; 21 | rtems_name sem_name; 22 | rtems_status_code status; 23 | 24 | uint32_t count; 25 | uint32_t telapsed; 26 | uint32_t tswitch_overhead; 27 | uint32_t tobtain_overhead; 28 | uint32_t sem_exe; 29 | 30 | rtems_task Init( rtems_task_argument ignored ) 31 | { 32 | rtems_attribute sem_attr; 33 | rtems_task_priority pri; 34 | rtems_mode prev_mode; 35 | 36 | sem_attr = RTEMS_INHERIT_PRIORITY | RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY; 37 | 38 | sem_name = rtems_build_name( 'S','0',' ',' ' ); 39 | status = rtems_semaphore_create( 40 | sem_name, 41 | 1, 42 | sem_attr, 43 | 0, 44 | &sem_id 45 | ); 46 | directive_failed( status, "rtems_semaphore_create of S0" ); 47 | 48 | Task_name[0] = rtems_build_name( 'T','A','0','1' ); 49 | status = rtems_task_create( 50 | Task_name[0], 51 | 26, /* High priority task */ 52 | RTEMS_MINIMUM_STACK_SIZE, 53 | RTEMS_DEFAULT_MODES, 54 | RTEMS_DEFAULT_ATTRIBUTES, 55 | &Task_id[0] 56 | ); 57 | directive_failed( status, "rtems_task_create of TA01" ); 58 | 59 | Task_name[1] = rtems_build_name( 'T','A','0','2' ); 60 | status = rtems_task_create( 61 | Task_name[1], 62 | 28, /* Mid priority task */ 63 | RTEMS_MINIMUM_STACK_SIZE, 64 | RTEMS_DEFAULT_MODES, 65 | RTEMS_DEFAULT_ATTRIBUTES, 66 | &Task_id[1] 67 | ); 68 | directive_failed( status, "rtems_task_create of TA02" ); 69 | 70 | Task_name[2] = rtems_build_name( 'T','A','0','3' ); 71 | status = rtems_task_create( 72 | Task_name[2], 73 | 30, /* Low priority task */ 74 | RTEMS_MINIMUM_STACK_SIZE, 75 | RTEMS_DEFAULT_MODES, 76 | RTEMS_DEFAULT_ATTRIBUTES, 77 | &Task_id[2] 78 | ); 79 | directive_failed( status, "rtems_task_create of TA03" ); 80 | 81 | /* find overhead of obtaining semaphore */ 82 | benchmark_timer_initialize(); 83 | rtems_semaphore_obtain( sem_id, RTEMS_WAIT, 0 ); 84 | tobtain_overhead = benchmark_timer_read(); 85 | rtems_semaphore_release( sem_id ); 86 | 87 | rtems_task_mode( RTEMS_PREEMPT, RTEMS_PREEMPT_MASK, &prev_mode ); 88 | /* Lower own priority so tasks can start up and run */ 89 | rtems_task_set_priority( RTEMS_SELF, 40, &pri ); 90 | 91 | /* Get time of benchmark with no semaphores involved, i.e. find overhead */ 92 | sem_exe = 0; 93 | status = rtems_task_start( Task_id[2], Task03, 0 ); 94 | directive_failed( status, "rtems_task_start of TA03" ); 95 | 96 | /* Get time of benchmark with semaphores */ 97 | sem_exe = 1; 98 | status = rtems_task_restart( Task_id[2], 0 ); 99 | directive_failed( status, "rtems_task_start of TA03" ); 100 | 101 | /* Should never reach here */ 102 | rtems_test_assert( false ); 103 | } 104 | 105 | rtems_task Task01( rtems_task_argument ignored ) 106 | { 107 | /* All tasks have had time to start up once TA01 is running */ 108 | 109 | /* Benchmark code */ 110 | benchmark_timer_initialize(); 111 | for ( count = 0; count < BENCHMARKS; count++ ) { 112 | if ( sem_exe == 1 ) { 113 | /* Block on call */ 114 | rtems_semaphore_obtain( sem_id, RTEMS_WAIT, 0 ); 115 | } 116 | 117 | if ( sem_exe == 1 ) { 118 | /* Release semaphore immediately after obtaining it */ 119 | rtems_semaphore_release( sem_id ); 120 | } 121 | 122 | /* Suspend self, go to TA02 */ 123 | rtems_task_suspend( RTEMS_SELF ); 124 | } 125 | telapsed = benchmark_timer_read(); 126 | 127 | /* Check which run this was */ 128 | if (sem_exe == 0) { 129 | tswitch_overhead = telapsed; 130 | rtems_task_suspend( Task_id[1] ); 131 | rtems_task_suspend( Task_id[2] ); 132 | rtems_task_suspend( RTEMS_SELF ); 133 | } else { 134 | put_time( 135 | "Rhealstone: Deadlock Break", 136 | telapsed, 137 | BENCHMARKS, /* Total number of times deadlock broken*/ 138 | tswitch_overhead, /* Overhead of loop and task switches */ 139 | tobtain_overhead 140 | ); 141 | rtems_test_exit( 0 ); 142 | } 143 | 144 | } 145 | 146 | rtems_task Task02( rtems_task_argument ignored ) 147 | { 148 | /* Start up TA01, get preempted */ 149 | if ( sem_exe == 1) { 150 | status = rtems_task_restart( Task_id[0], 0); 151 | directive_failed( status, "rtems_task_start of TA01"); 152 | } else { 153 | status = rtems_task_start( Task_id[0], Task01, 0); 154 | directive_failed( status, "rtems_task_start of TA01"); 155 | } 156 | 157 | /* Benchmark code */ 158 | for ( ; count < BENCHMARKS ; ) { 159 | /* Suspend self, go to TA01 */ 160 | rtems_task_suspend( RTEMS_SELF ); 161 | 162 | /* Wake up TA01, get preempted */ 163 | rtems_task_resume( Task_id[0] ); 164 | } 165 | } 166 | 167 | rtems_task Task03( rtems_task_argument ignored ) 168 | { 169 | if (sem_exe == 1) { 170 | /* Low priority task holds mutex */ 171 | rtems_semaphore_obtain( sem_id, RTEMS_WAIT, 0 ); 172 | } 173 | 174 | /* Start up TA02, get preempted */ 175 | if ( sem_exe == 1) { 176 | status = rtems_task_restart( Task_id[1], 0); 177 | directive_failed( status, "rtems_task_start of TA02"); 178 | } else { 179 | status = rtems_task_start( Task_id[1], Task02, 0); 180 | directive_failed( status, "rtems_task_start of TA02"); 181 | } 182 | 183 | /* Benchmark code */ 184 | for ( ; count < BENCHMARKS ; ) { 185 | if ( sem_exe == 1 ) { 186 | /* Preempted by TA01 upon release */ 187 | rtems_semaphore_release( sem_id ); 188 | } 189 | 190 | if ( sem_exe == 1 ) { 191 | /* Prepare for next Benchmark */ 192 | rtems_semaphore_obtain( sem_id, RTEMS_WAIT, 0 ); 193 | } 194 | /* Wake up TA02, get preempted */ 195 | rtems_task_resume( Task_id[1] ); 196 | } 197 | } 198 | 199 | /* configuration information */ 200 | #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER 201 | #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER 202 | #define CONFIGURE_TICKS_PER_TIMESLICE 0 203 | #define CONFIGURE_RTEMS_INIT_TASKS_TABLE 204 | #define CONFIGURE_MAXIMUM_SEMAPHORES 1 205 | #define CONFIGURE_MAXIMUM_TASKS 4 206 | #define CONFIGURE_INIT 207 | #include 208 | -------------------------------------------------------------------------------- /support/tmacros.h: -------------------------------------------------------------------------------- 1 | /* tmacros.h 2 | * 3 | * This include file contains macros which are useful in the RTEMS 4 | * test suites. 5 | * 6 | * COPYRIGHT (c) 1989-2009. 7 | * On-Line Applications Research Corporation (OAR). 8 | * 9 | * The license and distribution terms for this file may be 10 | * found in the file LICENSE in this distribution or at 11 | * http://www.rtems.com/license/LICENSE. 12 | */ 13 | 14 | #ifndef __TMACROS_h 15 | #define __TMACROS_h 16 | 17 | #include 18 | #include /* includes */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | 32 | #define FOREVER 1 /* infinite loop */ 33 | 34 | #ifdef CONFIGURE_INIT 35 | #define TEST_EXTERN 36 | #else 37 | #define TEST_EXTERN extern 38 | #endif 39 | 40 | #include 41 | 42 | /* 43 | * Check that that the dispatch disable level is proper for the 44 | * mode/state of the test. Normally it should be 0 when in task space. 45 | * 46 | * This test is only valid when in a non smp system. In an smp system 47 | * another cpu may be accessing the core at any point when this core 48 | * does not have it locked. 49 | */ 50 | #if defined SMPTEST 51 | #define check_dispatch_disable_level( _expect ) 52 | #else 53 | #define check_dispatch_disable_level( _expect ) \ 54 | do { \ 55 | if ( (_expect) != -1 \ 56 | && ((!_Thread_Dispatch_is_enabled() == false && (_expect) != 0) \ 57 | || (!_Thread_Dispatch_is_enabled() && (_expect) == 0)) \ 58 | ) { \ 59 | printk( \ 60 | "\n_Thread_Dispatch_disable_level is (%" PRId32 \ 61 | ") not %d detected at %s:%d\n", \ 62 | !_Thread_Dispatch_is_enabled(), (_expect), __FILE__, __LINE__ ); \ 63 | FLUSH_OUTPUT(); \ 64 | rtems_test_exit( 1 ); \ 65 | } \ 66 | } while ( 0 ) 67 | #endif 68 | 69 | /* 70 | * These macros properly report errors within the Classic API 71 | */ 72 | #define directive_failed( _dirstat, _failmsg ) \ 73 | fatal_directive_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg ) 74 | 75 | #define directive_failed_with_level( _dirstat, _failmsg, _level ) \ 76 | fatal_directive_status_with_level( \ 77 | _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level ) 78 | 79 | #define fatal_directive_status( _stat, _desired, _msg ) \ 80 | fatal_directive_status_with_level( _stat, _desired, _msg, 0 ) 81 | 82 | #define fatal_directive_check_status_only( _stat, _desired, _msg ) \ 83 | do { \ 84 | if ( (_stat) != (_desired) ) { \ 85 | printf( "\n%s FAILED -- expected (%s) got (%s)\n", \ 86 | (_msg), rtems_status_text(_desired), rtems_status_text(_stat) ); \ 87 | FLUSH_OUTPUT(); \ 88 | rtems_test_exit( _stat ); \ 89 | } \ 90 | } while ( 0 ) 91 | 92 | #define fatal_directive_status_with_level( _stat, _desired, _msg, _level ) \ 93 | do { \ 94 | check_dispatch_disable_level( _level ); \ 95 | fatal_directive_check_status_only( _stat, _desired, _msg ); \ 96 | } while ( 0 ) 97 | 98 | /* 99 | * These macros properly report errors from the POSIX API 100 | */ 101 | 102 | #define posix_service_failed( _dirstat, _failmsg ) \ 103 | fatal_posix_service_status( _dirstat, 0, _failmsg ) 104 | 105 | #define posix_service_failed_with_level( _dirstat, _failmsg, _level ) \ 106 | fatal_posix_service_status_with_level( _dirstat, 0, _failmsg, _level ) 107 | 108 | #define fatal_posix_service_status_errno( _stat, _desired, _msg ) \ 109 | if ( (_stat != -1) && (errno) != (_desired) ) { \ 110 | long statx = _stat; \ 111 | check_dispatch_disable_level( 0 ); \ 112 | printf( "\n%s FAILED -- expected (%d - %s) got (%ld %d - %s)\n", \ 113 | (_msg), _desired, strerror(_desired), \ 114 | statx, errno, strerror(errno) ); \ 115 | FLUSH_OUTPUT(); \ 116 | rtems_test_exit( _stat ); \ 117 | } 118 | 119 | #define fatal_posix_service_status( _stat, _desired, _msg ) \ 120 | fatal_posix_service_status_with_level( _stat, _desired, _msg, 0 ) 121 | 122 | #define fatal_posix_service_status_with_level( _stat, _desired, _msg, _level ) \ 123 | do { \ 124 | check_dispatch_disable_level( _level ); \ 125 | if ( (_stat) != (_desired) ) { \ 126 | printf( "\n%s FAILED -- expected (%d - %s) got (%d - %s)\n", \ 127 | (_msg), _desired, strerror(_desired), _stat, strerror(_stat) ); \ 128 | printf( "\n FAILED -- errno (%d - %s)\n", \ 129 | errno, strerror(errno) ); \ 130 | FLUSH_OUTPUT(); \ 131 | rtems_test_exit( _stat ); \ 132 | } \ 133 | } while ( 0 ) 134 | 135 | /* 136 | * Generic integer version of the error reporting 137 | */ 138 | 139 | #define int_service_failed( _dirstat, _failmsg ) \ 140 | fatal_int_service_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg ) 141 | 142 | #define int_service_failed_with_level( _dirstat, _failmsg, _level ) \ 143 | fatal_int_service_status_with_level( \ 144 | _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level ) 145 | 146 | #define fatal_int_service_status( _stat, _desired, _msg ) \ 147 | fatal_int_service_status_with_level( _stat, _desired, _msg, 0 ) 148 | 149 | #define fatal_int_service_status_with_level( _stat, _desired, _msg, _level ) \ 150 | do { \ 151 | check_dispatch_disable_level( _level ); \ 152 | if ( (_stat) != (_desired) ) { \ 153 | printf( "\n%s FAILED -- expected (%d) got (%d)\n", \ 154 | (_msg), (_desired), (_stat) ); \ 155 | FLUSH_OUTPUT(); \ 156 | rtems_test_exit( _stat ); \ 157 | } \ 158 | } while ( 0 ) 159 | 160 | 161 | /* 162 | * Print the time 163 | */ 164 | 165 | #define sprint_time(_str, _s1, _tb, _s2) \ 166 | do { \ 167 | sprintf( (_str), "%s%02d:%02d:%02d %02d/%02d/%04d%s", \ 168 | _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \ 169 | (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \ 170 | } while ( 0 ) 171 | 172 | #define print_time(_s1, _tb, _s2) \ 173 | do { \ 174 | printf( "%s%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 " %02" PRIu32 "/%02" PRIu32 "/%04" PRIu32 "%s", \ 175 | _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \ 176 | (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \ 177 | } while ( 0 ) 178 | 179 | #define put_dot( _c ) \ 180 | do { \ 181 | putchar( _c ); \ 182 | FLUSH_OUTPUT(); \ 183 | } while ( 0 ) 184 | 185 | #define new_line puts( "" ) 186 | 187 | #define puts_nocr printf 188 | 189 | #ifdef RTEMS_TEST_NO_PAUSE 190 | #define rtems_test_pause() \ 191 | do { \ 192 | printf( "\n" ); \ 193 | FLUSH_OUTPUT(); \ 194 | } while ( 0 ) 195 | 196 | #define rtems_test_pause_and_screen_number( _screen ) \ 197 | do { \ 198 | printf( "\n", (_screen) ); \ 199 | FLUSH_OUTPUT(); \ 200 | } while ( 0 ) 201 | #else 202 | #define rtems_test_pause() \ 203 | do { \ 204 | char buffer[ 80 ]; \ 205 | printf( "" ); \ 206 | FLUSH_OUTPUT(); \ 207 | gets( buffer ); \ 208 | puts( "" ); \ 209 | } while ( 0 ) 210 | 211 | #define rtems_test_pause_and_screen_number( _screen ) \ 212 | do { \ 213 | char buffer[ 80 ]; \ 214 | printf( "", (_screen) ); \ 215 | FLUSH_OUTPUT(); \ 216 | gets( buffer ); \ 217 | puts( "" ); \ 218 | } while ( 0 ) 219 | #endif 220 | 221 | #define put_name( name, crlf ) \ 222 | { int c0, c1, c2, c3; \ 223 | c0 = (name >> 24) & 0xff; \ 224 | c1 = (name >> 16) & 0xff; \ 225 | c2 = (name >> 8) & 0xff; \ 226 | c3 = name & 0xff; \ 227 | putchar( (isprint(c0)) ? c0 : '*' ); \ 228 | if ( c1 ) putchar( (isprint(c1)) ? c1 : '*' ); \ 229 | if ( c2 ) putchar( (isprint(c2)) ? c2 : '*' ); \ 230 | if ( c3 ) putchar( (isprint(c3)) ? c3 : '*' ); \ 231 | if ( crlf ) \ 232 | putchar( '\n' ); \ 233 | } 234 | 235 | #ifndef build_time 236 | #define build_time( TB, MON, DAY, YR, HR, MIN, SEC, TK ) \ 237 | { (TB)->year = YR; \ 238 | (TB)->month = MON; \ 239 | (TB)->day = DAY; \ 240 | (TB)->hour = HR; \ 241 | (TB)->minute = MIN; \ 242 | (TB)->second = SEC; \ 243 | (TB)->ticks = TK; } 244 | #endif 245 | 246 | #define task_number( tid ) \ 247 | ( rtems_object_id_get_index( tid ) - \ 248 | rtems_configuration_get_rtems_api_configuration()-> \ 249 | number_of_initialization_tasks ) 250 | 251 | #define rtems_test_assert(__exp) \ 252 | do { \ 253 | if (!(__exp)) { \ 254 | printf( "%s: %d %s\n", __FILE__, __LINE__, #__exp ); \ 255 | rtems_test_exit(0); \ 256 | } \ 257 | } while (0) 258 | 259 | /* 260 | * Various inttypes.h-stype macros to assist printing 261 | * certain system types on different targets. 262 | */ 263 | 264 | #if defined(RTEMS_USE_16_BIT_OBJECT) 265 | #define PRIxrtems_id PRIx16 266 | #else 267 | #define PRIxrtems_id PRIx32 268 | #endif 269 | 270 | /* c.f. cpukit/score/include/rtems/score/priority.h */ 271 | #define PRIdPriority_Control PRId32 272 | #define PRIxPriority_Control PRIx32 273 | /* rtems_task_priority is a typedef to Priority_Control */ 274 | #define PRIdrtems_task_priority PRIdPriority_Control 275 | #define PRIxrtems_task_priority PRIxPriority_Control 276 | 277 | /* c.f. cpukit/score/include/rtems/score/watchdog.h */ 278 | #define PRIdWatchdog_Interval PRIu32 279 | /* rtems_interval is a typedef to Watchdog_Interval */ 280 | #define PRIdrtems_interval PRIdWatchdog_Interval 281 | 282 | /* c.f. cpukit/score/include/rtems/score/thread.h */ 283 | #define PRIdThread_Entry_numeric_type PRIuPTR 284 | /* rtems_task_argument is a typedef to Thread_Entry_numeric_type */ 285 | #define PRIdrtems_task_argument PRIdThread_Entry_numeric_type 286 | 287 | /* rtems_event_set is a typedef to unit32_t */ 288 | #define PRIxrtems_event_set PRIx32 289 | 290 | /* HACK: newlib defines pthread_t as a typedef to __uint32_t */ 291 | /* HACK: There is no portable way to print pthread_t's */ 292 | #define PRIxpthread_t PRIx32 293 | 294 | /* rtems_signal_set is a typedef to uint32_t */ 295 | #define PRIxrtems_signal_set PRIx32 296 | 297 | /* newlib's ino_t is a typedef to "unsigned long" */ 298 | #define PRIxino_t "lx" 299 | 300 | #ifdef __cplusplus 301 | } 302 | #endif 303 | 304 | #endif 305 | --------------------------------------------------------------------------------