mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
Compare commits
2 Commits
main
...
18b2ce8e81
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18b2ce8e81 | ||
|
|
61c35cff46 |
62
cpukit/posix/src/semclockwait.c
Normal file
62
cpukit/posix/src/semclockwait.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup POSIX_SEMAPHORE
|
||||
*
|
||||
* @brief This source file contains the implementation of sem_clockwait().
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/posix/posixapi.h>
|
||||
#include <rtems/posix/semaphoreimpl.h>
|
||||
#include <rtems/score/todimpl.h>
|
||||
|
||||
int sem_clockwait(
|
||||
sem_t *__restrict _sem,
|
||||
clockid_t clock_id,
|
||||
const struct timespec *__restrict abstime
|
||||
)
|
||||
{
|
||||
if ( !_POSIX_Is_valid_clock_id( clock_id ) ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
|
||||
|
||||
int status = _Semaphore_Wait_timed_clock (
|
||||
&_sem->_Semaphore,
|
||||
abstime,
|
||||
clock_id
|
||||
);
|
||||
return _POSIX_Zero_or_minus_one_plus_errno( status );
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @ingroup POSIX_SEMAPHORE POSIX Semaphores Support
|
||||
*
|
||||
* @brief Lock a Semaphore
|
||||
* @brief This source file contains the implementation of sem_timedwait().
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -48,48 +48,16 @@
|
||||
*/
|
||||
|
||||
int sem_timedwait(
|
||||
sem_t *__restrict _sem,
|
||||
sem_t *__restrict _sem,
|
||||
const struct timespec *__restrict abstime
|
||||
)
|
||||
{
|
||||
Sem_Control *sem;
|
||||
Thread_queue_Context queue_context;
|
||||
ISR_Level level;
|
||||
Thread_Control *executing;
|
||||
unsigned int count;
|
||||
|
||||
POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
|
||||
|
||||
sem = _Sem_Get( &_sem->_Semaphore );
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||
executing = _Sem_Queue_acquire_critical( sem, &queue_context );
|
||||
|
||||
count = sem->count;
|
||||
if ( RTEMS_PREDICT_TRUE( count > 0 ) ) {
|
||||
sem->count = count - 1;
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
return 0;
|
||||
} else {
|
||||
Status_Control status;
|
||||
|
||||
_Thread_queue_Context_set_thread_state(
|
||||
&queue_context,
|
||||
STATES_WAITING_FOR_SEMAPHORE
|
||||
);
|
||||
_Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
|
||||
&queue_context,
|
||||
abstime,
|
||||
true
|
||||
);
|
||||
_Thread_queue_Context_set_ISR_level( &queue_context, level );
|
||||
_Thread_queue_Enqueue(
|
||||
&sem->Queue.Queue,
|
||||
SEMAPHORE_TQ_OPERATIONS,
|
||||
executing,
|
||||
&queue_context
|
||||
);
|
||||
status = _Thread_Wait_get_status( executing );
|
||||
return _POSIX_Zero_or_minus_one_plus_errno( status );
|
||||
}
|
||||
int status = _Semaphore_Wait_timed_clock(
|
||||
&_sem->_Semaphore,
|
||||
abstime,
|
||||
CLOCK_REALTIME
|
||||
);
|
||||
return _POSIX_Zero_or_minus_one_plus_errno( status );
|
||||
}
|
||||
|
||||
@@ -95,6 +95,50 @@ void _Semaphore_Wait( struct _Semaphore_Control *_sem )
|
||||
}
|
||||
}
|
||||
|
||||
int _Semaphore_Wait_timed_clock(
|
||||
struct _Semaphore_Control *_sem,
|
||||
const struct timespec *abstime,
|
||||
clockid_t clock_id
|
||||
)
|
||||
{
|
||||
Sem_Control *sem;
|
||||
Thread_queue_Context queue_context;
|
||||
ISR_Level level;
|
||||
Thread_Control *executing;
|
||||
unsigned int count;
|
||||
|
||||
sem = _Sem_Get( _sem );
|
||||
_Thread_queue_Context_initialize( &queue_context );
|
||||
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||
executing = _Sem_Queue_acquire_critical( sem, &queue_context );
|
||||
|
||||
count = sem->count;
|
||||
if ( RTEMS_PREDICT_TRUE( count > 0 ) ) {
|
||||
sem->count = count - 1;
|
||||
_Sem_Queue_release( sem, level, &queue_context );
|
||||
return 0;
|
||||
}
|
||||
|
||||
_Thread_queue_Context_set_thread_state(
|
||||
&queue_context,
|
||||
STATES_WAITING_FOR_SEMAPHORE
|
||||
);
|
||||
_Thread_queue_Context_set_enqueue_timeout_by_clock_id_timespec(
|
||||
&queue_context,
|
||||
abstime,
|
||||
true,
|
||||
clock_id
|
||||
);
|
||||
_Thread_queue_Context_set_ISR_level( &queue_context, level );
|
||||
_Thread_queue_Enqueue(
|
||||
&sem->Queue.Queue,
|
||||
SEMAPHORE_TQ_OPERATIONS,
|
||||
executing,
|
||||
&queue_context
|
||||
);
|
||||
return _Thread_Wait_get_status( executing );
|
||||
}
|
||||
|
||||
int _Semaphore_Wait_timed_ticks( struct _Semaphore_Control *_sem, uint32_t ticks )
|
||||
{
|
||||
Sem_Control *sem;
|
||||
|
||||
@@ -1175,6 +1175,7 @@ source:
|
||||
- cpukit/posix/src/sched_setscheduler.c
|
||||
- cpukit/posix/src/sched_yield.c
|
||||
- cpukit/posix/src/semaphoredeletesupp.c
|
||||
- cpukit/posix/src/semclockwait.c
|
||||
- cpukit/posix/src/semclose.c
|
||||
- cpukit/posix/src/semdestroy.c
|
||||
- cpukit/posix/src/semgetvalue.c
|
||||
|
||||
@@ -213,6 +213,7 @@ static void test_sem_null(void)
|
||||
int rv;
|
||||
int val;
|
||||
struct timespec to;
|
||||
clockid_t clock_id;
|
||||
|
||||
/* This equality is important for POSIX_SEMAPHORE_VALIDATE_OBJECT() */
|
||||
rtems_test_assert( NULL == SEM_FAILED );
|
||||
@@ -249,6 +250,14 @@ static void test_sem_null(void)
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
errno = 0;
|
||||
clock_id = CLOCK_REALTIME;
|
||||
rv = sem_clockwait( NULL, clock_id, &to );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_getvalue( NULL, &val );
|
||||
rtems_test_assert( rv == -1 );
|
||||
@@ -271,6 +280,7 @@ static void test_sem_not_initialized(void)
|
||||
int rv;
|
||||
int val;
|
||||
struct timespec to;
|
||||
clockid_t clock_id;
|
||||
|
||||
memset( &sem, 0xff, sizeof( sem ) );
|
||||
|
||||
@@ -301,6 +311,14 @@ static void test_sem_not_initialized(void)
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
to.tv_sec = 1;
|
||||
to.tv_nsec = 1;
|
||||
errno = 0;
|
||||
clock_id = CLOCK_REALTIME;
|
||||
rv = sem_clockwait( NULL, clock_id, &to );
|
||||
rtems_test_assert( rv == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
|
||||
errno = 0;
|
||||
rv = sem_getvalue( &sem, &val );
|
||||
rtems_test_assert( rv == -1 );
|
||||
@@ -363,6 +381,7 @@ void *POSIX_Init(
|
||||
sem_t *n_sem2;
|
||||
struct timespec waittime;
|
||||
char failure_msg[80];
|
||||
clockid_t clock_id;
|
||||
|
||||
TEST_BEGIN();
|
||||
|
||||
@@ -488,6 +507,46 @@ void *POSIX_Init(
|
||||
fatal_posix_service_status( errno, EINVAL, "sem_init errno EINVAL");
|
||||
#endif
|
||||
|
||||
puts( "Init: sem_post - SUCCESSFUL" );
|
||||
status = sem_post(&sems[2]);
|
||||
fatal_posix_service_status( status, 0, "sem_post semaphore 2");
|
||||
/* sem[2].count = 1 */
|
||||
|
||||
puts( "Init: sem_clockwait CLOCK_MONOTONIC - SUCCESSFUL" );
|
||||
clock_id = CLOCK_MONOTONIC;
|
||||
clock_gettime(clock_id, &waittime);
|
||||
waittime.tv_sec += 1;
|
||||
waittime.tv_nsec = 100;
|
||||
status = sem_clockwait(&sems[2], clock_id, &waittime);
|
||||
fatal_posix_service_status( status, 0, "sem_clockwait CLOCK_MONOTONIC semaphore 2");
|
||||
/* sem[2].count = 0 */
|
||||
|
||||
puts( "Init: sem_clockwait CLOCK_MONOTONIC - UNSUCCESSFUL (ETIMEDOUT)" );
|
||||
status = sem_clockwait(&sems[2], clock_id, &waittime);
|
||||
fatal_posix_service_status( status, -1, "sem_clockwait CLOCK_MONOTONIC error return status");
|
||||
fatal_posix_service_status(
|
||||
errno, ETIMEDOUT, "sem_clockwait CLOCK_MONOTONIC errno ETIMEDOUT");
|
||||
|
||||
puts( "Init: sem_post - SUCCESSFUL" );
|
||||
status = sem_post(&sems[2]);
|
||||
fatal_posix_service_status( status, 0, "sem_post semaphore 2");
|
||||
/* sem[2].count = 1 */
|
||||
|
||||
puts( "Init: sem_clockwait CLOCK_REALTIME - SUCCESSFUL" );
|
||||
clock_id = CLOCK_REALTIME;
|
||||
clock_gettime(clock_id, &waittime);
|
||||
waittime.tv_sec += 1;
|
||||
waittime.tv_nsec = 100;
|
||||
status = sem_clockwait(&sems[2], clock_id, &waittime);
|
||||
fatal_posix_service_status( status, 0, "sem_clockwait CLOCK_REALTIME semaphore 2");
|
||||
/* sem[2].count = 0 */
|
||||
|
||||
puts( "Init: sem_clockwait CLOCK_REALTIME - UNSUCCESSFUL (ETIMEDOUT)" );
|
||||
status = sem_clockwait(&sems[2], clock_id, &waittime);
|
||||
fatal_posix_service_status( status, -1, "sem_clockwait CLOCK_REALTIME error return status");
|
||||
fatal_posix_service_status(
|
||||
errno, ETIMEDOUT, "sem_clockwait CLOCK_REALTIME errno ETIMEDOUT");
|
||||
|
||||
puts( "Init: sem_post - UNSUCCESSFUL (EINVAL)" );
|
||||
status = sem_post(SEM_FAILED);
|
||||
fatal_posix_service_status( status, -1, "sem_post error return status");
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
*** BEGIN OF TEST PSXSEM 1 ***
|
||||
Init: sem_init - SUCCESSFUL
|
||||
Init: sem_destroy - SUCCESSFUL
|
||||
Init: sem_init - UNSUCCESSFUL (EINVAL)
|
||||
Init: sem_init - SUCCESSFUL
|
||||
Init: sem_init - UNSUCCESSFUL (ENOSPC)
|
||||
Init: sem_init - UNSUCCESSFUL (ENOSYS -- pshared not supported)
|
||||
Init: sem_init - SUCCESSFUL
|
||||
Init: sem_destroy - SUCCESSFUL
|
||||
Init: sem_getvalue - SUCCESSFUL
|
||||
Init: sem_getvalue - UNSUCCESSFUL
|
||||
Init: sem_destroy - SUCCESSFUL
|
||||
@@ -17,6 +19,12 @@ Init: sem_trywait - UNSUCCESSFUL (EINVAL)
|
||||
Init: sem_timedwait - SUCCESSFUL
|
||||
Init: sem_timedwait - UNSUCCESSFUL (ETIMEDOUT)
|
||||
Init: sem_timedwait - UNSUCCESSFUL (EINVAL) -- skipping
|
||||
Init: sem_post - SUCCESSFUL
|
||||
Init: sem_clockwait CLOCK_MONOTONIC - SUCCESSFUL
|
||||
Init: sem_clockwait CLOCK_MONOTONIC - UNSUCCESSFUL (ETIMEDOUT)
|
||||
Init: sem_post - SUCCESSFUL
|
||||
Init: sem_clockwait CLOCK_REALTIME - SUCCESSFUL
|
||||
Init: sem_clockwait CLOCK_REALTIME - UNSUCCESSFUL (ETIMEDOUT)
|
||||
Init: sem_post - UNSUCCESSFUL (EINVAL)
|
||||
Init: sem_destroy - SUCCESSFUL
|
||||
Init: sem_open - UNSUCCESSFUL (ENAMETOOLONG)
|
||||
|
||||
Reference in New Issue
Block a user