From 6bc7a5e1a38d6566fb404bcb736bf96926f4b1fe Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 4 Dec 2006 14:16:26 +0000 Subject: 2006-12-04 Joel Sherrill * posix/src/prwlockunlock.c, rtems/Makefile.am, rtems/src/barrierrelease.c, rtems/src/barrierwait.c, score/src/corerwlockobtainread.c, score/src/corerwlockrelease.c: Complete implementation of barrier as the rest of the test code is now implemented. Also add blocking code to rwlock. --- cpukit/score/src/corerwlockobtainread.c | 2 +- cpukit/score/src/corerwlockrelease.c | 34 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) (limited to 'cpukit/score') diff --git a/cpukit/score/src/corerwlockobtainread.c b/cpukit/score/src/corerwlockobtainread.c index 46f77043e8..724529eef5 100644 --- a/cpukit/score/src/corerwlockobtainread.c +++ b/cpukit/score/src/corerwlockobtainread.c @@ -93,7 +93,7 @@ void _CORE_RWLock_Obtain_for_reading( _Thread_queue_Enter_critical_section( &the_rwlock->Wait_queue ); executing->Wait.queue = &the_rwlock->Wait_queue; executing->Wait.id = id; - executing->Wait.option = CORE_RWLOCK_THREAD_WAITING_FOR_WRITE; + executing->Wait.option = CORE_RWLOCK_THREAD_WAITING_FOR_READ; executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL; _ISR_Enable( level ); diff --git a/cpukit/score/src/corerwlockrelease.c b/cpukit/score/src/corerwlockrelease.c index 5943785664..30daaeaba9 100644 --- a/cpukit/score/src/corerwlockrelease.c +++ b/cpukit/score/src/corerwlockrelease.c @@ -39,6 +39,8 @@ CORE_RWLock_Status _CORE_RWLock_Release( { ISR_Level level; Thread_Control *executing = _Thread_Executing; + Thread_Control *next; + uint32_t rwmode; /* * If unlocked, then OK to read. @@ -64,6 +66,7 @@ CORE_RWLock_Status _CORE_RWLock_Release( executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL; break; case CORE_RWLOCK_LOCKED_FOR_WRITING: + executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL; break; } @@ -71,10 +74,37 @@ CORE_RWLock_Status _CORE_RWLock_Release( * Implicitly transition to "unlocked" and find another thread interested * in obtaining this rwlock. */ + the_rwlock->current_state = CORE_RWLOCK_UNLOCKED; + _ISR_Enable( level ); + + next = _Thread_queue_Dequeue( &the_rwlock->Wait_queue ); + + rwmode = next->Wait.option; + if ( rwmode == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE ) { + the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING; + return CORE_RWLOCK_SUCCESSFUL; + } + + /* + * Must be CORE_RWLOCK_THREAD_WAITING_FOR_READING now see if more + * readers can be let go. + */ + + while ( 1 ) { + next = _Thread_queue_First( &the_rwlock->Wait_queue ); + if ( !next ) + return CORE_RWLOCK_SUCCESSFUL; + if ( next->Wait.option != CORE_RWLOCK_THREAD_WAITING_FOR_READ ) + return CORE_RWLOCK_SUCCESSFUL; + + /* it is definitely wanting to read */ + the_rwlock->number_of_readers += 1; + _Thread_queue_Extract( &the_rwlock->Wait_queue, next ); + } + + /* XXX need to put read/write lock request indicator in Wait info */ - /* XXX find one writer or multiple readers to take off */ - _ISR_Enable( level ); return CORE_RWLOCK_SUCCESSFUL; } -- cgit v1.2.3