Measured items

This section will describe the various tests and the numbers presented. All tests use the "C" kernel API (available by way of cyg/kernel/kapi.h). There is a single main thread in the system which performs the various tests. Additional threads may be created as part of the testing, but these are short lived and destroyed between tests unless otherwise noted. In this discussion, the terminology "lower priority" means a priority which is less important, not necessarily lower in numerical value. A higher priority thread will run in preference to a lower priority thread even though the priority value of the higher priority thread may be numerically less than that of the lower priority thread.

Thread primitives

Create thread

This test measures the cyg_thread_create() call. Each call creates a totally new thread. The set of threads created by this test will be re-used in the subsequent thread primitive tests.

Yield thread

This test measures the cyg_thread_yield() call. For this test, there are no other runnable threads, thus the test should just measure the overhead of trying to give up the CPU.

Suspend [suspended] thread

This test measures the cyg_thread_suspend() call. Each thread is already suspended from its initial creation and is suspended again.

Resume thread

This test measures the cyg_thread_resume() call. All of the threads have a suspend count of 2, thus this call does not make them runnable. This test just measures the overhead of resuming a thread.

Set priority

This test measures the cyg_thread_set_priority() call. Each thread, currently suspended, has its priority set to a new value.

Get priority

This test measures the cyg_thread_get_priority() call.

Kill [suspended] thread

This test measures the cyg_thread_kill() call. Each thread in the set is killed. All threads are known to be suspended before being killed.

Yield [no other] thread

This test measures the cyg_thread_yield() call again. This is to demonstrate that the cyg_thread_yield() call has a fixed overhead, regardless of whether there are other threads in the system.

Resume [suspended low priority] thread

This test measures the cyg_thread_resume() call again. In this case, the thread being resumed is lower priority than the main thread, thus it will simply become ready to run but not be granted the CPU. This test measures the cost of making a thread ready to run.

Resume [runnable low priority] thread

This test measures the cyg_thread_resume() call again. In this case, the thread being resumed is lower priority than the main thread and has already been made runnable, so in fact the resume call has no effect.

Suspend [runnable] thread

This test measures the cyg_thread_suspend() call again. In this case, each thread has already been made runnable (by previous tests).

Yield [only low prio] thread

This test measures the cyg_thread_yield() call. In this case, there are many other runnable threads, but they are all lower priority than the main thread, thus no thread switches will take place.

Suspend [runnable->not runnable] thread

This test measures the cyg_thread_suspend() call again. The thread being suspended will become non-runnable by this action.

Kill [runnable] thread

This test measures the cyg_thread_kill() call again. In this case, the thread being killed is currently runnable, but lower priority than the main thread.

Resume [high priority] thread

This test measures the cyg_thread_resume() call. The thread being resumed is higher priority than the main thread, thus a thread switch will take place on each call. In fact there will be two thread switches; one to the new higher priority thread and a second back to the test thread. The test thread exits immediately.

Thread switch

This test attempts to measure the cost of switching from one thread to another. Two equal priority threads are started and they will each yield to the other for a number of iterations. A time stamp is gatherered in one thread before the cyg_thread_yield() call and after the call in the other thread.

Scheduler primitives

Scheduler lock

This test measures the cyg_scheduler_lock() call.

Scheduler unlock [0 threads]

This test mesures the cyg_scheduler_unlock() call. There are no other threads in the system and the unlock happens immediately after a lock so there will be no pending DSRs to run.

Scheduler unlock [1 suspended thread]

This test measures the cyg_scheduler_unlock() call. There is a single other thread in the system which is currently suspended.

Scheduler unlock [many suspended threads]

This test measures the cyg_scheduler_unlock() call. There is are many other thread in the system which are currently suspended. The purpose of this test is to determine the cost of having additional threads in the system when the scheduler is activated via cyg_scheduler_unlock().

Scheduler unlock [many low prio threads]

This test measures the cyg_scheduler_unlock() call. There is are many other thread in the system which are runnable but lower priority than the main thread. The purpose of this test is to determine the cost of having additional threads in the system when the scheduler is activated via cyg_scheduler_unlock().

Mutex primitives

Init mutex

This test measures the cyg_mutex_init() call. A number of separate mutex variables are created. The purpose of this test is to measure the cost of creating a new mutex and introducing it to the system.

Lock [unlocked] mutex

This test measures the cyg_mutex_lock() call. The purpose of this test is to measure the cost of locking a mutex which is currently unlocked. There are no other threads executing in the system while this test runs.

Unlock [locked] mutex

This test measures the cyg_mutex_unlock() call. The purpose of this test is to measure the cost of unlocking a mutex which is currently locked. There are no other threads executing in the system while this test runs.

Trylock [unlocked] mutex

This test measures the cyg_mutex_trylock() call. The purpose of this test is to measure the cost of locking a mutex which is currently unlocked. There are no other threads executing in the system while this test runs.

Trylock [locked] mutex

This test measures the cyg_mutex_trylock() call. The purpose of this test is to measure the cost of locking a mutex which is currently locked. There are no other threads executing in the system while this test runs.

Destroy mutex

This test measures the cyg_mutex_destroy() call. The purpose of this test is to measure the cost of deleting a mutex from the system. There are no other threads executing in the system while this test runs.

Unlock/Lock mutex

This test attempts to measure the cost of unlocking a mutex for which there is another higher priority thread waiting. When the mutex is unlocked, the higher priority waiting thread will immediately take the lock. The time from when the unlock is issued until after the lock succeeds in the second thread is measured, thus giving the round-trip or circuit time for this type of synchronizer.

Mailbox primitives

Create mbox

This test measures the cyg_mbox_create() call. A number of separate mailboxes is created. The purpose of this test is to measure the cost of creating a new mailbox and introducing it to the system.

Peek [empty] mbox

This test measures the cyg_mbox_peek() call. An attempt is made to peek the value in each mailbox, which is currently empty. The purpose of this test is to measure the cost of checking a mailbox for a value without blocking.

Put [first] mbox

This test measures the cyg_mbox_put() call. One item is added to a currently empty mailbox. The purpose of this test is to measure the cost of adding an item to a mailbox. There are no other threads currently waiting for mailbox items to arrive.

Peek [1 msg] mbox

This test measures the cyg_mbox_peek() call. An attempt is made to peek the value in each mailbox, which contains a single item. The purpose of this test is to measure the cost of checking a mailbox which has data to deliver.

Put [second] mbox

This test measures the cyg_mbox_put() call. A second item is added to a mailbox. The purpose of this test is to measure the cost of adding an additional item to a mailbox. There are no other threads currently waiting for mailbox items to arrive.

Peek [2 msgs] mbox

This test measures the cyg_mbox_peek() call. An attempt is made to peek the value in each mailbox, which contains two items. The purpose of this test is to measure the cost of checking a mailbox which has data to deliver.

Get [first] mbox

This test measures the cyg_mbox_get() call. The first item is removed from a mailbox that currently contains two items. The purpose of this test is to measure the cost of obtaining an item from a mailbox without blocking.

Get [second] mbox

This test measures the cyg_mbox_get() call. The last item is removed from a mailbox that currently contains one items. The purpose of this test is to measure the cost of obtaining an item from a mailbox without blocking.

Tryput [first] mbox

This test measures the cyg_mbox_tryput() call. A single item is added to a currently empty mailbox. The purpose of this test is to measure the cost of adding an item to a mailbox.

Peek item [non-empty] mbox

This test measurest the cyg_mbox_peek_item() call. A single item is fetched from mailbox which contains a single item. The purpose of this test is to measure the cost of obtaining an item without disturbing the mailbox.

Tryget [non-empty] mbox

This test measures the cyg_mbox_tryget() call. A single item is removed from a mailbox that contains exactly one item. The purpose of this test is to measure the cost of obtaining one item from a non-empty mailbox.

Peek item [empty] mbox

This test measures the cyg_mbox_peek_item() call. A attempty is made to fetch an item from mailbox which is empty. The purpose of this test is to measure the cost of trying to obtain an item when the mailbox is empty.

Tryget [empty] mbox

This test measures the cyg_mbox_tryget() call. A attempty is made to fetch an item from mailbox which is empty. The purpose of this test is to measure the cost of trying to obtain an item when the mailbox is empty.

Waiting to get mbox

This test measures the cyg_mbox_waiting_to_get() call. The purpose of this test is to measure the cost of determining how many threads are waiting to obtain a message from this mailbox.

Waiting to put mbox

This test measures the cyg_mbox_waiting_to_put() call. The purpose of this test is to measure the cost of determining how many threads are waiting to put a message into this mailbox.

Delete mbox

This test measures the cyg_mbox_delete() call. The purpose of this test is to measure the cost of destroying a mailbox and removing it from the system.

Put/Get mbox

In this round-trip test, one thread is sending data to a mailbox which is being consumed by another thread. The time from when the data is put into the mailbox until it has been delivered to the waiting thread is measured. Note that this time will contain a thread switch.

Semaphore primitives

Init semaphore

This test measures the cyg_semaphore_init() call. A number of separate semaphore objects are created and introduced to the system. The purpose of this test is to measure the cost of creating a new semaphore.

Post [0] semaphore

This test measures the cyg_semaphore_post() call. Each semaphore currently has a value of 0 and there are no other threads in the system. The purpose of this test is to measure the overhead cost of posting to a semaphore. This cost will differ if there is a thread waiting for the semaphore.

Wait [1] semaphore

This test measures the cyg_semaphore_wait() call. The semaphore has a current value of 1 so the call is non-blocking. The purpose of the test is to measure the overhead of "taking" a semaphore.

Trywait [0] semaphore

This test measures the cyg_semaphore_trywait() call. The semaphore has a value of 0 when the call is made. The purpose of this test is to measure the cost of seeing if a semaphore can be taken without blocking. In this case, the answer would be no.

Trywait [1] semaphore

This test measures the cyg_semaphore_trywait() call. The semaphore has a value of 1 when the call is made. The purpose of this test is to measure the cost of seeing if a semaphore can be taken without blocking. In this case, the answer would be yes.

Peek semaphore

This test measures the cyg_semaphore_peek() call. The purpose of this test is to measure the cost of obtaining the current semaphore count value.

Destroy semaphore

This test measures the cyg_semaphore_destroy() call. The purpose of this test is to measure the cost of deleting a semaphore from the system.

Post/Wait semaphore

In this round-trip test, two threads are passing control back and forth by using a semaphore. The time from when one thread calls cyg_semaphore_post() until the other thread completes its cyg_semaphore_wait() is measured. Note that each iteration of this test will involve a thread switch.

Counters

Create counter

This test measures the cyg_counter_create() call. A number of separate counters are created. The purpose of this test is to measure the cost of creating a new counter and introducing it to the system.

Get counter value

This test measures the cyg_counter_current_value() call. The current value of each counter is obtained.

Set counter value

This test measures the cyg_counter_set_value() call. Each counter is set to a new value.

Tick counter

This test measures the cyg_counter_tick() call. Each counter is "ticked" once.

Delete counter

This test measures the cyg_counter_delete() call. Each counter is deleted from the sytem. The purpose of this test is to measure the cost of deleting a counter object.

Alarms

Create alarm

This test measures the cyg_alarm_create() call. A number of separate alarms are created, all attached to the same counter object. The purpose of this test is to measure the cost of creating a new counter and introducing it to the system.

Initialize alarm

This test measures the cyg_alarm_initialize() call. Each alarm is initialized to a small value.

Disable alarm

This test measures the cyg_alarm_disable() call. Each alarm is explicitly disabled.

Enable alarm

This test measures the cyg_alarm_enable() call. Each alarm is explicitly enabled.

Delete alarm

This test measures the cyg_alarm_delete() call. Each alarm is destroyed. The purpose of this test is to measure the cost of deleting an alarm and removing it from the sytem.

Tick counter [1 alarm]

This test measures the cyg_counter_tick() call. A counter is created which has a single alarm attached to it. The purpose of this test is to measure the cost of "ticking" a counter when it has a single attached alarm. In this test, the alarm is not activated (fired).

Tick counter [many alarms]

This test measures the cyg_counter_tick() call. A counter is created which has multiple alarms attached to it. The purpose of this test is to measure the cost of "ticking" a counter when it has many attached alarms. In this test, the alarms are not activated (fired).

Tick & fire counter [1 alarm]

This test measures the cyg_counter_tick() call. A counter is created which has a single alarm attached to it. The purpose of this test is to measure the cost of "ticking" a counter when it has a single attached alarm. In this test, the alarm is activated (fired). Thus the measured time will include the overhead of calling the alarm callback function.

Tick & fire counter [many alarms]

This test measures the cyg_counter_tick() call. A counter is created which has multiple alarms attached to it. The purpose of this test is to measure the cost of "ticking" a counter when it has many attached alarms. In this test, the alarms are activated (fired). Thus the measured time will include the overhead of calling the alarm callback function.

Alarm latency [0 threads]

This test attempts to measure the latency in calling an alarm callback function. The time from the clock interrupt until the alarm function is called is measured. In this test, there are no threads which can be run when the clock interrupt occurs (all threads are suspended).

Alarm latency [2 threads]

This test attempts to measure the latency in calling an alarm callback function. The time from the clock interrupt until the alarm function is called is measured. In this test, there are exactly two threads which are running when the clock interrupt occurs. They are simply passing back and forth via the cyg_thread_yield() call. The purpose of this test is to measure the variations in the latency when there are executing threads.

Alarm latency [many threads]

This test attempts to measure the latency in calling an alarm callback function. The time from the clock interrupt until the alarm function is called is measured. In this test, there are a number of threads which are running when the clock interrupt occurs. They are simply passing back and forth via the cyg_thread_yield() call. The purpose of this test is to measure the variations in the latency when there are many executing threads.