Changeset 0b590858 in rtems


Ignore:
Timestamp:
Apr 20, 2016, 4:59:16 AM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
ba5ef37
Parents:
b466226
git-author:
Sebastian Huber <sebastian.huber@…> (04/20/16 04:59:16)
git-committer:
Sebastian Huber <sebastian.huber@…> (04/22/16 07:25:09)
Message:

score: Use _Thread_queue_Flush_critical for futex

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/src/futex.c

    rb466226 r0b590858  
    11/*
    2  * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2015, 2016 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    104104}
    105105
    106 /*
    107  * Use a noinline function to force the compiler to set up and tear down the
    108  * large stack frame only in the slow case.
    109  */
    110 static __attribute__((noinline)) int _Futex_Wake_slow(
    111   Futex_Control      *futex,
    112   int                 count,
    113   Thread_queue_Heads *heads,
     106typedef struct {
     107  ISR_lock_Context Base;
     108  int              count;
     109} Futex_Lock_context;
     110
     111static Thread_Control *_Futex_Flush_filter(
     112  Thread_Control     *the_thread,
     113  Thread_queue_Queue *queue,
    114114  ISR_lock_Context   *lock_context
    115115)
    116116{
    117   Chain_Control  unblock;
    118   Chain_Node    *node;
    119   Chain_Node    *tail;
    120   int            woken;
     117  Futex_Lock_context *futex_lock_context;
    121118
    122   woken = 0;
    123   _Chain_Initialize_empty( &unblock );
     119  futex_lock_context = (Futex_Lock_context *) lock_context;
    124120
    125   while ( count > 0 && heads != NULL ) {
    126     const Thread_queue_Operations *operations;
    127     Thread_Control                *first;
    128     bool                           do_unblock;
    129 
    130     operations = FUTEX_TQ_OPERATIONS;
    131     first = ( *operations->first )( heads );
    132 
    133     do_unblock = _Thread_queue_Extract_locked(
    134       &futex->Queue.Queue,
    135       operations,
    136       first,
    137       NULL,
    138       0
    139     );
    140     if (do_unblock) {
    141       _Chain_Append_unprotected( &unblock, &first->Wait.Node.Chain );
    142     }
    143 
    144     ++woken;
    145     --count;
    146     heads = futex->Queue.Queue.heads;
     121  if ( futex_lock_context->count <= 0 ) {
     122    return NULL;
    147123  }
    148124
    149   node = _Chain_First( &unblock );
    150   tail = _Chain_Tail( &unblock );
     125  --futex_lock_context->count;
    151126
    152   if ( node != tail ) {
    153     Per_CPU_Control *cpu_self;
    154 
    155     cpu_self = _Thread_Dispatch_disable_critical( lock_context );
    156     _Futex_Queue_release( futex, lock_context );
    157 
    158     do {
    159       Thread_Control *thread;
    160       Chain_Node     *next;
    161 
    162       next = _Chain_Next( node );
    163       thread = THREAD_CHAIN_NODE_TO_THREAD( node );
    164       _Thread_Unblock( thread );
    165 
    166       node = next;
    167     } while ( node != tail );
    168 
    169     _Thread_Dispatch_enable( cpu_self );
    170   } else {
    171     _Futex_Queue_release( futex, lock_context );
    172   }
    173 
    174   return woken;
     127  return the_thread;
    175128}
    176129
     
    178131{
    179132  Futex_Control      *futex;
    180   ISR_lock_Context    lock_context;
    181   Thread_queue_Heads *heads;
     133  Futex_Lock_context  lock_context;
    182134
    183135  futex = _Futex_Get( _futex );
    184   _Futex_Queue_acquire( futex, &lock_context );
     136  _Futex_Queue_acquire( futex, &lock_context.Base );
    185137
    186138  /*
     
    189141   * check this condition early.
    190142   */
    191   heads = futex->Queue.Queue.heads;
    192   if ( __predict_true( heads == NULL ) ) {
    193     _Futex_Queue_release( futex, &lock_context );
    194 
     143  if ( __predict_true( _Thread_queue_Is_empty( &futex->Queue.Queue ) ) ) {
     144    _Futex_Queue_release( futex, &lock_context.Base );
    195145    return 0;
    196146  }
    197147
    198   return _Futex_Wake_slow( futex, count, heads, &lock_context );
     148  lock_context.count = count;
     149  return (int) _Thread_queue_Flush_critical(
     150    &futex->Queue.Queue,
     151    FUTEX_TQ_OPERATIONS,
     152    _Futex_Flush_filter,
     153    NULL,
     154    0,
     155    &lock_context.Base
     156  );
    199157}
    200158
Note: See TracChangeset for help on using the changeset viewer.