forked from Imagelibrary/rtems
@@ -210,6 +210,7 @@ include_rtems_HEADERS += include/rtems/termios_printk.h
|
|||||||
include_rtems_HEADERS += include/rtems/termios_printk_cnf.h
|
include_rtems_HEADERS += include/rtems/termios_printk_cnf.h
|
||||||
include_rtems_HEADERS += include/rtems/termiostypes.h
|
include_rtems_HEADERS += include/rtems/termiostypes.h
|
||||||
include_rtems_HEADERS += include/rtems/test.h
|
include_rtems_HEADERS += include/rtems/test.h
|
||||||
|
include_rtems_HEADERS += include/rtems/thread.h
|
||||||
include_rtems_HEADERS += include/rtems/timecounter.h
|
include_rtems_HEADERS += include/rtems/timecounter.h
|
||||||
include_rtems_HEADERS += include/rtems/timespec.h
|
include_rtems_HEADERS += include/rtems/timespec.h
|
||||||
include_rtems_HEADERS += include/rtems/tm27-default.h
|
include_rtems_HEADERS += include/rtems/tm27-default.h
|
||||||
|
|||||||
289
cpukit/include/rtems/thread.h
Normal file
289
cpukit/include/rtems/thread.h
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 embedded brains GmbH. All rights reserved.
|
||||||
|
*
|
||||||
|
* embedded brains GmbH
|
||||||
|
* Dornierstr. 4
|
||||||
|
* 82178 Puchheim
|
||||||
|
* Germany
|
||||||
|
* <rtems@embedded-brains.de>
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTEMS_THREAD_H
|
||||||
|
#define _RTEMS_THREAD_H
|
||||||
|
|
||||||
|
#include <sys/lock.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
/* Temporarily defined, will be shipped with a Newlib update */
|
||||||
|
int _Semaphore_Wait_timed_ticks(struct _Semaphore_Control *, __uint32_t);
|
||||||
|
|
||||||
|
/* Temporarily defined, will be shipped with a Newlib update */
|
||||||
|
int _Semaphore_Try_wait(struct _Semaphore_Control *);
|
||||||
|
|
||||||
|
/* Temporarily defined, will be shipped with a Newlib update */
|
||||||
|
void _Semaphore_Post_binary(struct _Semaphore_Control *);
|
||||||
|
|
||||||
|
typedef struct _Mutex_Control rtems_mutex;
|
||||||
|
|
||||||
|
#define RTEMS_MUTEX_INITIALIZER( name ) _MUTEX_NAMED_INITIALIZER( name )
|
||||||
|
|
||||||
|
static __inline void rtems_mutex_init( rtems_mutex *mutex, const char *name )
|
||||||
|
{
|
||||||
|
_Mutex_Initialize_named( mutex, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline const char *rtems_mutex_get_name( const rtems_mutex *mutex )
|
||||||
|
{
|
||||||
|
return mutex->_Queue._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_mutex_set_name( rtems_mutex *mutex, const char *name )
|
||||||
|
{
|
||||||
|
mutex->_Queue._name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_mutex_lock( rtems_mutex *mutex )
|
||||||
|
{
|
||||||
|
_Mutex_Acquire( mutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_mutex_unlock( rtems_mutex *mutex )
|
||||||
|
{
|
||||||
|
_Mutex_Release( mutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_mutex_destroy( rtems_mutex *mutex )
|
||||||
|
{
|
||||||
|
_Mutex_Destroy( mutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _Mutex_recursive_Control rtems_recursive_mutex;
|
||||||
|
|
||||||
|
#define RTEMS_RECURSIVE_MUTEX_INITIALIZER( name ) \
|
||||||
|
_MUTEX_RECURSIVE_NAMED_INITIALIZER( name )
|
||||||
|
|
||||||
|
static __inline void rtems_recursive_mutex_init(
|
||||||
|
rtems_recursive_mutex *mutex, const char *name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Mutex_recursive_Initialize_named( mutex, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline const char *rtems_recursive_mutex_get_name(
|
||||||
|
const rtems_recursive_mutex *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return mutex->_Mutex._Queue._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_recursive_mutex_set_name(
|
||||||
|
rtems_recursive_mutex *mutex, const char *name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
mutex->_Mutex._Queue._name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_recursive_mutex_lock(
|
||||||
|
rtems_recursive_mutex *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Mutex_recursive_Acquire( mutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_recursive_mutex_unlock(
|
||||||
|
rtems_recursive_mutex *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Mutex_recursive_Release( mutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_recursive_mutex_destroy(
|
||||||
|
rtems_recursive_mutex *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Mutex_recursive_Destroy( mutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _Condition_Control rtems_condition_variable;
|
||||||
|
|
||||||
|
#define RTEMS_CONDITION_VARIABLE_INITIALIZER( name ) \
|
||||||
|
_CONDITION_NAMED_INITIALIZER( name )
|
||||||
|
|
||||||
|
static __inline void rtems_condition_variable_init(
|
||||||
|
rtems_condition_variable *condition_variable,
|
||||||
|
const char *name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Condition_Initialize_named( condition_variable, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline const char *rtems_condition_variable_get_name(
|
||||||
|
const rtems_condition_variable *condition_variable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return condition_variable->_Queue._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_condition_variable_set_name(
|
||||||
|
rtems_condition_variable *condition_variable,
|
||||||
|
const char *name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
condition_variable->_Queue._name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_condition_variable_wait(
|
||||||
|
rtems_condition_variable *condition_variable,
|
||||||
|
rtems_mutex *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Condition_Wait( condition_variable, mutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_condition_variable_signal(
|
||||||
|
rtems_condition_variable *condition_variable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Condition_Broadcast( condition_variable );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_condition_variable_broadcast(
|
||||||
|
rtems_condition_variable *condition_variable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Condition_Broadcast( condition_variable );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_condition_variable_destroy(
|
||||||
|
rtems_condition_variable *condition_variable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Condition_Destroy( condition_variable );
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _Semaphore_Control rtems_counting_semaphore;
|
||||||
|
|
||||||
|
#define RTEMS_COUNTING_SEMAPHORE_INITIALIZER( name, value ) \
|
||||||
|
_SEMAPHORE_NAMED_INITIALIZER( name, value )
|
||||||
|
|
||||||
|
static __inline void rtems_counting_semaphore_init(
|
||||||
|
rtems_counting_semaphore *counting_semaphore,
|
||||||
|
const char *name,
|
||||||
|
unsigned int value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Semaphore_Initialize_named( counting_semaphore, name, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline const char *rtems_counting_semaphore_get_name(
|
||||||
|
const rtems_counting_semaphore *counting_semaphore
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return counting_semaphore->_Queue._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_counting_semaphore_set_name(
|
||||||
|
rtems_counting_semaphore *counting_semaphore,
|
||||||
|
const char *name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
counting_semaphore->_Queue._name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_counting_semaphore_wait(
|
||||||
|
rtems_counting_semaphore *counting_semaphore
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Semaphore_Wait( counting_semaphore );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_counting_semaphore_post(
|
||||||
|
rtems_counting_semaphore *counting_semaphore
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Semaphore_Post( counting_semaphore );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_counting_semaphore_destroy(
|
||||||
|
rtems_counting_semaphore *counting_semaphore
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Semaphore_Destroy( counting_semaphore );
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct _Semaphore_Control Semaphore;
|
||||||
|
} rtems_binary_semaphore;
|
||||||
|
|
||||||
|
#define RTEMS_BINARY_SEMAPHORE_INITIALIZER( name ) \
|
||||||
|
{ _SEMAPHORE_NAMED_INITIALIZER( name, 0 ) }
|
||||||
|
|
||||||
|
static __inline void rtems_binary_semaphore_init(
|
||||||
|
rtems_binary_semaphore *binary_semaphore,
|
||||||
|
const char *name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Semaphore_Initialize_named( &binary_semaphore->Semaphore, name, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline const char *rtems_binary_semaphore_get_name(
|
||||||
|
const rtems_binary_semaphore *binary_semaphore
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return binary_semaphore->Semaphore._Queue._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_binary_semaphore_set_name(
|
||||||
|
rtems_binary_semaphore *binary_semaphore,
|
||||||
|
const char *name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
binary_semaphore->Semaphore._Queue._name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_binary_semaphore_wait(
|
||||||
|
rtems_binary_semaphore *binary_semaphore
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Semaphore_Wait( &binary_semaphore->Semaphore );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline int rtems_binary_semaphore_wait_timed_ticks(
|
||||||
|
rtems_binary_semaphore *binary_semaphore,
|
||||||
|
uint32_t ticks
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _Semaphore_Wait_timed_ticks( &binary_semaphore->Semaphore, ticks );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline int rtems_binary_semaphore_try_wait(
|
||||||
|
rtems_binary_semaphore *binary_semaphore
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _Semaphore_Try_wait( &binary_semaphore->Semaphore );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_binary_semaphore_post(
|
||||||
|
rtems_binary_semaphore *binary_semaphore
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Semaphore_Post_binary( &binary_semaphore->Semaphore );
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void rtems_binary_semaphore_destroy(
|
||||||
|
rtems_binary_semaphore *binary_semaphore
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_Semaphore_Destroy( &binary_semaphore->Semaphore );
|
||||||
|
}
|
||||||
|
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* _RTEMS_THREAD_H */
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2015, 2017 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Dornierstr. 4
|
* Dornierstr. 4
|
||||||
@@ -18,8 +18,9 @@
|
|||||||
|
|
||||||
#include <rtems/score/semaphoreimpl.h>
|
#include <rtems/score/semaphoreimpl.h>
|
||||||
#include <rtems/score/statesimpl.h>
|
#include <rtems/score/statesimpl.h>
|
||||||
|
#include <rtems/score/threadimpl.h>
|
||||||
|
|
||||||
#include <limits.h>
|
#include <errno.h>
|
||||||
|
|
||||||
RTEMS_STATIC_ASSERT(
|
RTEMS_STATIC_ASSERT(
|
||||||
offsetof( Sem_Control, Queue )
|
offsetof( Sem_Control, Queue )
|
||||||
@@ -71,6 +72,66 @@ void _Semaphore_Wait( struct _Semaphore_Control *_sem )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _Semaphore_Wait_timed_ticks( struct _Semaphore_Control *_sem, uint32_t ticks )
|
||||||
|
{
|
||||||
|
Sem_Control *sem;
|
||||||
|
ISR_Level level;
|
||||||
|
Thread_queue_Context queue_context;
|
||||||
|
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 ( __predict_true( count > 0 ) ) {
|
||||||
|
sem->count = count - 1;
|
||||||
|
_Sem_Queue_release( sem, level, &queue_context );
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
_Thread_queue_Context_set_thread_state(
|
||||||
|
&queue_context,
|
||||||
|
STATES_WAITING_FOR_SEMAPHORE
|
||||||
|
);
|
||||||
|
_Thread_queue_Context_set_enqueue_timeout_ticks( &queue_context, ticks );
|
||||||
|
_Thread_queue_Context_set_ISR_level( &queue_context, level );
|
||||||
|
_Thread_queue_Enqueue(
|
||||||
|
&sem->Queue.Queue,
|
||||||
|
SEMAPHORE_TQ_OPERATIONS,
|
||||||
|
executing,
|
||||||
|
&queue_context
|
||||||
|
);
|
||||||
|
return STATUS_GET_POSIX( _Thread_Wait_get_status( executing ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int _Semaphore_Try_wait( struct _Semaphore_Control *_sem )
|
||||||
|
{
|
||||||
|
Sem_Control *sem;
|
||||||
|
ISR_Level level;
|
||||||
|
Thread_queue_Context queue_context;
|
||||||
|
unsigned int count;
|
||||||
|
int eno;
|
||||||
|
|
||||||
|
sem = _Sem_Get( _sem );
|
||||||
|
_Thread_queue_Context_initialize( &queue_context );
|
||||||
|
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||||
|
_Sem_Queue_acquire_critical( sem, &queue_context );
|
||||||
|
|
||||||
|
count = sem->count;
|
||||||
|
if ( __predict_true( count > 0 ) ) {
|
||||||
|
sem->count = count - 1;
|
||||||
|
eno = 0;
|
||||||
|
} else {
|
||||||
|
eno = EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Sem_Queue_release( sem, level, &queue_context );
|
||||||
|
return eno;
|
||||||
|
}
|
||||||
|
|
||||||
void _Semaphore_Post( struct _Semaphore_Control *_sem )
|
void _Semaphore_Post( struct _Semaphore_Control *_sem )
|
||||||
{
|
{
|
||||||
Sem_Control *sem;
|
Sem_Control *sem;
|
||||||
@@ -85,7 +146,6 @@ void _Semaphore_Post( struct _Semaphore_Control *_sem )
|
|||||||
|
|
||||||
heads = sem->Queue.Queue.heads;
|
heads = sem->Queue.Queue.heads;
|
||||||
if ( __predict_true( heads == NULL ) ) {
|
if ( __predict_true( heads == NULL ) ) {
|
||||||
_Assert( sem->count < UINT_MAX );
|
|
||||||
++sem->count;
|
++sem->count;
|
||||||
_Sem_Queue_release( sem, level, &queue_context );
|
_Sem_Queue_release( sem, level, &queue_context );
|
||||||
} else {
|
} else {
|
||||||
@@ -104,3 +164,36 @@ void _Semaphore_Post( struct _Semaphore_Control *_sem )
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _Semaphore_Post_binary( struct _Semaphore_Control *_sem )
|
||||||
|
{
|
||||||
|
Sem_Control *sem;
|
||||||
|
ISR_Level level;
|
||||||
|
Thread_queue_Context queue_context;
|
||||||
|
Thread_queue_Heads *heads;
|
||||||
|
|
||||||
|
sem = _Sem_Get( _sem );
|
||||||
|
_Thread_queue_Context_initialize( &queue_context );
|
||||||
|
_Thread_queue_Context_ISR_disable( &queue_context, level );
|
||||||
|
_Sem_Queue_acquire_critical( sem, &queue_context );
|
||||||
|
|
||||||
|
heads = sem->Queue.Queue.heads;
|
||||||
|
if ( __predict_true( heads == NULL ) ) {
|
||||||
|
sem->count = 1;
|
||||||
|
_Sem_Queue_release( sem, level, &queue_context );
|
||||||
|
} else {
|
||||||
|
const Thread_queue_Operations *operations;
|
||||||
|
Thread_Control *first;
|
||||||
|
|
||||||
|
_Thread_queue_Context_set_ISR_level( &queue_context, level );
|
||||||
|
operations = SEMAPHORE_TQ_OPERATIONS;
|
||||||
|
first = ( *operations->first )( heads );
|
||||||
|
|
||||||
|
_Thread_queue_Extract_critical(
|
||||||
|
&sem->Queue.Queue,
|
||||||
|
operations,
|
||||||
|
first,
|
||||||
|
&queue_context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ _SUBDIRS = \
|
|||||||
spsignal_err01 spport_err01 spmsgq_err01 spmsgq_err02 spsem_err01 \
|
spsignal_err01 spport_err01 spmsgq_err01 spmsgq_err02 spsem_err01 \
|
||||||
spsem_err02 sptask_err01 spevent_err03 sptask_err03 sptask_err02 \
|
spsem_err02 sptask_err01 spevent_err03 sptask_err03 sptask_err02 \
|
||||||
sptask_err04 spclock_err01
|
sptask_err04 spclock_err01
|
||||||
|
_SUBDIRS += spthread01
|
||||||
_SUBDIRS += spconsole01
|
_SUBDIRS += spconsole01
|
||||||
_SUBDIRS += spintrcritical24
|
_SUBDIRS += spintrcritical24
|
||||||
_SUBDIRS += spfatal29
|
_SUBDIRS += spfatal29
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ AM_CONDITIONAL(HAS_SMP,test "$rtems_cv_RTEMS_SMP" = "yes")
|
|||||||
|
|
||||||
# Explicitly list all Makefiles here
|
# Explicitly list all Makefiles here
|
||||||
AC_CONFIG_FILES([Makefile
|
AC_CONFIG_FILES([Makefile
|
||||||
|
spthread01/Makefile
|
||||||
sptls04/Makefile
|
sptls04/Makefile
|
||||||
spconsole01/Makefile
|
spconsole01/Makefile
|
||||||
spintrcritical24/Makefile
|
spintrcritical24/Makefile
|
||||||
|
|||||||
19
testsuites/sptests/spthread01/Makefile.am
Normal file
19
testsuites/sptests/spthread01/Makefile.am
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
rtems_tests_PROGRAMS = spthread01
|
||||||
|
spthread01_SOURCES = init.c
|
||||||
|
|
||||||
|
dist_rtems_tests_DATA = spthread01.scn spthread01.doc
|
||||||
|
|
||||||
|
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||||
|
include $(top_srcdir)/../automake/compile.am
|
||||||
|
include $(top_srcdir)/../automake/leaf.am
|
||||||
|
|
||||||
|
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
|
||||||
|
|
||||||
|
LINK_OBJS = $(spthread01_OBJECTS)
|
||||||
|
LINK_LIBS = $(spthread01_LDLIBS)
|
||||||
|
|
||||||
|
spthread01$(EXEEXT): $(spthread01_OBJECTS) $(spthread01_DEPENDENCIES)
|
||||||
|
@rm -f spthread01$(EXEEXT)
|
||||||
|
$(make-exe)
|
||||||
|
|
||||||
|
include $(top_srcdir)/../automake/local.am
|
||||||
249
testsuites/sptests/spthread01/init.c
Normal file
249
testsuites/sptests/spthread01/init.c
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 embedded brains GmbH. All rights reserved.
|
||||||
|
*
|
||||||
|
* embedded brains GmbH
|
||||||
|
* Dornierstr. 4
|
||||||
|
* 82178 Puchheim
|
||||||
|
* Germany
|
||||||
|
* <rtems@embedded-brains.de>
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <rtems/thread.h>
|
||||||
|
#include <rtems.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <tmacros.h>
|
||||||
|
|
||||||
|
const char rtems_test_name[] = "SPTHREAD 1";
|
||||||
|
|
||||||
|
static void test_mutex(void)
|
||||||
|
{
|
||||||
|
rtems_mutex a = RTEMS_MUTEX_INITIALIZER("a");
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
name = rtems_mutex_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "a") == 0);
|
||||||
|
|
||||||
|
rtems_mutex_set_name(&a, "b");
|
||||||
|
|
||||||
|
name = rtems_mutex_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "b") == 0);
|
||||||
|
|
||||||
|
rtems_mutex_destroy(&a);
|
||||||
|
|
||||||
|
rtems_mutex_init(&a, "c");
|
||||||
|
|
||||||
|
name = rtems_mutex_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "c") == 0);
|
||||||
|
|
||||||
|
rtems_mutex_lock(&a);
|
||||||
|
|
||||||
|
rtems_mutex_unlock(&a);
|
||||||
|
|
||||||
|
rtems_mutex_destroy(&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_recursive_mutex(void)
|
||||||
|
{
|
||||||
|
rtems_recursive_mutex a = RTEMS_RECURSIVE_MUTEX_INITIALIZER("a");
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
name = rtems_recursive_mutex_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "a") == 0);
|
||||||
|
|
||||||
|
rtems_recursive_mutex_set_name(&a, "b");
|
||||||
|
|
||||||
|
name = rtems_recursive_mutex_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "b") == 0);
|
||||||
|
|
||||||
|
rtems_recursive_mutex_destroy(&a);
|
||||||
|
|
||||||
|
rtems_recursive_mutex_init(&a, "c");
|
||||||
|
|
||||||
|
name = rtems_recursive_mutex_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "c") == 0);
|
||||||
|
|
||||||
|
rtems_recursive_mutex_lock(&a);
|
||||||
|
|
||||||
|
rtems_recursive_mutex_lock(&a);
|
||||||
|
|
||||||
|
rtems_recursive_mutex_unlock(&a);
|
||||||
|
|
||||||
|
rtems_recursive_mutex_unlock(&a);
|
||||||
|
|
||||||
|
rtems_recursive_mutex_destroy(&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rtems_mutex mtx;
|
||||||
|
rtems_condition_variable cnd;
|
||||||
|
} signal_context;
|
||||||
|
|
||||||
|
static void signal_task(rtems_task_argument arg)
|
||||||
|
{
|
||||||
|
signal_context *s;
|
||||||
|
|
||||||
|
s = (signal_context *) arg;
|
||||||
|
rtems_mutex_lock(&s->mtx);
|
||||||
|
rtems_condition_variable_signal(&s->cnd);
|
||||||
|
rtems_mutex_unlock(&s->mtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_condition_variable(void)
|
||||||
|
{
|
||||||
|
rtems_condition_variable a = RTEMS_CONDITION_VARIABLE_INITIALIZER("a");
|
||||||
|
signal_context s;
|
||||||
|
const char *name;
|
||||||
|
rtems_status_code sc;
|
||||||
|
rtems_id id;
|
||||||
|
|
||||||
|
name = rtems_condition_variable_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "a") == 0);
|
||||||
|
|
||||||
|
rtems_condition_variable_set_name(&a, "b");
|
||||||
|
|
||||||
|
name = rtems_condition_variable_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "b") == 0);
|
||||||
|
|
||||||
|
rtems_condition_variable_destroy(&a);
|
||||||
|
|
||||||
|
rtems_mutex_init(&s.mtx, "d");
|
||||||
|
rtems_condition_variable_init(&s.cnd, "c");
|
||||||
|
|
||||||
|
name = rtems_condition_variable_get_name(&s.cnd);
|
||||||
|
rtems_test_assert(strcmp(name, "c") == 0);
|
||||||
|
|
||||||
|
rtems_condition_variable_signal(&s.cnd);
|
||||||
|
|
||||||
|
rtems_condition_variable_broadcast(&s.cnd);
|
||||||
|
|
||||||
|
rtems_mutex_lock(&s.mtx);
|
||||||
|
|
||||||
|
sc = rtems_task_create(
|
||||||
|
rtems_build_name('C', 'O', 'N', 'D'),
|
||||||
|
2,
|
||||||
|
RTEMS_MINIMUM_STACK_SIZE,
|
||||||
|
RTEMS_DEFAULT_MODES,
|
||||||
|
RTEMS_DEFAULT_ATTRIBUTES,
|
||||||
|
&id
|
||||||
|
);
|
||||||
|
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
sc = rtems_task_start(id, signal_task, (rtems_task_argument) &s);
|
||||||
|
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
rtems_condition_variable_wait(&s.cnd, &s.mtx);
|
||||||
|
|
||||||
|
sc = rtems_task_delete(id);
|
||||||
|
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
rtems_mutex_unlock(&s.mtx);
|
||||||
|
|
||||||
|
rtems_condition_variable_destroy(&s.cnd);
|
||||||
|
rtems_mutex_destroy(&s.mtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_counting_semaphore(void)
|
||||||
|
{
|
||||||
|
rtems_counting_semaphore a = RTEMS_COUNTING_SEMAPHORE_INITIALIZER("a", 1);
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
name = rtems_counting_semaphore_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "a") == 0);
|
||||||
|
|
||||||
|
rtems_counting_semaphore_set_name(&a, "b");
|
||||||
|
|
||||||
|
name = rtems_counting_semaphore_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "b") == 0);
|
||||||
|
|
||||||
|
rtems_counting_semaphore_destroy(&a);
|
||||||
|
|
||||||
|
rtems_counting_semaphore_init(&a, "c", 0);
|
||||||
|
|
||||||
|
name = rtems_counting_semaphore_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "c") == 0);
|
||||||
|
|
||||||
|
rtems_counting_semaphore_post(&a);
|
||||||
|
|
||||||
|
rtems_counting_semaphore_wait(&a);
|
||||||
|
|
||||||
|
rtems_counting_semaphore_destroy(&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_binary_semaphore(void)
|
||||||
|
{
|
||||||
|
rtems_binary_semaphore a = RTEMS_BINARY_SEMAPHORE_INITIALIZER("a");
|
||||||
|
const char *name;
|
||||||
|
int eno;
|
||||||
|
|
||||||
|
name = rtems_binary_semaphore_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "a") == 0);
|
||||||
|
|
||||||
|
rtems_binary_semaphore_set_name(&a, "b");
|
||||||
|
|
||||||
|
name = rtems_binary_semaphore_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "b") == 0);
|
||||||
|
|
||||||
|
rtems_binary_semaphore_destroy(&a);
|
||||||
|
|
||||||
|
rtems_binary_semaphore_init(&a, "c");
|
||||||
|
|
||||||
|
name = rtems_binary_semaphore_get_name(&a);
|
||||||
|
rtems_test_assert(strcmp(name, "c") == 0);
|
||||||
|
|
||||||
|
eno = rtems_binary_semaphore_try_wait(&a);
|
||||||
|
rtems_test_assert(eno == EAGAIN);
|
||||||
|
|
||||||
|
eno = rtems_binary_semaphore_wait_timed_ticks(&a, 1);
|
||||||
|
rtems_test_assert(eno == ETIMEDOUT);
|
||||||
|
|
||||||
|
rtems_binary_semaphore_post(&a);
|
||||||
|
|
||||||
|
rtems_binary_semaphore_wait(&a);
|
||||||
|
|
||||||
|
rtems_binary_semaphore_post(&a);
|
||||||
|
|
||||||
|
eno = rtems_binary_semaphore_try_wait(&a);
|
||||||
|
rtems_test_assert(eno == 0);
|
||||||
|
|
||||||
|
rtems_binary_semaphore_post(&a);
|
||||||
|
|
||||||
|
eno = rtems_binary_semaphore_wait_timed_ticks(&a, 1);
|
||||||
|
rtems_test_assert(eno == 0);
|
||||||
|
|
||||||
|
rtems_binary_semaphore_destroy(&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Init(rtems_task_argument arg)
|
||||||
|
{
|
||||||
|
TEST_BEGIN();
|
||||||
|
|
||||||
|
test_mutex();
|
||||||
|
test_recursive_mutex();
|
||||||
|
test_condition_variable();
|
||||||
|
test_counting_semaphore();
|
||||||
|
test_binary_semaphore();
|
||||||
|
|
||||||
|
TEST_END();
|
||||||
|
rtems_test_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_TASKS 2
|
||||||
|
|
||||||
|
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||||
|
|
||||||
|
#define CONFIGURE_INIT
|
||||||
|
|
||||||
|
#include <rtems/confdefs.h>
|
||||||
11
testsuites/sptests/spthread01/spthread01.doc
Normal file
11
testsuites/sptests/spthread01/spthread01.doc
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
This file describes the directives and concepts tested by this test set.
|
||||||
|
|
||||||
|
test set name: spthread01
|
||||||
|
|
||||||
|
directives:
|
||||||
|
|
||||||
|
- All macros and functions defined by <rtems/thread.h>.
|
||||||
|
|
||||||
|
concepts:
|
||||||
|
|
||||||
|
- Test <rtems/thread.h> API.
|
||||||
0
testsuites/sptests/spthread01/spthread01.scn
Normal file
0
testsuites/sptests/spthread01/spthread01.scn
Normal file
Reference in New Issue
Block a user