[PATCH 08/12] rtems: Add and use _Region_Get_and_lock()

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Apr 8 06:49:23 UTC 2016


Get region and lock allocator in _Region_Get_and_lock() in case the
region exists and unlock it in _Region_Unlock().
---
 cpukit/rtems/include/rtems/rtems/regionimpl.h | 24 +++++--
 cpukit/rtems/src/regiondelete.c               | 27 ++++----
 cpukit/rtems/src/regionextend.c               | 40 ++++++-----
 cpukit/rtems/src/regiongetfreeinfo.c          | 22 +++---
 cpukit/rtems/src/regiongetinfo.c              | 20 +++---
 cpukit/rtems/src/regiongetsegment.c           | 96 +++++++++++++--------------
 cpukit/rtems/src/regiongetsegmentsize.c       | 18 +++--
 cpukit/rtems/src/regionprocessqueue.c         |  2 +-
 cpukit/rtems/src/regionresizesegment.c        | 50 +++++++-------
 cpukit/rtems/src/regionreturnsegment.c        | 29 ++++----
 10 files changed, 161 insertions(+), 167 deletions(-)

diff --git a/cpukit/rtems/include/rtems/rtems/regionimpl.h b/cpukit/rtems/include/rtems/rtems/regionimpl.h
index 60cf50c..4db6599 100644
--- a/cpukit/rtems/include/rtems/rtems/regionimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/regionimpl.h
@@ -19,7 +19,6 @@
 
 #include <rtems/rtems/region.h>
 #include <rtems/score/apimutex.h>
-#include <rtems/score/assert.h>
 #include <rtems/score/heapimpl.h>
 #include <rtems/score/objectimpl.h>
 #include <rtems/score/threadqimpl.h>
@@ -67,11 +66,28 @@ RTEMS_INLINE_ROUTINE void _Region_Free (
   _Objects_Free( &_Region_Information, &the_region->Object );
 }
 
-RTEMS_INLINE_ROUTINE Region_Control *_Region_Get( Objects_Id id )
+RTEMS_INLINE_ROUTINE Region_Control *_Region_Get_and_lock( Objects_Id id )
 {
-  _Assert( _RTEMS_Allocator_is_owner() );
-  return (Region_Control *)
+  Region_Control *the_region;
+
+  _RTEMS_Lock_allocator();
+
+  the_region = (Region_Control *)
     _Objects_Get_no_protection( &_Region_Information, id );
+
+  if ( the_region != NULL ) {
+    /* Keep allocator lock */
+    return the_region;
+  }
+
+  _RTEMS_Unlock_allocator();
+  return NULL;
+}
+
+RTEMS_INLINE_ROUTINE void _Region_Unlock( Region_Control *the_region )
+{
+  (void) the_region;
+  _RTEMS_Unlock_allocator();
 }
 
 /**
diff --git a/cpukit/rtems/src/regiondelete.c b/cpukit/rtems/src/regiondelete.c
index 3927a54..7897646 100644
--- a/cpukit/rtems/src/regiondelete.c
+++ b/cpukit/rtems/src/regiondelete.c
@@ -28,23 +28,22 @@ rtems_status_code rtems_region_delete(
   Region_Control    *the_region;
 
   _Objects_Allocator_lock();
-  _RTEMS_Lock_allocator();
-
-  the_region = _Region_Get( id );
-
-  if ( the_region != NULL ) {
-    if ( the_region->number_of_used_blocks != 0 ) {
-      status = RTEMS_RESOURCE_IN_USE;
-    } else {
-      _Objects_Close( &_Region_Information, &the_region->Object );
-      _Region_Free( the_region );
-      status = RTEMS_SUCCESSFUL;
-    }
+
+  the_region = _Region_Get_and_lock( id );
+
+  if ( the_region == NULL ) {
+    return RTEMS_INVALID_ID;
+  }
+
+  if ( the_region->number_of_used_blocks != 0 ) {
+    status = RTEMS_RESOURCE_IN_USE;
   } else {
-    status = RTEMS_INVALID_ID;
+    _Objects_Close( &_Region_Information, &the_region->Object );
+    _Region_Free( the_region );
+    status = RTEMS_SUCCESSFUL;
   }
 
-  _RTEMS_Unlock_allocator();
+  _Region_Unlock( the_region );
   _Objects_Allocator_unlock();
   return status;
 }
diff --git a/cpukit/rtems/src/regionextend.c b/cpukit/rtems/src/regionextend.c
index b1df066..e6cadf8 100644
--- a/cpukit/rtems/src/regionextend.c
+++ b/cpukit/rtems/src/regionextend.c
@@ -34,29 +34,27 @@ rtems_status_code rtems_region_extend(
     return RTEMS_INVALID_ADDRESS;
   }
 
-  _RTEMS_Lock_allocator();
-
-  the_region = _Region_Get( id );
-
-  if ( the_region != NULL ) {
-    amount_extended = _Heap_Extend(
-      &the_region->Memory,
-      starting_address,
-      length,
-      0
-    );
-
-    if ( amount_extended > 0 ) {
-      the_region->length               += amount_extended;
-      the_region->maximum_segment_size += amount_extended;
-      status = RTEMS_SUCCESSFUL;
-    } else {
-      status = RTEMS_INVALID_ADDRESS;
-    }
+  the_region = _Region_Get_and_lock( id );
+
+  if ( the_region == NULL ) {
+    return RTEMS_INVALID_ID;
+  }
+
+  amount_extended = _Heap_Extend(
+    &the_region->Memory,
+    starting_address,
+    length,
+    0
+  );
+
+  if ( amount_extended > 0 ) {
+    the_region->length               += amount_extended;
+    the_region->maximum_segment_size += amount_extended;
+    status = RTEMS_SUCCESSFUL;
   } else {
-    status = RTEMS_INVALID_ID;
+    status = RTEMS_INVALID_ADDRESS;
   }
 
-  _RTEMS_Unlock_allocator();
+  _Region_Unlock( the_region );
   return status;
 }
diff --git a/cpukit/rtems/src/regiongetfreeinfo.c b/cpukit/rtems/src/regiongetfreeinfo.c
index 7924c0f..c35d888 100644
--- a/cpukit/rtems/src/regiongetfreeinfo.c
+++ b/cpukit/rtems/src/regiongetfreeinfo.c
@@ -27,25 +27,21 @@ rtems_status_code rtems_region_get_free_information(
   Heap_Information_block *the_info
 )
 {
-  rtems_status_code  status;
-  Region_Control    *the_region;
+  Region_Control *the_region;
 
   if ( the_info == NULL ) {
     return RTEMS_INVALID_ADDRESS;
   }
 
-  _RTEMS_Lock_allocator();
+  the_region = _Region_Get_and_lock( id );
 
-  the_region = _Region_Get( id );
-
-  if ( the_region != NULL ) {
-    memset( &the_info->Used, 0, sizeof( the_info->Used ) );
-    _Heap_Get_free_information( &the_region->Memory, &the_info->Free );
-    status = RTEMS_SUCCESSFUL;
-  } else {
-    status = RTEMS_INVALID_ID;
+  if ( the_region == NULL ) {
+    return RTEMS_INVALID_ID;
   }
 
-  _RTEMS_Unlock_allocator();
-  return status;
+  memset( &the_info->Used, 0, sizeof( the_info->Used ) );
+  _Heap_Get_free_information( &the_region->Memory, &the_info->Free );
+
+  _Region_Unlock( the_region );
+  return RTEMS_SUCCESSFUL;
 }
diff --git a/cpukit/rtems/src/regiongetinfo.c b/cpukit/rtems/src/regiongetinfo.c
index 2ab3d40..8226dca 100644
--- a/cpukit/rtems/src/regiongetinfo.c
+++ b/cpukit/rtems/src/regiongetinfo.c
@@ -25,24 +25,20 @@ rtems_status_code rtems_region_get_information(
   Heap_Information_block *the_info
 )
 {
-  rtems_status_code  status;
-  Region_Control    *the_region;
+  Region_Control *the_region;
 
   if ( the_info == NULL ) {
     return RTEMS_INVALID_ADDRESS;
   }
 
-  _RTEMS_Lock_allocator();
+  the_region = _Region_Get_and_lock( id );
 
-  the_region = _Region_Get( id );
-
-  if ( the_region != NULL ) {
-    _Heap_Get_information( &the_region->Memory, the_info );
-    status = RTEMS_SUCCESSFUL;
-  } else {
-    status = RTEMS_INVALID_ID;
+  if ( the_region == NULL ) {
+    return RTEMS_INVALID_ID;
   }
 
-  _RTEMS_Unlock_allocator();
-  return status;
+  _Heap_Get_information( &the_region->Memory, the_info );
+
+  _Region_Unlock( the_region );
+  return RTEMS_SUCCESSFUL;
 }
diff --git a/cpukit/rtems/src/regiongetsegment.c b/cpukit/rtems/src/regiongetsegment.c
index 5a98e85..ecc6378 100644
--- a/cpukit/rtems/src/regiongetsegment.c
+++ b/cpukit/rtems/src/regiongetsegment.c
@@ -44,60 +44,58 @@ rtems_status_code rtems_region_get_segment(
     return RTEMS_INVALID_SIZE;
   }
 
-  _RTEMS_Lock_allocator();
+  the_region = _Region_Get_and_lock( id );
 
-  the_region = _Region_Get( id );
+  if ( the_region == NULL ) {
+    return RTEMS_INVALID_ID;
+  }
+
+  if ( size > the_region->maximum_segment_size ) {
+    status = RTEMS_INVALID_SIZE;
+  } else {
+    void *the_segment;
 
-  if ( the_region != NULL ) {
-    if ( size > the_region->maximum_segment_size ) {
-      status = RTEMS_INVALID_SIZE;
+    the_segment = _Region_Allocate_segment( the_region, size );
+
+    if ( the_segment != NULL ) {
+      the_region->number_of_used_blocks += 1;
+      *segment = the_segment;
+      status = RTEMS_SUCCESSFUL;
+    } else if ( _Options_Is_no_wait( option_set ) ) {
+      status = RTEMS_UNSATISFIED;
     } else {
-      void *the_segment;
-
-      the_segment = _Region_Allocate_segment( the_region, size );
-
-      if ( the_segment != NULL ) {
-        the_region->number_of_used_blocks += 1;
-        *segment = the_segment;
-        status = RTEMS_SUCCESSFUL;
-      } else if ( _Options_Is_no_wait( option_set ) ) {
-        status = RTEMS_UNSATISFIED;
-      } else {
-        Per_CPU_Control *cpu_self;
-        Thread_Control  *executing;
-
-        /*
-         *  Switch from using the memory allocation mutex to using a
-         *  dispatching disabled critical section.  We have to do this
-         *  because this thread is going to block.
-         */
-        /* FIXME: This is a home grown condition variable */
-        cpu_self = _Thread_Dispatch_disable();
-        _RTEMS_Unlock_allocator();
-
-        executing  = _Per_CPU_Get_executing( cpu_self );
-
-        executing->Wait.count           = size;
-        executing->Wait.return_argument = segment;
-
-        _Thread_queue_Enqueue(
-          &the_region->Wait_queue,
-          the_region->wait_operations,
-          executing,
-          STATES_WAITING_FOR_SEGMENT,
-          timeout,
-          RTEMS_TIMEOUT
-        );
-
-        _Thread_Dispatch_enable( cpu_self );
-
-        return (rtems_status_code) executing->Wait.return_code;
-      }
+      Per_CPU_Control *cpu_self;
+      Thread_Control  *executing;
+
+      /*
+       *  Switch from using the memory allocation mutex to using a
+       *  dispatching disabled critical section.  We have to do this
+       *  because this thread is going to block.
+       */
+      /* FIXME: This is a home grown condition variable */
+      cpu_self = _Thread_Dispatch_disable();
+      _Region_Unlock( the_region );
+
+      executing  = _Per_CPU_Get_executing( cpu_self );
+
+      executing->Wait.count           = size;
+      executing->Wait.return_argument = segment;
+
+      _Thread_queue_Enqueue(
+        &the_region->Wait_queue,
+        the_region->wait_operations,
+        executing,
+        STATES_WAITING_FOR_SEGMENT,
+        timeout,
+        RTEMS_TIMEOUT
+      );
+
+      _Thread_Dispatch_enable( cpu_self );
+
+      return (rtems_status_code) executing->Wait.return_code;
     }
-  } else {
-    status = RTEMS_INVALID_ID;
   }
 
-  _RTEMS_Unlock_allocator();
+  _Region_Unlock( the_region );
   return status;
 }
diff --git a/cpukit/rtems/src/regiongetsegmentsize.c b/cpukit/rtems/src/regiongetsegmentsize.c
index 21a2bb4..bb7481f 100644
--- a/cpukit/rtems/src/regiongetsegmentsize.c
+++ b/cpukit/rtems/src/regiongetsegmentsize.c
@@ -37,20 +37,18 @@ rtems_status_code rtems_region_get_segment_size(
     return RTEMS_INVALID_ADDRESS;
   }
 
-  _RTEMS_Lock_allocator();
+  the_region = _Region_Get_and_lock( id );
 
-  the_region = _Region_Get( id );
+  if ( the_region == NULL ) {
+    return RTEMS_INVALID_ID;
+  }
 
-  if ( the_region != NULL ) {
-    if ( _Heap_Size_of_alloc_area( &the_region->Memory, segment, size ) ) {
-      status = RTEMS_SUCCESSFUL;
-    } else {
-      status = RTEMS_INVALID_ADDRESS;
-    }
+  if ( _Heap_Size_of_alloc_area( &the_region->Memory, segment, size ) ) {
+    status = RTEMS_SUCCESSFUL;
   } else {
-    status = RTEMS_INVALID_ID;
+    status = RTEMS_INVALID_ADDRESS;
   }
 
-  _RTEMS_Unlock_allocator();
+  _Region_Unlock( the_region );
   return status;
 }
diff --git a/cpukit/rtems/src/regionprocessqueue.c b/cpukit/rtems/src/regionprocessqueue.c
index a28d68c..1c9d273 100644
--- a/cpukit/rtems/src/regionprocessqueue.c
+++ b/cpukit/rtems/src/regionprocessqueue.c
@@ -40,7 +40,7 @@ void _Region_Process_queue(
    *        switch could occur.
    */
   cpu_self = _Thread_Dispatch_disable();
-  _RTEMS_Unlock_allocator();
+  _Region_Unlock( the_region );
 
   /*
    *  NOTE: The following loop is O(n) where n is the number of
diff --git a/cpukit/rtems/src/regionresizesegment.c b/cpukit/rtems/src/regionresizesegment.c
index a21d1b9..303fce4 100644
--- a/cpukit/rtems/src/regionresizesegment.c
+++ b/cpukit/rtems/src/regionresizesegment.c
@@ -37,38 +37,36 @@ rtems_status_code rtems_region_resize_segment(
     return RTEMS_INVALID_ADDRESS;
   }
 
-  _RTEMS_Lock_allocator();
+  the_region = _Region_Get_and_lock( id );
 
-  the_region = _Region_Get( id );
+  if ( the_region == NULL ) {
+    return RTEMS_INVALID_ID;
+  }
 
-  if ( the_region != NULL ) {
-    resize_status = _Heap_Resize_block(
-      &the_region->Memory,
-      segment,
-      (uint32_t) size,
-      &osize,
-      &avail_size
-    );
-    *old_size = (uint32_t) osize;
+  resize_status = _Heap_Resize_block(
+    &the_region->Memory,
+    segment,
+    (uint32_t) size,
+    &osize,
+    &avail_size
+  );
+  *old_size = (uint32_t) osize;
 
-    switch ( resize_status ) {
-      case HEAP_RESIZE_SUCCESSFUL:
-        /* Unlocks allocator */
-        _Region_Process_queue( the_region );
-        return RTEMS_SUCCESSFUL;
+  switch ( resize_status ) {
+    case HEAP_RESIZE_SUCCESSFUL:
+      /* Unlocks allocator */
+      _Region_Process_queue( the_region );
+      return RTEMS_SUCCESSFUL;
 
-      case HEAP_RESIZE_UNSATISFIED:
-        status = RTEMS_UNSATISFIED;
-        break;
+    case HEAP_RESIZE_UNSATISFIED:
+      status = RTEMS_UNSATISFIED;
+      break;
 
-      default:
-        status = RTEMS_INVALID_ADDRESS;
-        break;
-    }
-  } else {
-    status = RTEMS_INVALID_ID;
+    default:
+      status = RTEMS_INVALID_ADDRESS;
+      break;
   }
 
-  _RTEMS_Unlock_allocator();
+  _Region_Unlock( the_region );
   return status;
 }
diff --git a/cpukit/rtems/src/regionreturnsegment.c b/cpukit/rtems/src/regionreturnsegment.c
index c7147bb..8ec84fb 100644
--- a/cpukit/rtems/src/regionreturnsegment.c
+++ b/cpukit/rtems/src/regionreturnsegment.c
@@ -25,27 +25,22 @@ rtems_status_code rtems_region_return_segment(
   void     *segment
 )
 {
-  rtems_status_code  status;
-  Region_Control    *the_region;
+  Region_Control *the_region;
 
-  _RTEMS_Lock_allocator();
+  the_region = _Region_Get_and_lock( id );
 
-  the_region = _Region_Get( id );
+  if ( the_region == NULL ) {
+    return RTEMS_INVALID_ID;
+  }
 
-  if ( the_region != NULL ) {
-     if ( _Region_Free_segment( the_region, segment ) ) {
-       the_region->number_of_used_blocks -= 1;
+  if ( _Region_Free_segment( the_region, segment ) ) {
+    the_region->number_of_used_blocks -= 1;
 
-       /* Unlocks allocator */
-       _Region_Process_queue( the_region );
-       return RTEMS_SUCCESSFUL;
-     } else {
-       status = RTEMS_INVALID_ADDRESS;
-     }
-  } else {
-    status = RTEMS_INVALID_ID;
+    /* Unlocks allocator */
+    _Region_Process_queue( the_region );
+    return RTEMS_SUCCESSFUL;
   }
 
-  _RTEMS_Unlock_allocator();
-  return status;
+  _Region_Unlock( the_region );
+  return RTEMS_INVALID_ADDRESS;
 }
-- 
1.8.4.5



More information about the devel mailing list