[PATCH 09/10] score: Avoid Giant lock for CORE rwlock
Update #2555. --- cpukit/posix/include/rtems/posix/rwlockimpl.h | 5 +- cpukit/posix/src/prwlockdestroy.c | 72 --- cpukit/posix/src/prwlockinit.c| 22 ++-- cpukit/posix/src/prwlockrdlock.c | 56 +++-- cpukit/posix/src/prwlocktimedrdlock.c | 88 + cpukit/posix/src/prwlocktimedwrlock.c | 87 + cpukit/posix/src/prwlocktryrdlock.c | 61 +++-- cpukit/posix/src/prwlocktrywrlock.c | 60 +++-- cpukit/posix/src/prwlockunlock.c | 41 ++ cpukit/posix/src/prwlockwrlock.c | 56 +++-- cpukit/score/include/rtems/score/corerwlockimpl.h | 24 +++- cpukit/score/src/corerwlockobtainread.c | 98 --- cpukit/score/src/corerwlockobtainwrite.c | 78 ++-- cpukit/score/src/corerwlockrelease.c | 144 +- 14 files changed, 367 insertions(+), 525 deletions(-) diff --git a/cpukit/posix/include/rtems/posix/rwlockimpl.h b/cpukit/posix/include/rtems/posix/rwlockimpl.h index 8c94843..c024ee5 100644 --- a/cpukit/posix/include/rtems/posix/rwlockimpl.h +++ b/cpukit/posix/include/rtems/posix/rwlockimpl.h @@ -23,6 +23,7 @@ #include #include +#include #include #ifdef __cplusplus @@ -86,8 +87,8 @@ RTEMS_INLINE_ROUTINE void _POSIX_RWLock_Free ( } POSIX_RWLock_Control *_POSIX_RWLock_Get( - pthread_rwlock_t *rwlock, - Objects_Locations *location + const pthread_rwlock_t *rwlock, + ISR_lock_Context *lock_context ); #ifdef __cplusplus diff --git a/cpukit/posix/src/prwlockdestroy.c b/cpukit/posix/src/prwlockdestroy.c index a675b90..6f9eec8 100644 --- a/cpukit/posix/src/prwlockdestroy.c +++ b/cpukit/posix/src/prwlockdestroy.c @@ -17,68 +17,42 @@ #include "config.h" #endif -#include -#include - #include -#include -/** - * This directive allows a thread to delete a rwlock specified by - * the rwlock id. The rwlock is freed back to the inactive - * rwlock chain. - * - * @param[in] rwlock is the rwlock id - * - * @return This method returns 0 if there was not an - * error. Otherwise, a status code is returned indicating the - * source of the error. - */ int pthread_rwlock_destroy( pthread_rwlock_t *rwlock ) { - POSIX_RWLock_Control *the_rwlock = NULL; - Objects_Locations location; + POSIX_RWLock_Control *the_rwlock; + ISR_lock_Context lock_context; _Objects_Allocator_lock(); - the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); - switch ( location ) { + the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context ); -case OBJECTS_LOCAL: - /* - * If there is at least one thread waiting, then do not delete it. - */ - if ( -_Thread_queue_First( - &the_rwlock->RWLock.Wait_queue, - CORE_RWLOCK_TQ_OPERATIONS -) != NULL - ) { -_Objects_Put( &the_rwlock->Object ); -_Objects_Allocator_unlock(); -return EBUSY; - } - - /* - * POSIX doesn't require behavior when it is locked. - */ + if ( the_rwlock == NULL ) { +_Objects_Allocator_unlock(); +return EINVAL; + } - _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object ); - _Objects_Put( &the_rwlock->Object ); - _POSIX_RWLock_Free( the_rwlock ); - _Objects_Allocator_unlock(); + _CORE_RWLock_Acquire_critical( &the_rwlock->RWLock, &lock_context ); - return 0; + /* + * If there is at least one thread waiting, then do not delete it. + */ -#if defined(RTEMS_MULTIPROCESSING) -case OBJECTS_REMOTE: -#endif -case OBJECTS_ERROR: - break; + if ( !_Thread_queue_Is_empty( &the_rwlock->RWLock.Wait_queue.Queue ) ) { +_CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context ); +_Objects_Allocator_unlock(); +return EBUSY; } - _Objects_Allocator_unlock(); + /* + * POSIX doesn't require behavior when it is locked. + */ - return EINVAL; + _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object ); + _CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context ); + _POSIX_RWLock_Free( the_rwlock ); + _Objects_Allocator_unlock(); + return 0; } diff --git a/cpukit/posix/src/prwlockinit.c b/cpukit/posix/src/prwlockinit.c index afb7056..ea6abe9 100644 --- a/cpukit/posix/src/prwlockinit.c +++ b/cpukit/posix/src/prwlockinit.c @@ -20,20 +20,14 @@ #include "config.h" #endif -#include -#include - #include #include static bool _POSIX_RWLock_Check_id_and_auto_init( - pthread_mutex_t *rwlock, - Objects_Locations *location + pthread_mutex_t *rwlock ) { if ( rwlock == NULL ) { -*location = OBJECTS_ERROR; - return false; } @@ -51,8 +45,6 @@ static bool _POSIX_RWLock_Check_id_and_auto_init( _Once_Unlock(); if ( eno != 0 ) { - *location = OBJECTS_ERROR; - return false; } } @@ -61,18 +53,18 @@ static bool _POSIX_RWLock_Check_
[PATCH 03/10] posix: Use _Objects_Get_local() for semaphores
This simplifies the code since the object location is no longer used. Remove superfluous header includes. --- cpukit/posix/include/rtems/posix/semaphoreimpl.h | 11 ++--- cpukit/posix/src/semaphorewaitsupp.c | 60 +--- cpukit/posix/src/semclose.c | 40 ++-- cpukit/posix/src/semdestroy.c| 51 cpukit/posix/src/semgetvalue.c | 45 +- cpukit/posix/src/sempost.c | 44 + 6 files changed, 83 insertions(+), 168 deletions(-) diff --git a/cpukit/posix/include/rtems/posix/semaphoreimpl.h b/cpukit/posix/include/rtems/posix/semaphoreimpl.h index d726761..6ec8480 100644 --- a/cpukit/posix/include/rtems/posix/semaphoreimpl.h +++ b/cpukit/posix/include/rtems/posix/semaphoreimpl.h @@ -60,17 +60,14 @@ RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free ( _Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object ); } -RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control * -_POSIX_Semaphore_Get_interrupt_disable( - sem_t *id, - Objects_Locations *location, +RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get( + const sem_t *id, ISR_lock_Context *lock_context ) { - return (POSIX_Semaphore_Control *) _Objects_Get_isr_disable( + return (POSIX_Semaphore_Control *) _Objects_Get_local( +(Objects_Id) *id, &_POSIX_Semaphore_Information, -(Objects_Id)*id, -location, lock_context ); } diff --git a/cpukit/posix/src/semaphorewaitsupp.c b/cpukit/posix/src/semaphorewaitsupp.c index cf8fe63..84ebe3d 100644 --- a/cpukit/posix/src/semaphorewaitsupp.c +++ b/cpukit/posix/src/semaphorewaitsupp.c @@ -18,18 +18,10 @@ #include "config.h" #endif -#include - -#include -#include -#include #include -#include -#include -#include #include -#include +#include THREAD_WAIT_QUEUE_OBJECT_ASSERT( POSIX_Semaphore_Control, @@ -43,43 +35,33 @@ int _POSIX_Semaphore_Wait_support( ) { POSIX_Semaphore_Control *the_semaphore; - Objects_Locationslocation; Thread_Control *executing; ISR_lock_Context lock_context; - the_semaphore = _POSIX_Semaphore_Get_interrupt_disable( -sem, -&location, -&lock_context - ); - switch ( location ) { + the_semaphore = _POSIX_Semaphore_Get( sem, &lock_context ); -case OBJECTS_LOCAL: - executing = _Thread_Executing; - _CORE_semaphore_Seize( -&the_semaphore->Semaphore, -executing, -the_semaphore->Object.id, -blocking, -timeout, -&lock_context - ); + if ( the_semaphore == NULL ) { +rtems_set_errno_and_return_minus_one( EINVAL ); + } - if ( !executing->Wait.return_code ) -return 0; + executing = _Thread_Executing; - rtems_set_errno_and_return_minus_one( -_POSIX_Semaphore_Translate_core_semaphore_return_code( - executing->Wait.return_code -) - ); + _CORE_semaphore_Seize( +&the_semaphore->Semaphore, +executing, +the_semaphore->Object.id, +blocking, +timeout, +&lock_context + ); -#if defined(RTEMS_MULTIPROCESSING) -case OBJECTS_REMOTE: -#endif -case OBJECTS_ERROR: - break; + if ( executing->Wait.return_code == CORE_SEMAPHORE_STATUS_SUCCESSFUL ) { +return 0; } - rtems_set_errno_and_return_minus_one( EINVAL ); + rtems_set_errno_and_return_minus_one( +_POSIX_Semaphore_Translate_core_semaphore_return_code( + executing->Wait.return_code +) + ); } diff --git a/cpukit/posix/src/semclose.c b/cpukit/posix/src/semclose.c index 1468c7f..3f18ff1 100644 --- a/cpukit/posix/src/semclose.c +++ b/cpukit/posix/src/semclose.c @@ -26,36 +26,24 @@ int sem_close( sem_t *sem ) { - POSIX_Semaphore_Control *the_semaphore; - Objects_Locations location; - ISR_lock_Context lock_context; + POSIX_Semaphore_Control *the_semaphore; + ISR_lock_Context lock_context; _Objects_Allocator_lock(); - the_semaphore = _POSIX_Semaphore_Get_interrupt_disable( -sem, -&location, + the_semaphore = _POSIX_Semaphore_Get( sem, &lock_context ); + + if ( the_semaphore == NULL ) { +_Objects_Allocator_unlock(); +rtems_set_errno_and_return_minus_one( EINVAL ); + } + + _CORE_semaphore_Acquire_critical( +&the_semaphore->Semaphore, &lock_context ); - switch ( location ) { - -case OBJECTS_LOCAL: - _CORE_semaphore_Acquire_critical( -&the_semaphore->Semaphore, -&lock_context - ); - the_semaphore->open_count -= 1; - _POSIX_Semaphore_Delete( the_semaphore, &lock_context ); - _Objects_Allocator_unlock(); - return 0; - -#if defined(RTEMS_MULTIPROCESSING) -case OBJECTS_REMOTE: -#endif -case OBJECTS_ERROR: - break; - } + the_semaphore->open_count -= 1; + _POSIX_Semaphore_Delete( the_semaphore, &lock_context ); _Objects_Allo
[PATCH 06/10] score: Use _Thread_queue_Flush_critical() for cond
--- cpukit/score/src/condition.c | 108 --- 1 file changed, 41 insertions(+), 67 deletions(-) diff --git a/cpukit/score/src/condition.c b/cpukit/score/src/condition.c index da3d133..ba255fc 100644 --- a/cpukit/score/src/condition.c +++ b/cpukit/score/src/condition.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 embedded brains GmbH. All rights reserved. + * Copyright (c) 2015, 2016 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -219,83 +219,57 @@ int _Condition_Wait_recursive_timed( return eno; } -static int _Condition_Wake( struct _Condition_Control *_condition, int count ) +typedef struct { + ISR_lock_Context Base; + int count; +} Condition_Lock_context; + +static Thread_Control *_Condition_Flush_filter( + Thread_Control *the_thread, + Thread_queue_Queue *queue, + ISR_lock_Context *lock_context +) { - Condition_Control *condition; - ISR_lock_Contextlock_context; - Thread_queue_Heads *heads; - Chain_Control unblock; - Chain_Node *node; - Chain_Node *tail; - int woken; - - condition = _Condition_Get( _condition ); - _ISR_lock_ISR_disable( &lock_context ); - _Condition_Queue_acquire_critical( condition, &lock_context ); + Condition_Lock_context *condition_lock_context; - /* - * In common uses cases of condition variables there are normally no threads - * on the queue, so check this condition early. - */ - heads = condition->Queue.Queue.heads; - if ( __predict_true( heads == NULL ) ) { -_Condition_Queue_release( condition, &lock_context ); - -return 0; - } + condition_lock_context = (Condition_Lock_context *) lock_context; - woken = 0; - _Chain_Initialize_empty( &unblock ); - while ( count > 0 && heads != NULL ) { -const Thread_queue_Operations *operations; -Thread_Control*first; -bool do_unblock; - -operations = CONDITION_TQ_OPERATIONS; -first = ( *operations->first )( heads ); - -do_unblock = _Thread_queue_Extract_locked( - &condition->Queue.Queue, - operations, - first, - NULL, - 0 -); -if (do_unblock) { - _Chain_Append_unprotected( &unblock, &first->Wait.Node.Chain ); -} - -++woken; ---count; -heads = condition->Queue.Queue.heads; + if ( condition_lock_context->count <= 0 ) { +return NULL; } - node = _Chain_First( &unblock ); - tail = _Chain_Tail( &unblock ); - if ( node != tail ) { -Per_CPU_Control *cpu_self; + --condition_lock_context->count; -cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); -_Condition_Queue_release( condition, &lock_context ); - -do { - Thread_Control *thread; - Chain_Node *next; + return the_thread; +} - next = _Chain_Next( node ); - thread = THREAD_CHAIN_NODE_TO_THREAD( node ); - _Thread_Timer_remove( thread ); - _Thread_Unblock( thread ); +static void _Condition_Wake( struct _Condition_Control *_condition, int count ) +{ + Condition_Control *condition; + Condition_Lock_context lock_context; - node = next; -} while ( node != tail ); + condition = _Condition_Get( _condition ); + _ISR_lock_ISR_disable( &lock_context.Base ); + _Condition_Queue_acquire_critical( condition, &lock_context.Base ); -_Thread_Dispatch_enable( cpu_self ); - } else { -_Condition_Queue_release( condition, &lock_context ); + /* + * In common uses cases of condition variables there are normally no threads + * on the queue, so check this condition early. + */ + if ( __predict_true( _Thread_queue_Is_empty( &condition->Queue.Queue ) ) ) { +_Condition_Queue_release( condition, &lock_context.Base ); +return; } - return woken; + lock_context.count = count; + _Thread_queue_Flush_critical( +&condition->Queue.Queue, +CONDITION_TQ_OPERATIONS, +_Condition_Flush_filter, +NULL, +0, +&lock_context.Base + ); } void _Condition_Signal( struct _Condition_Control *_condition ) -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 04/10] score: Add _Thread_queue_Is_empty()
--- cpukit/score/include/rtems/score/threadqimpl.h | 7 +++ testsuites/sptests/spthreadq01/init.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index 7b1c896..68ce109 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -547,6 +547,13 @@ void _Thread_queue_Extract_with_proxy( Thread_Control *the_thread ); +RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_empty( + const Thread_queue_Queue *queue +) +{ + return queue->heads == NULL; +} + /** * @brief Returns the first thread on the thread queue if it exists, otherwise * @c NULL. diff --git a/testsuites/sptests/spthreadq01/init.c b/testsuites/sptests/spthreadq01/init.c index c1812f6..fb2be64 100644 --- a/testsuites/sptests/spthreadq01/init.c +++ b/testsuites/sptests/spthreadq01/init.c @@ -375,7 +375,7 @@ static rtems_task Init( test_classic_obj(ctx); test_posix_obj(ctx); - rtems_test_assert( queue.Queue.heads == NULL ); + rtems_test_assert( _Thread_queue_Is_empty( &queue.Queue ) ); TEST_END(); rtems_test_exit(0); -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 07/10] score: Add _Thread_queue_Flush_default_filter()
--- cpukit/score/include/rtems/score/threadqimpl.h | 15 +++ cpukit/score/src/threadqflush.c| 11 +++ 2 files changed, 26 insertions(+) diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index 68ce109..a31b4c3 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -623,6 +623,21 @@ typedef Thread_Control *( *Thread_queue_Flush_filter )( ISR_lock_Context *lock_context ); +/** + * @brief Default thread queue flush filter function. + * + * @param the_thread The thread to extract. + * @param queue Unused. + * @param lock_context Unused. + * + * @retval the_thread Extract this thread. + */ +Thread_Control *_Thread_queue_Flush_default_filter( + Thread_Control *the_thread, + Thread_queue_Queue *queue, + ISR_lock_Context *lock_context +); + size_t _Thread_queue_Do_flush_critical( Thread_queue_Queue*queue, const Thread_queue_Operations *operations, diff --git a/cpukit/score/src/threadqflush.c b/cpukit/score/src/threadqflush.c index 0ce639e..9e54e1f 100644 --- a/cpukit/score/src/threadqflush.c +++ b/cpukit/score/src/threadqflush.c @@ -20,6 +20,17 @@ #include +Thread_Control *_Thread_queue_Flush_default_filter( + Thread_Control *the_thread, + Thread_queue_Queue *queue, + ISR_lock_Context *lock_context +) +{ + (void) queue; + (void) lock_context; + return the_thread; +} + size_t _Thread_queue_Do_flush_critical( Thread_queue_Queue*queue, const Thread_queue_Operations *operations, -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 02/10] score: Avoid Giant lock for CORE mtx/sem
Avoid Giant lock for CORE mutex and semaphore flush and delete operations. Update #2555. --- cpukit/posix/include/rtems/posix/semaphoreimpl.h | 26 +--- cpukit/posix/src/semaphoredeletesupp.c | 22 +++ cpukit/posix/src/semclose.c | 22 +++ cpukit/posix/src/semdestroy.c| 27 cpukit/posix/src/semunlink.c | 9 ++- cpukit/rtems/src/semdelete.c | 83 cpukit/rtems/src/semflush.c | 25 +-- cpukit/score/include/rtems/score/coremuteximpl.h | 26 +++- cpukit/score/include/rtems/score/coresemimpl.h | 46 +++-- cpukit/score/include/rtems/score/mrspimpl.h | 41 +--- 10 files changed, 186 insertions(+), 141 deletions(-) diff --git a/cpukit/posix/include/rtems/posix/semaphoreimpl.h b/cpukit/posix/include/rtems/posix/semaphoreimpl.h index 41bfdad..d726761 100644 --- a/cpukit/posix/include/rtems/posix/semaphoreimpl.h +++ b/cpukit/posix/include/rtems/posix/semaphoreimpl.h @@ -22,8 +22,7 @@ #include #include #include - -#include +#include #ifdef __cplusplus extern "C" { @@ -61,26 +60,6 @@ RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free ( _Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object ); } -/** - * @brief POSIX Semaphore Get - * - * This function maps semaphore IDs to semaphore control blocks. - * If ID corresponds to a local semaphore, then it returns - * the_semaphore control pointer which maps to ID and location - * is set to OBJECTS_LOCAL. if the semaphore ID is global and - * resides on a remote node, then location is set to OBJECTS_REMOTE, - * and the_semaphore is undefined. Otherwise, location is set - * to OBJECTS_ERROR and the_semaphore is undefined. - */ -RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get ( - sem_t *id, - Objects_Locations *location -) -{ - return (POSIX_Semaphore_Control *) -_Objects_Get( &_POSIX_Semaphore_Information, (Objects_Id)*id, location ); -} - RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control * _POSIX_Semaphore_Get_interrupt_disable( sem_t *id, @@ -116,7 +95,8 @@ int _POSIX_Semaphore_Create_support( * This routine supports the sem_close and sem_unlink routines. */ void _POSIX_Semaphore_Delete( - POSIX_Semaphore_Control *the_semaphore + POSIX_Semaphore_Control *the_semaphore, + ISR_lock_Context*lock_context ); /** diff --git a/cpukit/posix/src/semaphoredeletesupp.c b/cpukit/posix/src/semaphoredeletesupp.c index 43946746..7c23bb8 100644 --- a/cpukit/posix/src/semaphoredeletesupp.c +++ b/cpukit/posix/src/semaphoredeletesupp.c @@ -18,25 +18,23 @@ #include "config.h" #endif -#include - -#include -#include -#include -#include -#include - -#include #include -#include void _POSIX_Semaphore_Delete( - POSIX_Semaphore_Control *the_semaphore + POSIX_Semaphore_Control *the_semaphore, + ISR_lock_Context*lock_context ) { if ( !the_semaphore->linked && !the_semaphore->open_count ) { _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object ); -_CORE_semaphore_Destroy( &the_semaphore->Semaphore, NULL, 0 ); +_CORE_semaphore_Destroy( + &the_semaphore->Semaphore, + NULL, + 0, + lock_context +); _POSIX_Semaphore_Free( the_semaphore ); + } else { +_CORE_semaphore_Release( &the_semaphore->Semaphore, lock_context ); } } diff --git a/cpukit/posix/src/semclose.c b/cpukit/posix/src/semclose.c index f134dc4..1468c7f 100644 --- a/cpukit/posix/src/semclose.c +++ b/cpukit/posix/src/semclose.c @@ -18,17 +18,9 @@ #include "config.h" #endif -#include - -#include -#include -#include #include -#include -#include #include -#include int sem_close( sem_t *sem @@ -36,15 +28,23 @@ int sem_close( { POSIX_Semaphore_Control *the_semaphore; Objects_Locations location; + ISR_lock_Context lock_context; _Objects_Allocator_lock(); - the_semaphore = _POSIX_Semaphore_Get( sem, &location ); + the_semaphore = _POSIX_Semaphore_Get_interrupt_disable( +sem, +&location, +&lock_context + ); switch ( location ) { case OBJECTS_LOCAL: + _CORE_semaphore_Acquire_critical( +&the_semaphore->Semaphore, +&lock_context + ); the_semaphore->open_count -= 1; - _POSIX_Semaphore_Delete( the_semaphore ); - _Objects_Put( &the_semaphore->Object ); + _POSIX_Semaphore_Delete( the_semaphore, &lock_context ); _Objects_Allocator_unlock(); return 0; diff --git a/cpukit/posix/src/semdestroy.c b/cpukit/posix/src/semdestroy.c index 896dece..7511699 100644 --- a/cpukit/posix/src/semdestroy.c +++ b/cpukit/posix/src/semdestroy.c @@ -18,17 +18,9 @@ #include "config.h" #endif -#include - -#include -#include -#include #include -#include -#include #include -#include int sem_destroy( sem_t *sem
[PATCH 08/10] score: Avoid Giant lock for barriers
Use _Thread_queue_Flush_critical() to atomically release the barrier. Update #2555. --- cpukit/posix/include/rtems/posix/barrierimpl.h | 24 ++--- cpukit/posix/src/pbarrierdestroy.c | 45 -- cpukit/posix/src/pbarrierwait.c| 50 +-- cpukit/rtems/include/rtems/rtems/barrierimpl.h | 19 +--- cpukit/rtems/src/barrierdelete.c | 31 +++ cpukit/rtems/src/barrierrelease.c | 50 --- cpukit/rtems/src/barrierwait.c | 51 +-- cpukit/score/include/rtems/score/corebarrierimpl.h | 100 ++--- cpukit/score/src/corebarrierrelease.c | 36 +++- cpukit/score/src/corebarrierwait.c | 53 +-- 10 files changed, 203 insertions(+), 256 deletions(-) diff --git a/cpukit/posix/include/rtems/posix/barrierimpl.h b/cpukit/posix/include/rtems/posix/barrierimpl.h index 646b734..16ccdc5 100644 --- a/cpukit/posix/include/rtems/posix/barrierimpl.h +++ b/cpukit/posix/include/rtems/posix/barrierimpl.h @@ -23,6 +23,7 @@ #include #include +#include #include #ifdef __cplusplus @@ -76,26 +77,15 @@ RTEMS_INLINE_ROUTINE void _POSIX_Barrier_Free ( _Objects_Free( &_POSIX_Barrier_Information, &the_barrier->Object ); } -/** - * @brief Get a barrier control block. - * - * This function maps barrier IDs to barrier control blocks. - * If ID corresponds to a local barrier, then it returns - * the_barrier control pointer which maps to ID and location - * is set to OBJECTS_LOCAL. if the barrier ID is global and - * resides on a remote node, then location is set to OBJECTS_REMOTE, - * and the_barrier is undefined. Otherwise, location is set - * to OBJECTS_ERROR and the_barrier is undefined. - */ RTEMS_INLINE_ROUTINE POSIX_Barrier_Control *_POSIX_Barrier_Get ( - pthread_barrier_t *barrier, - Objects_Locations *location + const pthread_barrier_t *barrier, + ISR_lock_Context*lock_context ) { - return (POSIX_Barrier_Control *) _Objects_Get( - &_POSIX_Barrier_Information, - (Objects_Id) *barrier, - location + return (POSIX_Barrier_Control *) _Objects_Get_local( +(Objects_Id) *barrier, +&_POSIX_Barrier_Information, +lock_context ); } diff --git a/cpukit/posix/src/pbarrierdestroy.c b/cpukit/posix/src/pbarrierdestroy.c index 4b9a0fd..709644b 100644 --- a/cpukit/posix/src/pbarrierdestroy.c +++ b/cpukit/posix/src/pbarrierdestroy.c @@ -18,10 +18,6 @@ #include "config.h" #endif -#include -#include - -#include #include /** @@ -39,37 +35,32 @@ int pthread_barrier_destroy( pthread_barrier_t *barrier ) { - POSIX_Barrier_Control *the_barrier = NULL; - Objects_Locations location; + POSIX_Barrier_Control *the_barrier; + ISR_lock_Context lock_context; - if ( !barrier ) + if ( barrier == NULL ) { return EINVAL; + } _Objects_Allocator_lock(); - the_barrier = _POSIX_Barrier_Get( barrier, &location ); - switch ( location ) { + the_barrier = _POSIX_Barrier_Get( barrier, &lock_context ); -case OBJECTS_LOCAL: - if ( the_barrier->Barrier.number_of_waiting_threads != 0 ) { -_Objects_Put( &the_barrier->Object ); -return EBUSY; - } - - _Objects_Close( &_POSIX_Barrier_Information, &the_barrier->Object ); - _Objects_Put( &the_barrier->Object ); + if ( the_barrier == NULL ) { +_Objects_Allocator_unlock(); +return EINVAL; + } - _POSIX_Barrier_Free( the_barrier ); - _Objects_Allocator_unlock(); - return 0; + _CORE_barrier_Acquire_critical( &the_barrier->Barrier, &lock_context ); -#if defined(RTEMS_MULTIPROCESSING) -case OBJECTS_REMOTE: -#endif -case OBJECTS_ERROR: - break; + if ( the_barrier->Barrier.number_of_waiting_threads != 0 ) { +_CORE_barrier_Release( &the_barrier->Barrier, &lock_context ); +_Objects_Allocator_unlock(); +return EBUSY; } + _Objects_Close( &_POSIX_Barrier_Information, &the_barrier->Object ); + _CORE_barrier_Release( &the_barrier->Barrier, &lock_context ); + _POSIX_Barrier_Free( the_barrier ); _Objects_Allocator_unlock(); - - return EINVAL; + return 0; } diff --git a/cpukit/posix/src/pbarrierwait.c b/cpukit/posix/src/pbarrierwait.c index 86bfba7..9200dc0 100644 --- a/cpukit/posix/src/pbarrierwait.c +++ b/cpukit/posix/src/pbarrierwait.c @@ -18,9 +18,6 @@ #include "config.h" #endif -#include -#include - #include #include @@ -40,36 +37,31 @@ int pthread_barrier_wait( pthread_barrier_t *barrier ) { - POSIX_Barrier_Control *the_barrier = NULL; - Objects_Locationslocation; - Thread_Control *executing; + POSIX_Barrier_Control *the_barrier; + ISR_lock_Context lock_context; + Thread_Control*executing; - if ( !barrier ) + if ( barrier == NULL ) { return EINVAL; + } - the_barrier = _POSIX_Barrier_Get( barrier, &location ); - switch ( location ) { - -case OBJECTS_LOCAL: - executing
[PATCH 10/10] rtems: Avoid Giant lock for dual ported memory
There is no need for an ISR lock since the Dual_ported_memory_Control is immutable after initialization. ISR disable is enough for deletion safety on uni-processor configurations. Update #2555. --- cpukit/rtems/include/rtems/rtems/dpmemimpl.h | 18 +++ cpukit/rtems/src/dpmemdelete.c | 33 ++- cpukit/rtems/src/dpmemexternal2internal.c| 47 --- cpukit/rtems/src/dpmeminternal2external.c| 48 4 files changed, 54 insertions(+), 92 deletions(-) diff --git a/cpukit/rtems/include/rtems/rtems/dpmemimpl.h b/cpukit/rtems/include/rtems/rtems/dpmemimpl.h index 213856d..1e96722 100644 --- a/cpukit/rtems/include/rtems/rtems/dpmemimpl.h +++ b/cpukit/rtems/include/rtems/rtems/dpmemimpl.h @@ -66,23 +66,13 @@ RTEMS_INLINE_ROUTINE void _Dual_ported_memory_Free ( _Objects_Free( &_Dual_ported_memory_Information, &the_port->Object ); } -/** - * @brief Maps port IDs to port control blocks. - * - * This function maps port IDs to port control blocks. If ID - * corresponds to a local port, then it returns the_port control - * pointer which maps to ID and location is set to OBJECTS_LOCAL. - * Global ports are not supported, thus if ID does not map to a - * local port, location is set to OBJECTS_ERROR and the_port is - * undefined. - */ -RTEMS_INLINE_ROUTINE Dual_ported_memory_Control *_Dual_ported_memory_Get ( - Objects_Id id, - Objects_Locations *location +RTEMS_INLINE_ROUTINE Dual_ported_memory_Control *_Dual_ported_memory_Get( + Objects_Idid, + ISR_lock_Context *lock_context ) { return (Dual_ported_memory_Control *) - _Objects_Get( &_Dual_ported_memory_Information, id, location ); +_Objects_Get_local( id, &_Dual_ported_memory_Information, lock_context ); } /**@}*/ diff --git a/cpukit/rtems/src/dpmemdelete.c b/cpukit/rtems/src/dpmemdelete.c index 6f11a53..f303629 100644 --- a/cpukit/rtems/src/dpmemdelete.c +++ b/cpukit/rtems/src/dpmemdelete.c @@ -18,39 +18,26 @@ #include "config.h" #endif -#include -#include -#include -#include #include -#include rtems_status_code rtems_port_delete( rtems_id id ) { - Dual_ported_memory_Control *the_port; - Objects_Locationslocation; + Dual_ported_memory_Control *the_port; + ISR_lock_Contextlock_context; _Objects_Allocator_lock(); - the_port = _Dual_ported_memory_Get( id, &location ); - switch ( location ) { + the_port = _Dual_ported_memory_Get( id, &lock_context ); -case OBJECTS_LOCAL: - _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object ); - _Objects_Put( &the_port->Object ); - _Dual_ported_memory_Free( the_port ); - _Objects_Allocator_unlock(); - return RTEMS_SUCCESSFUL; - -#if defined(RTEMS_MULTIPROCESSING) -case OBJECTS_REMOTE:/* this error cannot be returned */ -#endif -case OBJECTS_ERROR: - break; + if ( the_port == NULL ) { +_Objects_Allocator_unlock(); +return RTEMS_INVALID_ID; } + _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object ); + _ISR_lock_ISR_enable( &lock_context ); + _Dual_ported_memory_Free( the_port ); _Objects_Allocator_unlock(); - - return RTEMS_INVALID_ID; + return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/dpmemexternal2internal.c b/cpukit/rtems/src/dpmemexternal2internal.c index 237d5c4..0456010 100644 --- a/cpukit/rtems/src/dpmemexternal2internal.c +++ b/cpukit/rtems/src/dpmemexternal2internal.c @@ -18,12 +18,8 @@ #include "config.h" #endif -#include -#include -#include -#include #include -#include +#include rtems_status_code rtems_port_external_to_internal( rtems_id id, @@ -31,31 +27,28 @@ rtems_status_code rtems_port_external_to_internal( void **internal ) { - Dual_ported_memory_Control *the_port; - Objects_Locationslocation; - uint32_t ending; + Dual_ported_memory_Control *the_port; + ISR_lock_Contextlock_context; + uint32_tending; - if ( !internal ) + if ( internal == NULL ) { return RTEMS_INVALID_ADDRESS; + } - the_port = _Dual_ported_memory_Get( id, &location ); - switch ( location ) { -case OBJECTS_LOCAL: - ending = _Addresses_Subtract( external, the_port->external_base ); - if ( ending > the_port->length ) -*internal = external; - else -*internal = _Addresses_Add_offset( the_port->internal_base, - ending ); - _Objects_Put( &the_port->Object ); - return RTEMS_SUCCESSFUL; - -#if defined(RTEMS_MULTIPROCESSING) -case OBJECTS_REMOTE:/* this error cannot be returned */ -#endif -case OBJECTS_ERROR: - break; + the_port = _Dual_ported_memory_Get( id, &lock_context ); + + if ( the_port == NULL ) { +return RTEMS_INVALID_ID; + } + + ending = _Addresses_Subtract( external, the_port->externa
[PATCH 05/10] score: Use _Thread_queue_Flush_critical for futex
--- cpukit/score/src/futex.c | 98 ++-- 1 file changed, 28 insertions(+), 70 deletions(-) diff --git a/cpukit/score/src/futex.c b/cpukit/score/src/futex.c index 73d48fd..59a625c 100644 --- a/cpukit/score/src/futex.c +++ b/cpukit/score/src/futex.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 embedded brains GmbH. All rights reserved. + * Copyright (c) 2015, 2016 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -103,99 +103,57 @@ int _Futex_Wait( struct _Futex_Control *_futex, int *uaddr, int val ) return eno; } -/* - * Use a noinline function to force the compiler to set up and tear down the - * large stack frame only in the slow case. - */ -static __attribute__((noinline)) int _Futex_Wake_slow( - Futex_Control *futex, - int count, - Thread_queue_Heads *heads, +typedef struct { + ISR_lock_Context Base; + int count; +} Futex_Lock_context; + +static Thread_Control *_Futex_Flush_filter( + Thread_Control *the_thread, + Thread_queue_Queue *queue, ISR_lock_Context *lock_context ) { - Chain_Control unblock; - Chain_Node*node; - Chain_Node*tail; - intwoken; - - woken = 0; - _Chain_Initialize_empty( &unblock ); - - while ( count > 0 && heads != NULL ) { -const Thread_queue_Operations *operations; -Thread_Control*first; -bool do_unblock; + Futex_Lock_context *futex_lock_context; -operations = FUTEX_TQ_OPERATIONS; -first = ( *operations->first )( heads ); + futex_lock_context = (Futex_Lock_context *) lock_context; -do_unblock = _Thread_queue_Extract_locked( - &futex->Queue.Queue, - operations, - first, - NULL, - 0 -); -if (do_unblock) { - _Chain_Append_unprotected( &unblock, &first->Wait.Node.Chain ); -} - -++woken; ---count; -heads = futex->Queue.Queue.heads; + if ( futex_lock_context->count <= 0 ) { +return NULL; } - node = _Chain_First( &unblock ); - tail = _Chain_Tail( &unblock ); - - if ( node != tail ) { -Per_CPU_Control *cpu_self; - -cpu_self = _Thread_Dispatch_disable_critical( lock_context ); -_Futex_Queue_release( futex, lock_context ); + --futex_lock_context->count; -do { - Thread_Control *thread; - Chain_Node *next; - - next = _Chain_Next( node ); - thread = THREAD_CHAIN_NODE_TO_THREAD( node ); - _Thread_Unblock( thread ); - - node = next; -} while ( node != tail ); - -_Thread_Dispatch_enable( cpu_self ); - } else { -_Futex_Queue_release( futex, lock_context ); - } - - return woken; + return the_thread; } int _Futex_Wake( struct _Futex_Control *_futex, int count ) { Futex_Control *futex; - ISR_lock_Contextlock_context; - Thread_queue_Heads *heads; + Futex_Lock_context lock_context; futex = _Futex_Get( _futex ); - _Futex_Queue_acquire( futex, &lock_context ); + _Futex_Queue_acquire( futex, &lock_context.Base ); /* * For some synchronization objects like barriers the _Futex_Wake() must be * called in the fast path. Normally there are no threads on the queue, so * check this condition early. */ - heads = futex->Queue.Queue.heads; - if ( __predict_true( heads == NULL ) ) { -_Futex_Queue_release( futex, &lock_context ); - + if ( __predict_true( _Thread_queue_Is_empty( &futex->Queue.Queue ) ) ) { +_Futex_Queue_release( futex, &lock_context.Base ); return 0; } - return _Futex_Wake_slow( futex, count, heads, &lock_context ); + lock_context.count = count; + return (int) _Thread_queue_Flush_critical( +&futex->Queue.Queue, +FUTEX_TQ_OPERATIONS, +_Futex_Flush_filter, +NULL, +0, +&lock_context.Base + ); } #endif /* HAVE_STRUCT__THREAD_QUEUE_QUEUE */ -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 01/10] posix: Avoid Giant lock in sem_getvalue()
Update #2555. --- cpukit/posix/src/semgetvalue.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cpukit/posix/src/semgetvalue.c b/cpukit/posix/src/semgetvalue.c index ed49c09..f895266 100644 --- a/cpukit/posix/src/semgetvalue.c +++ b/cpukit/posix/src/semgetvalue.c @@ -37,13 +37,22 @@ int sem_getvalue( { POSIX_Semaphore_Control *the_semaphore; Objects_Locations location; + ISR_lock_Context lock_context; - the_semaphore = _POSIX_Semaphore_Get( sem, &location ); + the_semaphore = _POSIX_Semaphore_Get_interrupt_disable( +sem, +&location, +&lock_context + ); switch ( location ) { case OBJECTS_LOCAL: + /* + * Assume a relaxed atomic load of the value on SMP configurations. + * Thus, there is no need to acquire a lock. + */ *sval = _CORE_semaphore_Get_count( &the_semaphore->Semaphore ); - _Objects_Put( &the_semaphore->Object ); + _ISR_lock_ISR_enable( &lock_context ); return 0; #if defined(RTEMS_MULTIPROCESSING) -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 11/13] mghttpd: Allow to have no timegm().
From: Christian Mauderer We currently don't have a timegm function. There seems to be no easy way to replace this function with POSIX functions in a thread save way. This patch just avoids the call. Note that with this solution, the caching feature is effectively disabled. --- cpukit/mghttpd/civetweb.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/cpukit/mghttpd/civetweb.c b/cpukit/mghttpd/civetweb.c index edc13d6..41c3eed 100644 --- a/cpukit/mghttpd/civetweb.c +++ b/cpukit/mghttpd/civetweb.c @@ -4918,6 +4918,7 @@ get_month_index(const char *s) /* Parse UTC date-time string, and return the corresponding time_t value. */ +#if !defined(NO_TIMEGM) static time_t parse_date_string(const char *datetime) { @@ -4971,6 +4972,7 @@ parse_date_string(const char *datetime) return result; } +#endif /* !NO_TIMEGM */ /* Protect against directory disclosure attack by removing '..', @@ -7051,6 +7053,7 @@ substitute_index_file(struct mg_connection *conn, static int is_not_modified(const struct mg_connection *conn, const struct file *filep) { +#if !defined(NO_TIMEGM) char etag[64]; const char *ims = mg_get_header(conn, "If-Modified-Since"); const char *inm = mg_get_header(conn, "If-None-Match"); @@ -7060,6 +7063,9 @@ is_not_modified(const struct mg_connection *conn, const struct file *filep) } return (inm != NULL && !mg_strcasecmp(etag, inm)) || (ims != NULL && (filep->last_modified <= parse_date_string(ims))); +#else /* NO_TIMEGM */ + return false; +#endif /* !NO_TIMEGM */ } -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 00/13] Replace mongoose with civetweb.
This patch series replaces the mongoose webserver by its still MIT licensed fork civetweb. Please note that I try to get some (currently two) of the patches directly into civetweb too. But I think that it might need some time and adaption till they are accepted. So I thought that adding them to RTEMS would still make sense as a working interim solution. ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 03/13] testsuite: Add test for getnameinfo().
From: Christian Mauderer --- testsuites/libtests/Makefile.am| 1 + testsuites/libtests/configure.ac | 1 + testsuites/libtests/libnetworking01/Makefile.am| 22 +++ testsuites/libtests/libnetworking01/init.c | 161 + .../libtests/libnetworking01/libnetworking01.doc | 24 +++ .../libtests/libnetworking01/libnetworking01.scn | 9 ++ 6 files changed, 218 insertions(+) create mode 100644 testsuites/libtests/libnetworking01/Makefile.am create mode 100644 testsuites/libtests/libnetworking01/init.c create mode 100644 testsuites/libtests/libnetworking01/libnetworking01.doc create mode 100644 testsuites/libtests/libnetworking01/libnetworking01.scn diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am index d775c77..4be862e 100644 --- a/testsuites/libtests/Makefile.am +++ b/testsuites/libtests/Makefile.am @@ -23,6 +23,7 @@ _SUBDIRS += block13 _SUBDIRS += rbheap01 _SUBDIRS += flashdisk01 _SUBDIRS += capture01 +_SUBDIRS += libnetworking01 _SUBDIRS += bspcmdline01 cpuuse devfs01 devfs02 devfs03 devfs04 \ deviceio01 devnullfatal01 dumpbuf01 gxx01 top\ diff --git a/testsuites/libtests/configure.ac b/testsuites/libtests/configure.ac index 5ac2dfd..d0b7d6f 100644 --- a/testsuites/libtests/configure.ac +++ b/testsuites/libtests/configure.ac @@ -79,6 +79,7 @@ AM_CONDITIONAL(DLTESTS,[test x"$TEST_LIBDL" = x"yes"]) # Explicitly list all Makefiles here AC_CONFIG_FILES([Makefile +libnetworking01/Makefile libfdt01/Makefile defaultconfig01/Makefile pwdgrp02/Makefile diff --git a/testsuites/libtests/libnetworking01/Makefile.am b/testsuites/libtests/libnetworking01/Makefile.am new file mode 100644 index 000..9d25c75 --- /dev/null +++ b/testsuites/libtests/libnetworking01/Makefile.am @@ -0,0 +1,22 @@ + +rtems_tests_PROGRAMS = libnetworking01 +libnetworking01_SOURCES = init.c + +dist_rtems_tests_DATA = libnetworking01.scn +dist_rtems_tests_DATA += libnetworking01.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 +AM_CPPFLAGS += -I$(top_srcdir)/termios04 + +LINK_OBJS = $(libnetworking01_OBJECTS) +LINK_LIBS = $(libnetworking01_LDLIBS) + +libnetworking01$(EXEEXT): $(libnetworking01_OBJECTS) $(libnetworking01_DEPENDENCIES) + @rm -f libnetworking01$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/libtests/libnetworking01/init.c b/testsuites/libtests/libnetworking01/init.c new file mode 100644 index 000..c6edca4 --- /dev/null +++ b/testsuites/libtests/libnetworking01/init.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include +#include + +const char rtems_test_name[] = "LIBNETWORKING 1"; + +/* forward declarations to avoid warnings */ +static rtems_task Init(rtems_task_argument argument); + +static void fill_sa(struct sockaddr *sa, sa_family_t family) +{ + memset(sa, 0, sizeof(struct sockaddr)); + sa->sa_len = sizeof(struct sockaddr); + sa->sa_family = family; +} + +static void fill_sa_in(struct sockaddr_in *sa_in, + in_addr_t addr, in_port_t port) +{ + fill_sa((struct sockaddr *)sa_in, AF_INET); + sa_in->sin_port = port; + sa_in->sin_addr.s_addr = addr; +} + +static void test_getnameinfo( + const struct sockaddr *sa, + int flags, + bool ask_node, + bool ask_service, + int expected_returnvalue, + const char *expected_node, + const char *expected_service +) +{ + char node[] = "255.255.255.255"; + char service[] = "65535"; + socklen_t salen = sa->sa_len; + int rv; + + char *node_p = node; + char *service_p = service; + size_t node_l = sizeof(node); + size_t service_l = sizeof(service); + + if(ask_node == false) { +node_p = NULL; +node_l = 0; + } + + if(ask_service == false) { +service_p = NULL; +service_l = 0; + } + + rv = getnameinfo(sa, salen, node_p, node_l, service_p, service_l, flags); + rtems_test_assert(rv == expected_returnvalue); + + if(expected_node != NULL) { +rtems_test_assert(strcmp(expected_node, node) == 0); + } + + if(expected_service != NULL) { +rtems_test_assert(strcmp(expected_service, service) == 0); + } +} + +static void test(void) +{ + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr *sa_in_p = (struct sockaddr *) &sa_in; + + const in_addr_t ip1_num = 0x7F01u; + const char ip1_string[] = "127.0.0.1"; + + const in_addr_t ip2_num = 0xC0A86464u; + const char ip2_string[] = "192.168.100.100"; + + const
[PATCH 09/13] mghttpd: Add stack size and scheduling options.
From: Christian Mauderer This applies the changes from 54da7c3e55056efd93adece52076b720490258d6. --- cpukit/mghttpd/civetweb.c | 117 +- 1 file changed, 96 insertions(+), 21 deletions(-) diff --git a/cpukit/mghttpd/civetweb.c b/cpukit/mghttpd/civetweb.c index 47e1dfe..0c907f0 100644 --- a/cpukit/mghttpd/civetweb.c +++ b/cpukit/mghttpd/civetweb.c @@ -1117,10 +1117,18 @@ enum { CONFIG_TCP_NODELAY, /* Prepended CONFIG_ to avoid conflict with the * socket option typedef TCP_NODELAY. */ STATIC_FILE_MAX_AGE, + THREAD_STACK_SIZE, +#if !defined(_WIN32) + THREAD_PRIORITY, + THREAD_POLICY, +#endif NUM_OPTIONS }; +/* Macros for stringification */ +#define TO_STRING(s) X_TO_STRING(s) +#define X_TO_STRING(s) #s /* Config option name, config types, default value */ static struct mg_option config_options[] = { @@ -1191,7 +1199,15 @@ static struct mg_option config_options[] = { {"_experimental_static_file_max_age", CONFIG_TYPE_NUMBER, "3600"}, /* TODO: redefine parameter */ - +#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) +{"thread_stack_size", CONFIG_TYPE_NUMBER, TO_STRING(USE_STACK_SIZE)}, +#else +{"thread_stack_size", CONFIG_TYPE_NUMBER, "0"}, +#endif +#if !defined(_WIN32) +{"thread_priority", CONFIG_TYPE_NUMBER, NULL}, +{"thread_policy", CONFIG_TYPE_STRING, NULL}, +#endif {NULL, CONFIG_TYPE_UNKNOWN, NULL}}; /* Check if the config_options and the corresponding enum have compatible @@ -3121,19 +3137,22 @@ set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */) int mg_start_thread(mg_thread_func_t f, void *p) { -#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) - /* Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 -*/ - return ((_beginthread((void(__cdecl *)(void *))f, USE_STACK_SIZE, p) + struct mg_context* ctx = p; + char* stacksize = ctx->config[THREAD_STACK_SIZE]; + unsigned size = 0; + + if (stacksize != NULL) { + int size = atoi(stacksize); + if (size <= 0) { + mg_cry(fc(ctx), + "Stack size has to be a positive number. Is: %d", + size); + } + } + return ((_beginthread((void(__cdecl *)(void *))f, size, p) == ((uintptr_t)(-1L))) ? -1 : 0); -#else - return ( - (_beginthread((void(__cdecl *)(void *))f, 0, p) == ((uintptr_t)(-1L))) - ? -1 - : 0); -#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */ } @@ -3440,6 +3459,68 @@ set_close_on_exec(SOCKET fd, struct mg_connection *conn /* may be null */) } } +static void +set_pthread_attributes(struct mg_context *ctx, pthread_attr_t *attr) +{ + char* stacksize = ctx->config[THREAD_STACK_SIZE]; + char* priority = ctx->config[THREAD_PRIORITY]; + char* policy = ctx->config[THREAD_POLICY]; + int noinheritsched = 0; + + if (stacksize != NULL) { + int size = atoi(stacksize); + if (size <= 0) { + mg_cry(fc(ctx), + "Stack size has to be a positive number. Is: %d", + size); + } + (void) pthread_attr_setstacksize(attr, (size_t) size); + } + + if (priority != NULL) { + struct sched_param sched_param; + memset(&sched_param, 0, sizeof(sched_param)); + sched_param.sched_priority = atoi(priority); + (void) pthread_attr_setschedparam(attr, &sched_param); + noinheritsched = 1; + } + + if (policy != NULL) { + int p_policy; + (void) pthread_attr_getschedpolicy(attr, &p_policy); + + switch (policy[0]) { + case 'o': + p_policy = SCHED_OTHER; + break; + case 'f': + p_policy = SCHED_FIFO; + break; + case 'r': + p_policy = SCHED_RR; + break; +#if (defined(_POSIX_SPORADIC_SERVER) && (_POSIX_SPORADIC_SERVER > 0)) || \ +(defined(_POSIX_THREAD_SPORADIC_SERVER) && \ +(_POSIX_THREAD_SPORADIC_SERVER > 0)) + case 's': + p_policy = SCHED_SPORADIC; + break; +#endif + default: + mg_cry(fc(ctx), "Unknown scheduler: %s", policy); + break; + } + + (void) pthread_attr_setschedpolicy(attr, p_policy); + + noinheritsched = 1; + } + + if (noinheritsched != 0) { + (void) pthread_attr_setinheritsched(attr, + PTHREAD_EXPLICIT_SCHED); + }
[PATCH 04/13] libcsupport: Add dummy for setgroups().
From: Christian Mauderer The dummy for setgroups() allows applications using it to build (for example civetweb webserver). --- cpukit/libcsupport/Makefile.am | 2 +- cpukit/libcsupport/src/setgroups.c | 26 testsuites/psxtests/psxhdrs/Makefile.am| 1 + testsuites/psxtests/psxhdrs/unistd/setgroups.c | 33 ++ 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 cpukit/libcsupport/src/setgroups.c create mode 100644 testsuites/psxtests/psxhdrs/unistd/setgroups.c diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am index b3ad3db..effe426 100644 --- a/cpukit/libcsupport/Makefile.am +++ b/cpukit/libcsupport/Makefile.am @@ -73,7 +73,7 @@ DIRECTORY_SCAN_C_FILES += src/getcwd.c ID_C_FILES = src/getegid.c src/geteuid.c src/getgid.c src/getgroups.c \ src/getlogin.c src/getpgrp.c src/getpid.c src/getppid.c src/getuid.c \ src/seteuid.c src/setgid.c src/setuid.c src/setegid.c src/setpgid.c \ -src/setsid.c +src/setsid.c src/setgroups.c MALLOC_C_FILES = src/malloc_initialize.c src/malloc.c \ src/realloc.c src/_calloc_r.c src/_malloc_r.c \ diff --git a/cpukit/libcsupport/src/setgroups.c b/cpukit/libcsupport/src/setgroups.c new file mode 100644 index 000..9f75f20 --- /dev/null +++ b/cpukit/libcsupport/src/setgroups.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#include + +int setgroups(int size, const gid_t *list) +{ + /* FIXME: Implement this function properly. Currently it only returns a +* success. */ + + (void) size; + (void) list; + + return 0; +} diff --git a/testsuites/psxtests/psxhdrs/Makefile.am b/testsuites/psxtests/psxhdrs/Makefile.am index 3eecd84..c3b1f88 100644 --- a/testsuites/psxtests/psxhdrs/Makefile.am +++ b/testsuites/psxtests/psxhdrs/Makefile.am @@ -128,6 +128,7 @@ lib_a_SOURCES += unistd/getppid.c lib_a_SOURCES += unistd/getuid.c lib_a_SOURCES += unistd/pause.c lib_a_SOURCES += unistd/setgid.c +lib_a_SOURCES += unistd/setgroups.c lib_a_SOURCES += unistd/setpgid.c lib_a_SOURCES += unistd/setsid.c lib_a_SOURCES += unistd/setuid.c diff --git a/testsuites/psxtests/psxhdrs/unistd/setgroups.c b/testsuites/psxtests/psxhdrs/unistd/setgroups.c new file mode 100644 index 000..e8b87ab --- /dev/null +++ b/testsuites/psxtests/psxhdrs/unistd/setgroups.c @@ -0,0 +1,33 @@ +/* + * This test file is used to verify that the header files associated with + * invoking this function are correct. + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +int test( void ); + +int test( void ) +{ + gid_t grouplist[ 20 ]; + int gidsetsize; + int result; + + gidsetsize = sizeof(grouplist)/sizeof(grouplist[0]); + + result = setgroups( gidsetsize, grouplist ); + + return result; +} -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 07/13] mghttpd: Use HAVE_CONFIG_H.
From: Christian Mauderer This applies the changes from 4248b28296af7a56c3b1fb14c53debd8d79ed6d9. --- cpukit/mghttpd/civetweb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpukit/mghttpd/civetweb.c b/cpukit/mghttpd/civetweb.c index 5c5cd72..1fb9ead 100644 --- a/cpukit/mghttpd/civetweb.c +++ b/cpukit/mghttpd/civetweb.c @@ -20,6 +20,9 @@ * THE SOFTWARE. */ +#if HAVE_CONFIG_H + #include "config.h" +#endif #if defined(_WIN32) #if !defined(_CRT_SECURE_NO_WARNINGS) -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 06/13] mghttpd: Use poll() replacement.
From: Christian Mauderer This patch provides a poll() replacement based on the poll() used for civetweb on windows. A similar patch based on the one on http://forums.bannister.org/ubbthreads.php?ubb=showflat&topic=7600&gonew=1 had been integrated into the RTEMS version of mongoose in commit b5d2d4a61ce91765e9cac1b02271a8f4b049c558. --- cpukit/mghttpd/civetweb.c | 93 +++ 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/cpukit/mghttpd/civetweb.c b/cpukit/mghttpd/civetweb.c index 32cee56..5c5cd72 100644 --- a/cpukit/mghttpd/civetweb.c +++ b/cpukit/mghttpd/civetweb.c @@ -376,17 +376,6 @@ typedef struct DIR { struct dirent result; } DIR; -#if defined(_WIN32) && !defined(POLLIN) -#ifndef HAVE_POLL -struct pollfd { - SOCKET fd; - short events; - short revents; -}; -#define POLLIN (0x0300) -#endif -#endif - /* Mark required libraries */ #if defined(_MSC_VER) #pragma comment(lib, "Ws2_32.lib") @@ -397,7 +386,9 @@ struct pollfd { #include #include +#ifdef HAVE_POLL #include +#endif #include #include #include @@ -467,6 +458,15 @@ typedef int SOCKET; #endif /* defined(_WIN32) && !defined(__SYMBIAN32__) - WINDOWS / UNIX include \ block */ +#ifndef HAVE_POLL +struct pollfd { + SOCKET fd; + short events; + short revents; +}; +#define POLLIN (0x0300) +#endif + /* va_copy should always be a macro, C99 and C++11 - DTL */ #ifndef va_copy #define va_copy(x, y) ((x) = (y)) @@ -3096,42 +3096,6 @@ readdir(DIR *dir) } -#ifndef HAVE_POLL -static int -poll(struct pollfd *pfd, unsigned int n, int milliseconds) -{ - struct timeval tv; - fd_set set; - unsigned int i; - int result; - SOCKET maxfd = 0; - - memset(&tv, 0, sizeof(tv)); - tv.tv_sec = milliseconds / 1000; - tv.tv_usec = (milliseconds % 1000) * 1000; - FD_ZERO(&set); - - for (i = 0; i < n; i++) { - FD_SET((SOCKET)pfd[i].fd, &set); - pfd[i].revents = 0; - - if (pfd[i].fd > maxfd) { - maxfd = pfd[i].fd; - } - } - - if ((result = select((int)maxfd + 1, &set, NULL, NULL, &tv)) > 0) { - for (i = 0; i < n; i++) { - if (FD_ISSET(pfd[i].fd, &set)) { - pfd[i].revents = POLLIN; - } - } - } - - return result; -} -#endif /* HAVE_POLL */ - #if defined(__MINGW32__) /* Enable unused function warning again */ #pragma GCC diagnostic pop @@ -3637,6 +3601,41 @@ set_non_blocking_mode(SOCKET sock) #endif /* _WIN32 */ /* End of initial operating system specific define block. */ +#ifndef HAVE_POLL +static int +poll(struct pollfd *pfd, unsigned int n, int milliseconds) +{ + struct timeval tv; + fd_set set; + unsigned int i; + int result; + SOCKET maxfd = 0; + + memset(&tv, 0, sizeof(tv)); + tv.tv_sec = milliseconds / 1000; + tv.tv_usec = (milliseconds % 1000) * 1000; + FD_ZERO(&set); + + for (i = 0; i < n; i++) { + FD_SET((SOCKET)pfd[i].fd, &set); + pfd[i].revents = 0; + + if (pfd[i].fd > maxfd) { + maxfd = pfd[i].fd; + } + } + + if ((result = select((int)maxfd + 1, &set, NULL, NULL, &tv)) > 0) { + for (i = 0; i < n; i++) { + if (FD_ISSET(pfd[i].fd, &set)) { + pfd[i].revents = POLLIN; + } + } + } + + return result; +} +#endif /* HAVE_POLL */ /* Get a random number (independent of C rand function) */ static uint64_t -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 10/13] mghttpd: Don't use __sync_XXX_and_fetch functions.
From: Christian Mauderer This patch should be replaced by one that uses libatomic as soon as it is provided by our toolchain. --- cpukit/mghttpd/civetweb.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cpukit/mghttpd/civetweb.c b/cpukit/mghttpd/civetweb.c index 0c907f0..edc13d6 100644 --- a/cpukit/mghttpd/civetweb.c +++ b/cpukit/mghttpd/civetweb.c @@ -1371,7 +1371,9 @@ mg_atomic_inc(volatile int *addr) * so whatever you use, the other SDK is likely to raise a warning. */ ret = InterlockedIncrement((volatile long *)addr); #elif defined(__GNUC__) \ -&& ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) +&& ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \ +&& !defined(__rtems__) +/* FIXME: Use libatomic support as soon as it is provided. */ ret = __sync_add_and_fetch(addr, 1); #else ret = (++(*addr)); @@ -1390,7 +1392,9 @@ mg_atomic_dec(volatile int *addr) * so whatever you use, the other SDK is likely to raise a warning. */ ret = InterlockedDecrement((volatile long *)addr); #elif defined(__GNUC__) \ -&& ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) +&& ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \ +&& !defined(__rtems__) +/* FIXME: Use libatomic support as soon as it is provided. */ ret = __sync_sub_and_fetch(addr, 1); #else ret = (--(*addr)); -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 02/13] libnetworking: Add minimal getnameinfo().
From: Christian Mauderer This implementation just falls back to giving a string representation of the IP. It supports IPv4 only. --- cpukit/libnetworking/Makefile.am| 2 +- cpukit/libnetworking/libc/getnameinfo.c | 61 + 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 cpukit/libnetworking/libc/getnameinfo.c diff --git a/cpukit/libnetworking/Makefile.am b/cpukit/libnetworking/Makefile.am index 2a8e06a..1dff40c 100644 --- a/cpukit/libnetworking/Makefile.am +++ b/cpukit/libnetworking/Makefile.am @@ -213,7 +213,7 @@ include_HEADERS += ifaddrs.h libc_a_SOURCES = libc/base64.c \ libc/gethostbydns.c libc/gethostbyht.c libc/gethostbynis.c \ libc/gethostnamadr.c libc/getnetbydns.c libc/getnetbyht.c \ -libc/getnetbynis.c libc/getnetnamadr.c libc/getproto.c \ +libc/getnetbynis.c libc/getnetnamadr.c libc/getnameinfo.c libc/getproto.c \ libc/getprotoent.c libc/getprotoname.c libc/getservbyname.c \ libc/getservbyport.c libc/getservent.c libc/herror.c libc/inet_addr.c \ libc/inet_lnaof.c libc/inet_makeaddr.c libc/inet_netof.c \ diff --git a/cpukit/libnetworking/libc/getnameinfo.c b/cpukit/libnetworking/libc/getnameinfo.c new file mode 100644 index 000..415f150 --- /dev/null +++ b/cpukit/libnetworking/libc/getnameinfo.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#include +#include +#include +#include +#include + +int +getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, +size_t nodelen, char *service, size_t servicelen, int flags) +{ + int af; + const struct sockaddr_in *sa_in = (const struct sockaddr_in *)sa; + + (void) salen; + + af = sa->sa_family; + if (af != AF_INET) { + return EAI_FAMILY; + } + + if ((flags & NI_NAMEREQD) != 0) { + return EAI_NONAME; + } + + /* FIXME: This return just the address value. Try resolving instead. */ + if (node != NULL && nodelen > 0) { + const void *addr = &sa_in->sin_addr; + + if(inet_ntop(af, addr, node, nodelen) == NULL) { + return EAI_FAIL; + } + } + + if (service != NULL && servicelen > 0) { + in_port_t port = sa_in->sin_port; + int rv; + + rv = snprintf(service, servicelen, "%u", port); + if (rv <= 0) { + return EAI_FAIL; + } else if ((unsigned)rv >= servicelen) { + return EAI_OVERFLOW; + } + } + + return 0; +} -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 01/13] libnetworking: Add prototype for getnameinfo().
From: Christian Mauderer Copy the prototype and necessary defines for getnameinfo() from current FreeBSD. --- cpukit/libnetworking/netdb.h | 47 1 file changed, 47 insertions(+) diff --git a/cpukit/libnetworking/netdb.h b/cpukit/libnetworking/netdb.h index 92e283b..4272902 100644 --- a/cpukit/libnetworking/netdb.h +++ b/cpukit/libnetworking/netdb.h @@ -114,6 +114,8 @@ struct protoent { int p_proto;/* protocol # */ }; +struct sockaddr; + /* * Error return codes from gethostbyname() and gethostbyaddr() * (left in h_errno). @@ -127,6 +129,49 @@ struct protoent { #defineNO_DATA 4 /* Valid name, no data record of requested type */ #defineNO_ADDRESS NO_DATA /* no address, look for MX record */ +/* + * Error return codes from getaddrinfo() + */ +#if 0 +/* obsoleted */ +#defineEAI_ADDRFAMILY 1 /* address family for hostname not supported */ +#endif +#defineEAI_AGAIN2 /* temporary failure in name resolution */ +#defineEAI_BADFLAGS 3 /* invalid value for ai_flags */ +#defineEAI_FAIL 4 /* non-recoverable failure in name resolution */ +#defineEAI_FAMILY 5 /* ai_family not supported */ +#defineEAI_MEMORY 6 /* memory allocation failure */ +#if 0 +/* obsoleted */ +#defineEAI_NODATA 7 /* no address associated with hostname */ +#endif +#defineEAI_NONAME 8 /* hostname nor servname provided, or not known */ +#defineEAI_SERVICE 9 /* servname not supported for ai_socktype */ +#defineEAI_SOCKTYPE10 /* ai_socktype not supported */ +#defineEAI_SYSTEM 11 /* system error returned in errno */ +#defineEAI_BADHINTS12 /* invalid value for hints */ +#defineEAI_PROTOCOL13 /* resolved protocol is unknown */ +#defineEAI_OVERFLOW14 /* argument buffer overflow */ +#defineEAI_MAX 15 + +/* + * Constants for getnameinfo() + */ +#defineNI_MAXHOST 1025 +#defineNI_MAXSERV 32 + +/* + * Flag values for getnameinfo() + */ +#defineNI_NOFQDN 0x0001 +#defineNI_NUMERICHOST 0x0002 +#defineNI_NAMEREQD 0x0004 +#defineNI_NUMERICSERV 0x0008 +#defineNI_DGRAM0x0010 +#if 0 /* obsolete */ +#define NI_WITHSCOPEID 0x0020 +#endif + __BEGIN_DECLS void endhostent(void); void endnetent(void); @@ -152,6 +197,8 @@ voidsethostent(int); void setnetent(int); void setprotoent(int); void setservent(int); +intgetnameinfo(const struct sockaddr *, socklen_t, char *, + size_t, char *, size_t, int); #ifdef _THREAD_SAFE struct hostent* gethostent_r(char* buf, int len); -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 08/13] mghttpd: Use MD5 library.
From: Christian Mauderer This applies the changes from ea008e2d0d78b49e0f793949ab4a665b69283372. --- cpukit/mghttpd/civetweb.c | 5 + 1 file changed, 5 insertions(+) diff --git a/cpukit/mghttpd/civetweb.c b/cpukit/mghttpd/civetweb.c index 1fb9ead..47e1dfe 100644 --- a/cpukit/mghttpd/civetweb.c +++ b/cpukit/mghttpd/civetweb.c @@ -24,6 +24,11 @@ #include "config.h" #endif +#if defined(__rtems__) +#include +#define HAVE_MD5 +#endif // __rtems__ + #if defined(_WIN32) #if !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005 */ -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 12/13] mghttpd: Use gethostbyname instead of getaddrinfo.
From: Christian Mauderer RTEMS does not have a getaddrinfo() so use gethostbyname() instead. This reintroduces a not thread save function into the code but it seems that we have no better replacement at the moment. --- cpukit/mghttpd/civetweb.c | 28 1 file changed, 28 insertions(+) diff --git a/cpukit/mghttpd/civetweb.c b/cpukit/mghttpd/civetweb.c index 41c3eed..520a6b6 100644 --- a/cpukit/mghttpd/civetweb.c +++ b/cpukit/mghttpd/civetweb.c @@ -5801,6 +5801,33 @@ is_valid_port(unsigned long port) static int mg_inet_pton(int af, const char *src, void *dst, size_t dstlen) { + +#if defined(__rtems__) && !defined(USE_IPV6) + int ret = 0; + struct sockaddr_in *sin_dst = dst; + struct hostent *he; + + if (af != AF_INET || dstlen != sizeof(struct sockaddr_in)) { + /* only IPv4 is supported */ + return 0; + } + + memset(sin_dst, '0', dstlen); + + /* FIXME: gethostbyname is NOT thread-save! */ + he = gethostbyname(src); + if(he != NULL) { + sin_dst->sin_family = af; + memcpy(&sin_dst->sin_addr, he->h_addr_list[0], he->h_length); + ret = 1; + } + + return ret; + +#else /* !defined(__rtems) || defined(USE_IPV6) */ +#if defined(__rtems__) +#warning This does not work with the integrated (old) RTEMS network stack +#endif struct addrinfo hints, *res, *ressave; int ret = 0; @@ -5824,6 +5851,7 @@ mg_inet_pton(int af, const char *src, void *dst, size_t dstlen) freeaddrinfo(ressave); return ret; +#endif /* defined(__rtems) && !defined(USE_IPV6) */ } -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Provide POSIX network header for all normal Newlib targets?
Hello, with the recent type changes for etc. we are now able to build the FreeBSD 9.3 network stack on RTEMS. We directly use * , * , * , * , * , * , and * from Newlib with mostly unmodified FreeBSD header and source files. Cygwin and Linux provide currently their own set of network header files in Newlib. RTEMS has its own sets outside of Newlib. Since the Linux port is a bit special I don't consider it here. I think for the other Newlib targets it may be beneficial to provide at least the POSIX network header files * , * , * , * , * , * , * , * , and * in Newlib. It has the advantage that Newlib users get a consistent set of POSIX network header files with compatibility to FreeBSD. Since there are a lot of software packages available for Cygwin it would be quite nice for the smaller embedded systems targets to share header files with Cygwin. My approach would be to import the latest network header files from FreeBSD. Then remove all #ifdef _KERNEL parts and use an #include to provide machine-specific stuff for each header file, e.g. , . Keep the #ifndef _KERNEL parts for FreeBSD compatibility. I only roughly looked at the Cygwin network headers, but it would be a bit of work to import the latest network headers from FreeBSD and use them in Cygwin, e.g. deal with __INSIDE_CYGWIN_NET__. How do you think about this? -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: RKI Build Error - rtems_clock_get not available on 4.12
Hello Habeeb, rtems_clock_get() has been obsoleted long time ago and has been removed in e65c45c4b6cf6dfb485bef48385e39969de8b361 Obsolete rtems_clock_get() directive. This service was marked as deprecated long prior to the 4.11 release series and is now being removed. closes #2676. You should rewrite code as rtems_interval ticks; - rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT,&ticks); + ticks = rtems_clock_get_ticks_since_boot(); If you need to be compatible even with very old RTEMS versions, probably pre-4.9, you can use rtems_interval ticks; #ifndef RTEMS_CLOCK_GET_TICKS_SINCE_BOOT ticks = rtems_clock_get_ticks_since_boot(); #else /*RTEMS_CLOCK_GET_TICKS_SINCE_BOOT*/ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT,&ticks); #endif /*RTEMS_CLOCK_GET_TICKS_SINCE_BOOT*/ Best wishes, Pavel On Thursday 21 of April 2016 02:50:55 Olufowobi, Habeeb wrote: > Hi, > > I am trying to build RKI for Raspberrypi but I have been getting this error > message: > > > arm-rtems4.12-gcc > -Wa,-a=legacy-build/arm-rtems4.12-raspberrypi/task_cmd.lis -march=armv7-a > -mthumb -mfpu=neon -mfloat-abi=hard -mtune=cortex-a7 -D__ARM__ --pipe > -B/home/dipupo/development/rtems/kernel/builds/b-rpi/arm-rtems4.12/raspberr >ypi/lib -specs bsp_specs -qrtems -Wall -I. -Iinclude/ -I. -g -O2 -c -o > legacy-build/arm-rtems4.12-raspberrypi/task_cmd.o task_cmd.c > task_cmd.c: In function 'get_ticks_per_second': > task_cmd.c:23:10: warning: implicit declaration of function > 'rtems_clock_get' [-Wimplicit-function-declaration] >(void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, > &ticks_per_second ); return ticks_per_second; > ^~~ > task_cmd.c:23:27: error: 'RTEMS_CLOCK_GET_TICKS_PER_SECOND' undeclared > (first use in this function) >(void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, > &ticks_per_second ); return ticks_per_second; >^~~~ > > > The line associated with this message in the task_cmd.c is > > { > rtems_interval ticks_per_second; > (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, > &ticks_per_second ); return ticks_per_second; > } > > > Any ideas on how I can fix this? > > Thanks. > > Best regards, > Habeeb ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: RKI Build Error - rtems_clock_get not available on 4.12
I should be able to update my RKI repository soon.. I’m building the latest tools and RTEMS repo now. Alan > On Apr 21, 2016, at 6:14 AM, Pavel Pisa wrote: > > Hello Habeeb, > > rtems_clock_get() has been obsoleted long time ago > and has been removed in > >e65c45c4b6cf6dfb485bef48385e39969de8b361 >Obsolete rtems_clock_get() directive. > >This service was marked as deprecated long prior to the 4.11 release >series and is now being removed. > >closes #2676. > > > You should rewrite code as > > rtems_interval ticks; > - rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT,&ticks); > + ticks = rtems_clock_get_ticks_since_boot(); > > > If you need to be compatible even with very old RTEMS versions, probably > pre-4.9, you can use > > rtems_interval ticks; > #ifndef RTEMS_CLOCK_GET_TICKS_SINCE_BOOT > ticks = rtems_clock_get_ticks_since_boot(); > #else /*RTEMS_CLOCK_GET_TICKS_SINCE_BOOT*/ > rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT,&ticks); > #endif /*RTEMS_CLOCK_GET_TICKS_SINCE_BOOT*/ > > Best wishes, > > Pavel > > > On Thursday 21 of April 2016 02:50:55 Olufowobi, Habeeb wrote: >> Hi, >> >> I am trying to build RKI for Raspberrypi but I have been getting this error >> message: >> >> >> arm-rtems4.12-gcc >> -Wa,-a=legacy-build/arm-rtems4.12-raspberrypi/task_cmd.lis -march=armv7-a >> -mthumb -mfpu=neon -mfloat-abi=hard -mtune=cortex-a7 -D__ARM__ --pipe >> -B/home/dipupo/development/rtems/kernel/builds/b-rpi/arm-rtems4.12/raspberr >> ypi/lib -specs bsp_specs -qrtems -Wall -I. -Iinclude/ -I. -g -O2 -c -o >> legacy-build/arm-rtems4.12-raspberrypi/task_cmd.o task_cmd.c >> task_cmd.c: In function 'get_ticks_per_second': >> task_cmd.c:23:10: warning: implicit declaration of function >> 'rtems_clock_get' [-Wimplicit-function-declaration] >> (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, >> &ticks_per_second ); return ticks_per_second; >> ^~~ >> task_cmd.c:23:27: error: 'RTEMS_CLOCK_GET_TICKS_PER_SECOND' undeclared >> (first use in this function) >> (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, >> &ticks_per_second ); return ticks_per_second; >> ^~~~ >> >> >> The line associated with this message in the task_cmd.c is >> >> { >> rtems_interval ticks_per_second; >> (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, >> &ticks_per_second ); return ticks_per_second; >> } >> >> >> Any ideas on how I can fix this? >> >> Thanks. >> >> Best regards, >> Habeeb > > ___ > devel mailing list > devel@rtems.org > http://lists.rtems.org/mailman/listinfo/devel ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH] config/microblaze/rtems.h: Redefine LINK_SPEC for RTEMS
2016-04-21 Joel Sherrill * config/microblaze/rtems.h: Redefine LINK_SPEC to avoid xilink.ld and flags not relevant to RTEMS. --- gcc/config/microblaze/rtems.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/gcc/config/microblaze/rtems.h b/gcc/config/microblaze/rtems.h index 68aa381..56f3f70 100644 --- a/gcc/config/microblaze/rtems.h +++ b/gcc/config/microblaze/rtems.h @@ -23,3 +23,10 @@ along with GCC; see the file COPYING3. If not see builtin_define( "__rtems__" ); \ builtin_assert( "system=rtems" );\ } while (0) + +/* Redefine to include only items relevant for RTEMS */ +#undef LINK_SPEC +#define LINK_SPEC "%{shared:-shared} -N -relax \ + %{mbig-endian:-EB --oformat=elf32-microblaze} \ + %{mlittle-endian:-EL --oformat=elf32-microblazeel} \ + %{mxl-gp-opt:%{G*}} %{!mxl-gp-opt: -G 0}" -- 1.8.3.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Managing RTEMS time in a paravirtualized environment
Hi Gedare and I are working on a paravirtualized RTEMS executing in an ARINC 653 partition. One challenge is ensuring the time passage in RTEMS is correct. The problem in a nutshell is that RTEMS is not executing the entire time. Each partition is an independent RTEMS instance. There will be no "ticks" while an RTEMS partition is executing. Consider this basic scenario. + Time Window 1 - RTEMS runs + TIme Window 2 .. n-1 - other applications run + Time Window n - RTEMS runs again We do not have a periodic interrupt which is documented in #2271 as a requirement. Additionally we can ask the underlying protection kernel for the value of a nanoseconds counter. We see this as satisfying the requirement for a running counter. Time WIndow 1 can end because RTEMS either voluntarily yielded the time window or because it used its entire time budge. Either way, when it runs again in Time Window N, we can determine how much time has passed from the beginning of Time Window 1 to the beginning of Time Window N. Our working assumption is that we will advance time at the beginning of each time window. The length of time advanced should be assumed to be variable. We have control over a recommended configure vaiue for nanoseconds per tick and I am thinking always using 1 millisecond and calling clock tick the proper number of times on each time windows entry. Another challenge is ensuring the implementation does not include non-RTEMS time windows in the CPU time statistics of the thread that was executing at the end of one time windows and beginning of our next one. Any thoughts on how to best manage this variable clock tick? Thanks. --joel ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 00/13] Replace mongoose with civetweb.
On 21/04/2016 18:49, Christian Mauderer wrote: This patch series replaces the mongoose webserver by its still MIT licensed fork civetweb. Please note that I try to get some (currently two) of the patches directly into civetweb too. But I think that it might need some time and adaption till they are accepted. So I thought that adding them to RTEMS would still make sense as a working interim solution. Would we be better served by providing this as an external 3rd party package via the RSB and we remove the code or add a configure disable? The package could be used by both stacks. We have plans to remove the existing stack from the source tree and to make a separate package and I guess at that point in time all dependent client networking code in the source tree will also need to be removed. Chris ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 00/13] Replace mongoose with civetweb.
On Thu, Apr 21, 2016 at 7:36 PM, Chris Johns wrote: > On 21/04/2016 18:49, Christian Mauderer wrote: > >> This patch series replaces the mongoose webserver by its still MIT >> licensed fork civetweb. >> >> Please note that I try to get some (currently two) of the patches >> directly into civetweb too. But I think that it might need some time and >> adaption till they are accepted. So I thought that adding them to RTEMS >> would still make sense as a working interim solution. >> >> > Would we be better served by providing this as an external 3rd party > package via the RSB and we remove the code or add a configure disable? The > package could be used by both stacks. > > We have plans to remove the existing stack from the source tree and to > make a separate package and I guess at that point in time all dependent > client networking code in the source tree will also need to be removed. > > I think this is an excellent idea and starts to move us down the path of + base RTEMS without network stack + choice of network stack in separate repo (current, rtems-libbsd, or LwIP) + RSB packages for services. The RSB packages deal nicely with patches that need to go upstream. --joel > Chris > > ___ > devel mailing list > devel@rtems.org > http://lists.rtems.org/mailman/listinfo/devel > ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
the rtems kernel source list
Hello, I am learning RTEMS, where is the kernel source, I find some place seems holding the kernel source: rtems/c/src/support/ - only version.c there. rtems/c/src/ada/ - is this kernel source? rtems/cpukit/score/src why named score? rtems/cpukit/rtems/src kernel source? rtems/score/cpu/$(ARCH) --- cpu depended code? is there any more code belone to the RTEMS kernel. thanks very much. please kindly help. - - duhuanpeng ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: the rtems kernel source list
On 22/04/2016 12:19, printk wrote: Hello, I am learning RTEMS, where is the kernel source, I find some place seems holding the kernel source: rtems/c/src/support/ - only version.c there. rtems/c/src/ada/ - is this kernel source? No. rtems/cpukit/score/src why named score? Supercore or score, it sits behind the POSIX and Classic APIs and is a superset of the various APIs that export the kernel to users, eg POSIX. rtems/cpukit/rtems/src kernel source? RTEMS Classic API. rtems/score/cpu/$(ARCH) --- cpu depended code? Yes. is there any more code belone to the RTEMS kernel. thanks very much. please kindly help. The BSP code, and a chip driver library (libchip). Chris ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 00/13] Replace mongoose with civetweb.
Yes that's right. 05/13 just adds the unchanged sources from civetweb. Beneath civetweb.c and civetweb.h it also adds handle_form.inl and md5.inl. The last two files are included into civetweb.c. According to the documentation "The *INL* file extension represents code that is statically included inline in a source file." And yes: The patch didn't get through. I have got a replay that "Your message to devel awaits moderator approval". The civetweb.c file is over 300k and the mailing list seems to have a maximum of 256k. I hoped that one of the mail admins would approve the patch soon. Am 21.04.2016 um 22:49 schrieb Gedare Bloom: > I think patch 05/13 probably adds civetweb.c and civetweb.h? But it > did not come through the mailman. > > On Thu, Apr 21, 2016 at 4:46 PM, Gedare Bloom wrote: >> P.S. might be worth it to open a ticket related to civetweb and >> #update it from these patches. >> >> On Thu, Apr 21, 2016 at 4:45 PM, Gedare Bloom wrote: >>> Is the plan eventually to be able to use the upstream civetweb? or to >>> track it with our own copy? >>> >>> On Thu, Apr 21, 2016 at 4:49 AM, Christian Mauderer >>> wrote: This patch series replaces the mongoose webserver by its still MIT licensed fork civetweb. Please note that I try to get some (currently two) of the patches directly into civetweb too. But I think that it might need some time and adaption till they are accepted. So I thought that adding them to RTEMS would still make sense as a working interim solution. ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel -- embedded brains GmbH Christian Mauderer Dornierstr. 4 D-82178 Puchheim Germany email: christian.maude...@embedded-brains.de Phone: +49-89-18 94 741 - 18 Fax: +49-89-18 94 741 - 08 PGP: Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
arm shared code contains not shared code?
Hello, I am learning the rtems source, and when i look into this folder: rtems@book64:~/rtems-lite/rtems/c/src/lib/libcpu/arm/shared$ tree . ├── arm920 │ └── mmu.c └── include ├── am335x.h ├── arm-cp15.h ├── cache_.h ├── mmu.h ├── omap3.h └── omap_timer.h 2 directories, 7 files rtems@book64:~/rtems-lite/rtems/c/src/lib/libcpu/arm/shared$ this folder i guess it means stuff shared by arm arch? or something else? why these files here to, it seems can not 'share' with other arm 'SoC' am335x.h omap3.h omap_timer.h How about move these file to some place machine depended folders? I guess the arm just means the arm cpu in the SoC, not a arm SoC. thanks, duhuanpeng ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel