mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
cpukit/rtems: add rtems_barrier_get_number_waiting()
Closes rtems/programs/gsoc#9 Added rtems_get_number_waiting according to the issue rtems/programs/gsoc#9, including tests and documentation.
This commit is contained in:
@@ -349,6 +349,43 @@ rtems_status_code rtems_barrier_wait( rtems_id id, rtems_interval timeout );
|
||||
*/
|
||||
rtems_status_code rtems_barrier_release( rtems_id id, uint32_t *released );
|
||||
|
||||
/* Generated from spec:/rtems/barrier/if/get-number-waiting */
|
||||
|
||||
/**
|
||||
* @ingroup RTEMSAPIClassicBarrier
|
||||
*
|
||||
* @brief Gets the number of tasks waiting at the barrier.
|
||||
*
|
||||
* @param id is the barrier identifier.
|
||||
*
|
||||
* @param[out] waiting is the pointer to an uint32_t object. When the directive
|
||||
* call is successful, the number of waiting tasks will be stored in this
|
||||
* object.
|
||||
*
|
||||
* This directive gets the number of tasks waiting at the barrier specified by
|
||||
* ``id``. The number of waiting tasks will be returned in ``waiting``.
|
||||
*
|
||||
* @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
|
||||
*
|
||||
* @retval ::RTEMS_INVALID_ADDRESS The ``waiting`` parameter was NULL.
|
||||
*
|
||||
* @retval ::RTEMS_INVALID_ID There was no barrier associated with the
|
||||
* identifier specified by ``id``.
|
||||
*
|
||||
* @par Constraints
|
||||
* @parblock
|
||||
* The following constraints apply to this directive:
|
||||
*
|
||||
* * The directive may be called from within interrupt context.
|
||||
*
|
||||
* * The directive may be called from within task context.
|
||||
* @endparblock
|
||||
*/
|
||||
rtems_status_code rtems_barrier_get_number_waiting(
|
||||
rtems_id id,
|
||||
uint32_t *waiting
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -189,6 +189,23 @@ static inline void _CORE_barrier_Flush(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the number of threads waiting at the barrier.
|
||||
*
|
||||
* This routine returns the count of threads currently waiting at the barrier.
|
||||
*
|
||||
* @param[in] the_barrier The barrier to check.
|
||||
* @param[in] queue_context The thread queue context.
|
||||
*
|
||||
* @return The number of threads currently waiting at the barrier.
|
||||
*/
|
||||
static inline uint32_t _CORE_barrier_Get_number_waiting(
|
||||
const CORE_barrier_Control *the_barrier
|
||||
)
|
||||
{
|
||||
return the_barrier->number_of_waiting_threads;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
68
cpukit/rtems/src/barriergetnumwaiting.c
Normal file
68
cpukit/rtems/src/barriergetnumwaiting.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSImplClassicBarrier
|
||||
*
|
||||
* @brief This source file contains the implementation of
|
||||
* rtems_barrier_get_number_waiting().
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Mazen Adel Elmessady
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/rtems/barrierimpl.h>
|
||||
|
||||
rtems_status_code rtems_barrier_get_number_waiting(
|
||||
rtems_id id,
|
||||
uint32_t *waiting
|
||||
)
|
||||
{
|
||||
Barrier_Control *the_barrier;
|
||||
Thread_queue_Context queue_context;
|
||||
|
||||
if ( waiting == NULL ) {
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
the_barrier = _Barrier_Get( id, &queue_context );
|
||||
|
||||
if ( the_barrier == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
_CORE_barrier_Acquire_critical( &the_barrier->Barrier, &queue_context );
|
||||
|
||||
*waiting = _CORE_barrier_Get_number_waiting( &the_barrier->Barrier );
|
||||
|
||||
_CORE_barrier_Release( &the_barrier->Barrier, &queue_context );
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -1206,6 +1206,7 @@ source:
|
||||
- cpukit/rtems/src/barrierdelete.c
|
||||
- cpukit/rtems/src/barrierident.c
|
||||
- cpukit/rtems/src/barrierrelease.c
|
||||
- cpukit/rtems/src/barriergetnumwaiting.c
|
||||
- cpukit/rtems/src/barrierwait.c
|
||||
- cpukit/rtems/src/clockgetsecondssinceepoch.c
|
||||
- cpukit/rtems/src/clockgettickssinceboot.c
|
||||
|
||||
@@ -91,6 +91,7 @@ rtems_task Init(
|
||||
rtems_status_code status;
|
||||
rtems_name name = rtems_build_name('B','A','R','1');
|
||||
uint32_t released;
|
||||
uint32_t waiting;
|
||||
rtems_id testId;
|
||||
rtems_id Tasks[CONFIGURE_MAXIMUM_TASKS-1];
|
||||
uint32_t i;
|
||||
@@ -114,6 +115,14 @@ rtems_task Init(
|
||||
"rtems_barrier_release did not return RTEMS_INVALID_ID"
|
||||
);
|
||||
|
||||
puts( "rtems_barrier_get_number_waiting - bad id - INVALID_ID" );
|
||||
status = rtems_barrier_get_number_waiting( 100, &waiting );
|
||||
fatal_directive_status(
|
||||
status,
|
||||
RTEMS_INVALID_ID,
|
||||
"rtems_barrier_get_number_waiting did not return RTEMS_INVALID_ID"
|
||||
);
|
||||
|
||||
puts( "rtems_barrier_wait - bad id - INVALID_ID" );
|
||||
status = rtems_barrier_wait( 100, 10 );
|
||||
fatal_directive_status(
|
||||
@@ -202,6 +211,28 @@ rtems_task Init(
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
|
||||
/* Get number waiting with bad return pointer */
|
||||
puts(
|
||||
"rtems_barrier_get_number_waiting - NULL return count - INVALID_ADDRESS"
|
||||
);
|
||||
status = rtems_barrier_get_number_waiting( Barrier, NULL );
|
||||
fatal_directive_status(
|
||||
status,
|
||||
RTEMS_INVALID_ADDRESS,
|
||||
"rtems_barrier_get_number_waiting bad return pointer"
|
||||
);
|
||||
|
||||
/* number of waiting tasks must be 0 */
|
||||
status = rtems_barrier_get_number_waiting( Barrier, &waiting );
|
||||
directive_failed(status, "rtems_barrier_get_number_waiting");
|
||||
if ( waiting != 0 ) {
|
||||
printf(
|
||||
"ERROR -- rtems_barrier_get_number_waiting -- waiting != 0, = %" PRIu32,
|
||||
waiting
|
||||
);
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
|
||||
/* Create some tasks to wait for the barrier */
|
||||
SuccessfulCase = TRUE;
|
||||
DeletedCase = FALSE;
|
||||
@@ -225,6 +256,20 @@ rtems_task Init(
|
||||
status = rtems_task_wake_after( rtems_clock_get_ticks_per_second() );
|
||||
directive_failed(status, "rtems_task_wake_after");
|
||||
|
||||
/* Gets the number of tasks that are waiting at the barrier */
|
||||
puts( "Getting the number of tasks that are waiting at the barrier" );
|
||||
status = rtems_barrier_get_number_waiting( Barrier, &waiting );
|
||||
printf("Number of tasks waiting at the barrier: %" PRIu32 "\n", waiting);
|
||||
directive_failed(status, "rtems_barrier_get_number_waiting" );
|
||||
if ( waiting != ( CONFIGURE_MAXIMUM_TASKS - 1 ) ) {
|
||||
printf(
|
||||
"ERROR -- rtems_barrier_get_number_waiting -- waiting != %d, = %" PRIu32,
|
||||
( CONFIGURE_MAXIMUM_TASKS - 1 ),
|
||||
waiting
|
||||
);
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
|
||||
/* Release tasks which were waiting */
|
||||
puts( "Releasing tasks" );
|
||||
status = rtems_barrier_release( Barrier, &released );
|
||||
@@ -242,6 +287,21 @@ rtems_task Init(
|
||||
status = rtems_task_wake_after( rtems_clock_get_ticks_per_second() );
|
||||
directive_failed(status, "rtems_task_wake_after");
|
||||
|
||||
/* Gets the number of tasks that are waiting at the barrier */
|
||||
puts( "Getting the number of tasks that are waiting at the barrier" );
|
||||
status = rtems_barrier_get_number_waiting( Barrier, &waiting );
|
||||
printf("Number of tasks waiting at the barrier: %" PRIu32 "\n", waiting);
|
||||
directive_failed(status, "rtems_barrier_get_number_waiting" );
|
||||
if ( waiting != 0 ) {
|
||||
printf(
|
||||
"ERROR -- rtems_barrier_get_number_waiting -- waiting != %d, = %" PRIu32,
|
||||
0,
|
||||
waiting
|
||||
);
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
|
||||
|
||||
/* Create some tasks to wait for the barrier */
|
||||
SuccessfulCase = FALSE;
|
||||
DeletedCase = TRUE;
|
||||
|
||||
@@ -36,6 +36,7 @@ directives:
|
||||
status = rtems_barrier_ident
|
||||
status = rtems_barrier_wait
|
||||
status = rtems_barrier_release
|
||||
status = rtems_barrier_get_number_waiting
|
||||
|
||||
concepts:
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
*** TEST 33 ***
|
||||
rtems_barrier_delete - bad id - INVALID_ID
|
||||
rtems_barrier_release - bad id - INVALID_ID
|
||||
rtems_barrier_get_number_waiting - bad id - INVALID_ID
|
||||
rtems_barrier_wait - bad id - INVALID_ID
|
||||
Create barrier with automatic release and 0 max waiters
|
||||
rtems_barrier_create - bad name - INVALID_NAME
|
||||
@@ -10,6 +11,7 @@ rtems_barrier_create - too many
|
||||
Check barrier ident
|
||||
Wait on barrier w/timeout and TIMEOUT
|
||||
rtems_barrier_release - NULL return count - INVALID_ADDRESS
|
||||
rtems_barrier_get_number_waiting - NULL return count - INVALID_ADDRESS
|
||||
|
||||
*** Testing manual release of barrier ***
|
||||
Delay to let Waiters block
|
||||
@@ -17,12 +19,16 @@ Waiter 0 waiting on barrier
|
||||
Waiter 1 waiting on barrier
|
||||
Waiter 2 waiting on barrier
|
||||
Waiter 3 waiting on barrier
|
||||
Getting the number of tasks that are waiting at the barrier
|
||||
Number of tasks waiting at the barrier: 4
|
||||
Releasing tasks
|
||||
Delay to let Waiters print a message
|
||||
Waiter 0 back from barrier
|
||||
Waiter 1 back from barrier
|
||||
Waiter 2 back from barrier
|
||||
Waiter 3 back from barrier
|
||||
Getting the number of tasks that are waiting at the barrier
|
||||
Number of tasks waiting at the barrier: 0
|
||||
|
||||
*** Testing Deletion of barrier ***
|
||||
Delay to let Waiters block
|
||||
@@ -48,4 +54,6 @@ Waiter 3 back from barrier
|
||||
Waiter 0 back from barrier
|
||||
Waiter 1 back from barrier
|
||||
Waiter 2 back from barrier
|
||||
*** END OF TEST 33 ***
|
||||
|
||||
*** END OF TEST SP 33 ***
|
||||
|
||||
|
||||
Reference in New Issue
Block a user