[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

more on light weight mutex



This is the overhead we are talking of avoiding on locking a
binary semaphore:

  the_semaphore = _Semaphore_Get( id, &location );
  switch ( location ) {
   ...
    case OBJECTS_LOCAL:
      if ( _Options_Is_no_wait( option_set ) )
        wait = FALSE;
      else
        wait = TRUE;

      if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set )
) {
        _CORE_mutex_Seize(
          &the_semaphore->Core_control.mutex,
          id,
          wait,
          timeout
        );
        _Thread_Enable_dispatch();
        return _Semaphore_Translate_core_mutex_return_code(
                  _Thread_Executing->Wait.return_code );

We could avoid the _Semaphore_Get, switch, _Options_Is_no_wait, and
_Attributes_Is_binary_semaphore, and
_Semaphore_Translate_core_mutex_return_code.  I don't know how much it
will save but it has to be non-zero. :)

I would propose 3 lightweight wrappers for:

  + obtain, block forever
  + obtain, timeout
  + obtain, poll

The resulting code for the obtains would be something like this with the
appropriate arguments passed in for wait and timeout.

_Thread_Disable_dispatch();
  _CORE_mutex_Seize(
    &the_semaphore->mutex,
    id,                    /* of object we are waiting on */ 
    wait,                  /* TRUE if blocking, FALSE otherwise */
    timeout                /* number of ticks */
  );
_Thread_Enable_dispatch();
return _Thread_Executing->Wait.return_code;

forever: wait=TRUE,  timeout=0
timeout: wait=TRUE,  timeout=non-zero
poll:    wait=FALSE, timeout=don't care

We may still need to put them in an object information table to make
something work but at first glance I don't see it being necessary.  The
"id" argument to _CORE_mutex_Seize is for the id of an object you are
waiting on. I will have to investigate to make sure about the requirement
for this information.

Release similarly saves a _Semaphore_Get, switch,
_Attributes_Is_binary_semaphore, and
_Semaphore_Translate_core_mutex_return_code.

The same logic can be applied to both binary and counting semaphores.

These light-weight semaphores would be appropriate to protect the
SuperCore Heap in the RTEMS malloc implementation and could be used to
bypass the region there.  Eliminating the region will save
(36+37+168+333+147+249) = 970 bytes on the i386ex.  I think all of this is
forced in all of the time. But we may pick up some overhead for using the
Heap and a "light weight mutex"

If all uses of the semaphore manager were eliminated in support
components, then we have the maximum potential to get rid of
(33+455+208+186+159)=1041 bytes.  

So conservatively, say 50% of that or about 1K smaller for a minimum
application -- which is now around 60K on the sparc/erc32.

--joel