Changeset cc18d7b in rtems


Ignore:
Timestamp:
Apr 30, 2015, 11:12:54 AM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
e76c517
Parents:
c654b525
git-author:
Sebastian Huber <sebastian.huber@…> (04/30/15 11:12:54)
git-committer:
Sebastian Huber <sebastian.huber@…> (05/19/15 10:00:46)
Message:

score: Fine grained locking for message queues

Aggregate several critical sections into a bigger one. Sending and
receiving messages is now protected by an ISR lock. Thread dispatching
is only disabled in case a blocking operation is necessary. The message
copy procedure is done inside the critical section (interrupts
disabled). Thus this change may have a negative impact on the interrupt
latency in case very large messages are transferred.

Update #2273.

Files:
17 edited

Legend:

Unmodified
Added
Removed
  • cpukit/posix/include/rtems/posix/mqueueimpl.h

    rc654b525 rcc18d7b  
    251251  );
    252252}
     253
     254RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control_fd *
     255_POSIX_Message_queue_Get_fd_interrupt_disable(
     256  mqd_t              id,
     257  Objects_Locations *location,
     258  ISR_lock_Context  *lock_context
     259)
     260{
     261  return (POSIX_Message_queue_Control_fd *) _Objects_Get_isr_disable(
     262    &_POSIX_Message_queue_Information_fds,
     263    (Objects_Id)id,
     264    location,
     265    lock_context
     266  );
     267}
    253268 
    254269/**
  • cpukit/posix/src/mqueuerecvsupp.c

    rc654b525 rcc18d7b  
    5555  bool                             do_wait;
    5656  Thread_Control                  *executing;
     57  ISR_lock_Context                 lock_context;
    5758
    58   the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
     59  the_mq_fd = _POSIX_Message_queue_Get_fd_interrupt_disable(
     60    mqdes,
     61    &location,
     62    &lock_context
     63  );
    5964  switch ( location ) {
    6065
    6166    case OBJECTS_LOCAL:
    6267      if ( (the_mq_fd->oflag & O_ACCMODE) == O_WRONLY ) {
    63         _Objects_Put( &the_mq_fd->Object );
     68        _ISR_lock_ISR_enable( &lock_context );
    6469        rtems_set_errno_and_return_minus_one( EBADF );
    6570      }
     
    6873
    6974      if ( msg_len < the_mq->Message_queue.maximum_message_size ) {
    70         _Objects_Put( &the_mq_fd->Object );
     75        _ISR_lock_ISR_enable( &lock_context );
    7176        rtems_set_errno_and_return_minus_one( EMSGSIZE );
    7277      }
     
    98103        &length_out,
    99104        do_wait,
    100         timeout
     105        timeout,
     106        &lock_context
    101107      );
    102108
    103       _Objects_Put( &the_mq_fd->Object );
    104109      if (msg_prio) {
    105110        *msg_prio = _POSIX_Message_queue_Priority_from_core(
  • cpukit/posix/src/mqueuesendsupp.c

    rc654b525 rcc18d7b  
    6565  bool                            do_wait;
    6666  Thread_Control                 *executing;
     67  ISR_lock_Context                lock_context;
    6768
    6869  /*
     
    7475    rtems_set_errno_and_return_minus_one( EINVAL );
    7576
    76   the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
     77  the_mq_fd = _POSIX_Message_queue_Get_fd_interrupt_disable(
     78    mqdes,
     79    &location,
     80    &lock_context
     81  );
    7782  switch ( location ) {
    7883
    7984    case OBJECTS_LOCAL:
    8085      if ( (the_mq_fd->oflag & O_ACCMODE) == O_RDONLY ) {
    81         _Objects_Put( &the_mq_fd->Object );
     86        _ISR_lock_ISR_enable( &lock_context );
    8287        rtems_set_errno_and_return_minus_one( EBADF );
    8388      }
     
    106111        _POSIX_Message_queue_Priority_to_core( msg_prio ),
    107112        do_wait,
    108         timeout    /* no timeout */
     113        timeout,   /* no timeout */
     114        &lock_context
    109115      );
    110 
    111       _Objects_Put( &the_mq_fd->Object );
    112116
    113117      /*
  • cpukit/rtems/include/rtems/rtems/messageimpl.h

    rc654b525 rcc18d7b  
    140140}
    141141
     142RTEMS_INLINE_ROUTINE Message_queue_Control *
     143_Message_queue_Get_interrupt_disable(
     144  Objects_Id         id,
     145  Objects_Locations *location,
     146  ISR_lock_Context  *lock_context
     147)
     148{
     149  return (Message_queue_Control *) _Objects_Get_isr_disable(
     150    &_Message_queue_Information,
     151    id,
     152    location,
     153    lock_context
     154  );
     155}
     156
    142157RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Allocate( void )
    143158{
  • cpukit/rtems/src/msgqbroadcast.c

    rc654b525 rcc18d7b  
    4141  Objects_Locations               location;
    4242  CORE_message_queue_Status       core_status;
     43  ISR_lock_Context                lock_context;
    4344
    4445  if ( !buffer )
     
    4849    return RTEMS_INVALID_ADDRESS;
    4950
    50   the_message_queue = _Message_queue_Get( id, &location );
     51  the_message_queue = _Message_queue_Get_interrupt_disable(
     52    id,
     53    &location,
     54    &lock_context
     55  );
    5156  switch ( location ) {
    5257
     
    6267                        NULL,
    6368                      #endif
    64                       count
     69                      count,
     70                      &lock_context
    6571                    );
    66 
    67       _Objects_Put( &the_message_queue->Object );
    6872      return
    6973        _Message_queue_Translate_core_message_queue_return_code( core_status );
  • cpukit/rtems/src/msgqflush.c

    rc654b525 rcc18d7b  
    5555  Message_queue_Control          *the_message_queue;
    5656  Objects_Locations               location;
     57  ISR_lock_Context                lock_context;
    5758
    5859  if ( !count )
    5960    return RTEMS_INVALID_ADDRESS;
    6061
    61   the_message_queue = _Message_queue_Get( id, &location );
     62  the_message_queue = _Message_queue_Get_interrupt_disable(
     63    id,
     64    &location,
     65    &lock_context
     66  );
    6267  switch ( location ) {
    6368
    6469    case OBJECTS_LOCAL:
    65       *count = _CORE_message_queue_Flush( &the_message_queue->message_queue );
    66       _Objects_Put( &the_message_queue->Object );
     70      *count = _CORE_message_queue_Flush(
     71        &the_message_queue->message_queue,
     72        &lock_context
     73      );
    6774      return RTEMS_SUCCESSFUL;
    6875
  • cpukit/rtems/src/msgqreceive.c

    rc654b525 rcc18d7b  
    4343  bool                            wait;
    4444  Thread_Control                 *executing;
     45  ISR_lock_Context                lock_context;
    4546
    4647  if ( !buffer )
     
    5051    return RTEMS_INVALID_ADDRESS;
    5152
    52   the_message_queue = _Message_queue_Get( id, &location );
     53  the_message_queue = _Message_queue_Get_interrupt_disable(
     54    id,
     55    &location,
     56    &lock_context
     57  );
    5358  switch ( location ) {
    5459
     
    6772        size,
    6873        wait,
    69         timeout
     74        timeout,
     75        &lock_context
    7076      );
    71       _Objects_Put( &the_message_queue->Object );
    7277      return _Message_queue_Translate_core_message_queue_return_code(
    7378        executing->Wait.return_code
  • cpukit/rtems/src/msgqsend.c

    rc654b525 rcc18d7b  
    6363  Objects_Locations                location;
    6464  CORE_message_queue_Status        status;
     65  ISR_lock_Context                 lock_context;
    6566
    6667  if ( !buffer )
    6768    return RTEMS_INVALID_ADDRESS;
    6869
    69   the_message_queue = _Message_queue_Get( id, &location );
     70  the_message_queue = _Message_queue_Get_interrupt_disable(
     71    id,
     72    &location,
     73    &lock_context
     74  );
    7075  switch ( location ) {
    7176
     
    7883        MESSAGE_QUEUE_MP_HANDLER,
    7984        false,   /* sender does not block */
    80         0        /* no timeout */
     85        0,       /* no timeout */
     86        &lock_context
    8187      );
    82 
    83       _Objects_Put( &the_message_queue->Object );
    8488
    8589      /*
  • cpukit/rtems/src/msgqurgent.c

    rc654b525 rcc18d7b  
    4646  Objects_Locations                location;
    4747  CORE_message_queue_Status        status;
     48  ISR_lock_Context                 lock_context;
    4849
    4950  if ( !buffer )
    5051    return RTEMS_INVALID_ADDRESS;
    5152
    52   the_message_queue = _Message_queue_Get( id, &location );
     53  the_message_queue = _Message_queue_Get_interrupt_disable(
     54    id,
     55    &location,
     56    &lock_context
     57  );
    5358  switch ( location ) {
    5459
     
    6166        MESSAGE_QUEUE_MP_HANDLER,
    6267        false,   /* sender does not block */
    63         0        /* no timeout */
     68        0,       /* no timeout */
     69        &lock_context
    6470      );
    65       _Objects_Put( &the_message_queue->Object );
    6671
    6772      /*
  • cpukit/score/include/rtems/score/coremsgimpl.h

    rc654b525 rcc18d7b  
    2222#include <rtems/score/coremsg.h>
    2323#include <rtems/score/chainimpl.h>
     24#include <rtems/score/threaddispatch.h>
    2425#include <rtems/score/threadqimpl.h>
    2526
     
    173174 *
    174175 *  @param[in] the_message_queue points to the message queue to flush
     176 *  @param[in] lock_context The lock context of the interrupt disable.
    175177 *
    176178 *  @retval This method returns the number of message pending messages flushed.
    177179 */
    178180uint32_t   _CORE_message_queue_Flush(
    179   CORE_message_queue_Control *the_message_queue
     181  CORE_message_queue_Control *the_message_queue,
     182  ISR_lock_Context           *lock_context
    180183);
    181184
     
    216219 *  @param[out] count points to the variable that will contain the
    217220 *         number of tasks that are sent this message
     221 *  @param[in] lock_context The lock context of the interrupt disable.
    218222 *  @retval @a *count will contain the number of messages sent
    219223 *  @retval indication of the successful completion or reason for failure
     
    225229  Objects_Id                                 id,
    226230  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
    227   uint32_t                                  *count
     231  uint32_t                                  *count,
     232  ISR_lock_Context                          *lock_context
    228233);
    229234
     
    251256 *  @param[in] timeout is the maximum number of clock ticks that the calling
    252257 *         thread is willing to block if the message queue is full.
     258 *  @param[in] lock_context The lock context of the interrupt disable.
    253259 *  @retval indication of the successful completion or reason for failure
    254260 */
     
    262268  CORE_message_queue_Submit_types            submit_type,
    263269  bool                                       wait,
    264   Watchdog_Interval                          timeout
     270  Watchdog_Interval                          timeout,
     271  ISR_lock_Context                          *lock_context
    265272);
    266273
     
    288295 *  @param[in] timeout is the maximum number of clock ticks that the calling
    289296 *         thread is willing to block if the message queue is empty.
     297 *  @param[in] lock_context The lock context of the interrupt disable.
    290298 *
    291299 *  @retval indication of the successful completion or reason for failure.
     
    306314  size_t                          *size_p,
    307315  bool                             wait,
    308   Watchdog_Interval                timeout
     316  Watchdog_Interval                timeout,
     317  ISR_lock_Context                *lock_context
    309318);
    310319
     
    339348  Objects_Id                                 id,
    340349  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
    341   bool                                    wait,
    342   Watchdog_Interval                          timeout
     350  bool                                       wait,
     351  Watchdog_Interval                          timeout,
     352  ISR_lock_Context                          *lock_context
    343353)
    344354{
     
    352362    CORE_MESSAGE_QUEUE_SEND_REQUEST,
    353363    wait,     /* sender may block */
    354     timeout   /* timeout interval */
     364    timeout,  /* timeout interval */
     365    lock_context
    355366  );
    356367}
     
    365376  Objects_Id                                 id,
    366377  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
    367   bool                                    wait,
    368   Watchdog_Interval                          timeout
     378  bool                                       wait,
     379  Watchdog_Interval                          timeout,
     380  ISR_lock_Context                          *lock_context
    369381)
    370382{
     
    378390    CORE_MESSAGE_QUEUE_URGENT_REQUEST,
    379391    wait,     /* sender may block */
    380     timeout   /* timeout interval */
     392    timeout,  /* timeout interval */
     393    lock_context
    381394 );
     395}
     396
     397RTEMS_INLINE_ROUTINE void _CORE_message_queue_Acquire(
     398  CORE_message_queue_Control *the_message_queue,
     399  ISR_lock_Context           *lock_context
     400)
     401{
     402  _Thread_queue_Acquire( &the_message_queue->Wait_queue, lock_context );
     403}
     404
     405RTEMS_INLINE_ROUTINE void _CORE_message_queue_Acquire_critical(
     406  CORE_message_queue_Control *the_message_queue,
     407  ISR_lock_Context           *lock_context
     408)
     409{
     410  _Thread_queue_Acquire_critical( &the_message_queue->Wait_queue, lock_context );
     411
     412  #if defined(RTEMS_MULTIPROCESSING)
     413    /*
     414     * In case RTEMS_MULTIPROCESSING is enabled, then we have to prevent
     415     * deletion of the executing thread after the thread queue operations.
     416     */
     417    _Thread_Dispatch_disable();
     418  #endif
     419}
     420
     421RTEMS_INLINE_ROUTINE void _CORE_message_queue_Release(
     422  CORE_message_queue_Control *the_message_queue,
     423  ISR_lock_Context           *lock_context
     424)
     425{
     426  _Thread_queue_Release( &the_message_queue->Wait_queue, lock_context );
     427  #if defined(RTEMS_MULTIPROCESSING)
     428    _Thread_Dispatch_enable( _Per_CPU_Get() );
     429  #endif
    382430}
    383431
     
    405453{
    406454   return (CORE_message_queue_Buffer_control *)
    407      _Chain_Get( &the_message_queue->Inactive_messages );
     455     _Chain_Get_unprotected( &the_message_queue->Inactive_messages );
    408456}
    409457
     
    417465)
    418466{
    419   _Chain_Append( &the_message_queue->Inactive_messages, &the_message->Node );
     467  _Chain_Append_unprotected( &the_message_queue->Inactive_messages, &the_message->Node );
    420468}
    421469
     
    511559#endif
    512560
     561RTEMS_INLINE_ROUTINE Thread_Control *_CORE_message_queue_Dequeue_receiver(
     562  CORE_message_queue_Control      *the_message_queue,
     563  const void                      *buffer,
     564  size_t                           size,
     565  CORE_message_queue_Submit_types  submit_type,
     566  ISR_lock_Context                *lock_context
     567)
     568{
     569  Thread_Control *the_thread;
     570
     571  /*
     572   *  If there are pending messages, then there can't be threads
     573   *  waiting for us to send them a message.
     574   *
     575   *  NOTE: This check is critical because threads can block on
     576   *        send and receive and this ensures that we are broadcasting
     577   *        the message to threads waiting to receive -- not to send.
     578   */
     579  if ( the_message_queue->number_of_pending_messages != 0 ) {
     580    return NULL;
     581  }
     582
     583  /*
     584   *  There must be no pending messages if there is a thread waiting to
     585   *  receive a message.
     586   */
     587  the_thread = _Thread_queue_First_locked( &the_message_queue->Wait_queue );
     588  if ( the_thread == NULL ) {
     589    return NULL;
     590  }
     591
     592   *(size_t *) the_thread->Wait.return_argument = size;
     593   the_thread->Wait.count = (uint32_t) submit_type;
     594
     595  _CORE_message_queue_Copy_buffer(
     596    buffer,
     597    the_thread->Wait.return_argument_second.mutable_object,
     598    size
     599  );
     600
     601  _Thread_queue_Extract_critical(
     602    &the_message_queue->Wait_queue,
     603    the_thread,
     604    lock_context
     605  );
     606
     607  return the_thread;
     608}
     609
    513610/** @} */
    514611
  • cpukit/score/src/coremsgbroadcast.c

    rc654b525 rcc18d7b  
    2121#include <rtems/score/coremsgimpl.h>
    2222#include <rtems/score/objectimpl.h>
    23 #include <rtems/score/thread.h>
    2423
    2524CORE_message_queue_Status _CORE_message_queue_Broadcast(
     
    3433    CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support __attribute__((unused)),
    3534  #endif
    36   uint32_t                                  *count
     35  uint32_t                                  *count,
     36  ISR_lock_Context                          *lock_context
    3737)
    3838{
    39   Thread_Control          *the_thread;
    40   uint32_t                 number_broadcasted;
    41   Thread_Wait_information *waitp;
     39  Thread_Control             *the_thread;
     40  uint32_t                    number_broadcasted;
    4241
    4342  if ( size > the_message_queue->maximum_message_size ) {
     43    _ISR_lock_ISR_enable( lock_context );
    4444    return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
    4545  }
    4646
    47   /*
    48    *  If there are pending messages, then there can't be threads
    49    *  waiting for us to send them a message.
    50    *
    51    *  NOTE: This check is critical because threads can block on
    52    *        send and receive and this ensures that we are broadcasting
    53    *        the message to threads waiting to receive -- not to send.
    54    */
     47  number_broadcasted = 0;
    5548
    56   if ( the_message_queue->number_of_pending_messages != 0 ) {
    57     *count = 0;
    58     return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
     49  _CORE_message_queue_Acquire_critical( the_message_queue, lock_context );
     50
     51  while (
     52    ( the_thread =
     53      _CORE_message_queue_Dequeue_receiver(
     54        the_message_queue,
     55        buffer,
     56        size,
     57        0,
     58        lock_context
     59      )
     60    )
     61  ) {
     62    number_broadcasted += 1;
     63
     64#if defined(RTEMS_MULTIPROCESSING)
     65    if ( !_Objects_Is_local_id( the_thread->Object.id ) )
     66      (*api_message_queue_mp_support) ( the_thread, id );
     67#endif
     68
     69    _CORE_message_queue_Acquire( the_message_queue, lock_context );
    5970  }
    6071
    61   /*
    62    *  There must be no pending messages if there is a thread waiting to
    63    *  receive a message.
    64    */
    65   number_broadcasted = 0;
    66   while ((the_thread =
    67           _Thread_queue_Dequeue(&the_message_queue->Wait_queue))) {
    68     waitp = &the_thread->Wait;
    69     number_broadcasted += 1;
     72  _CORE_message_queue_Release( the_message_queue, lock_context );
    7073
    71     _CORE_message_queue_Copy_buffer(
    72       buffer,
    73       waitp->return_argument_second.mutable_object,
    74       size
    75     );
    76 
    77     *(size_t *) the_thread->Wait.return_argument = size;
    78 
    79     #if defined(RTEMS_MULTIPROCESSING)
    80       if ( !_Objects_Is_local_id( the_thread->Object.id ) )
    81         (*api_message_queue_mp_support) ( the_thread, id );
    82     #endif
    83 
    84   }
    8574  *count = number_broadcasted;
    8675  return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
  • cpukit/score/src/coremsgclose.c

    rc654b525 rcc18d7b  
    1919#endif
    2020
    21 #include <rtems/system.h>
    22 #include <rtems/score/chain.h>
    23 #include <rtems/score/isr.h>
    2421#include <rtems/score/coremsgimpl.h>
    25 #include <rtems/score/thread.h>
    2622#include <rtems/score/wkspace.h>
    2723
     
    3228)
    3329{
     30  ISR_lock_Context lock_context;
    3431
    3532  /*
     
    5047   */
    5148
    52   (void) _CORE_message_queue_Flush( the_message_queue );
     49  _ISR_lock_ISR_disable( &lock_context );
     50  (void) _CORE_message_queue_Flush( the_message_queue, &lock_context );
    5351
    5452  (void) _Workspace_Free( the_message_queue->message_buffers );
  • cpukit/score/src/coremsgflush.c

    rc654b525 rcc18d7b  
    2121
    2222#include <rtems/score/coremsgimpl.h>
    23 #include <rtems/score/isr.h>
    2423
    2524uint32_t   _CORE_message_queue_Flush(
    26   CORE_message_queue_Control *the_message_queue
     25  CORE_message_queue_Control *the_message_queue,
     26  ISR_lock_Context           *lock_context
    2727)
    2828{
    29   ISR_Level   level;
    3029  Chain_Node *inactive_head;
    3130  Chain_Node *inactive_first;
     
    6160   */
    6261
    63   _ISR_Disable( level );
     62  _CORE_message_queue_Acquire_critical( the_message_queue, lock_context );
    6463
    6564  count = the_message_queue->number_of_pending_messages;
     
    8079  }
    8180
    82   _ISR_Enable( level );
     81  _CORE_message_queue_Release( the_message_queue, lock_context );
    8382  return count;
    8483}
  • cpukit/score/src/coremsginsert.c

    rc654b525 rcc18d7b  
    2020
    2121#include <rtems/score/coremsgimpl.h>
    22 #include <rtems/score/isrlevel.h>
    2322
    2423#if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
     
    4645{
    4746  Chain_Control *pending_messages;
    48   ISR_Level      level;
    4947#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
    5048  bool           notify;
     
    5351  _CORE_message_queue_Set_message_priority( the_message, submit_type );
    5452  pending_messages = &the_message_queue->Pending_messages;
    55 
    56   _ISR_Disable( level );
    5753
    5854#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
     
    7571  }
    7672
    77   _ISR_Enable( level );
    78 
    7973  #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
    8074    /*
  • cpukit/score/src/coremsgseize.c

    rc654b525 rcc18d7b  
    3434  size_t                          *size_p,
    3535  bool                             wait,
    36   Watchdog_Interval                timeout
     36  Watchdog_Interval                timeout,
     37  ISR_lock_Context                *lock_context
    3738)
    3839{
    39   ISR_lock_Context                   lock_context;
    4040  CORE_message_queue_Buffer_control *the_message;
    4141
    4242  executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
    43   _Thread_queue_Acquire( &the_message_queue->Wait_queue, &lock_context );
     43  _CORE_message_queue_Acquire_critical( the_message_queue, lock_context );
    4444  the_message = _CORE_message_queue_Get_pending_message( the_message_queue );
    4545  if ( the_message != NULL ) {
    4646    the_message_queue->number_of_pending_messages -= 1;
    47     _Thread_queue_Release( &the_message_queue->Wait_queue, &lock_context );
    4847
    4948    *size_p = the_message->Contents.size;
     
    6261       */
    6362      _CORE_message_queue_Free_message_buffer(the_message_queue, the_message);
     63      _CORE_message_queue_Release( the_message_queue, lock_context );
    6464      return;
    6565    #else
     
    7474       *  then we can avoid this dequeue.
    7575       */
    76       the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
    77       if ( !the_thread ) {
     76      the_thread = _Thread_queue_First_locked(
     77        &the_message_queue->Wait_queue
     78      );
     79      if ( the_thread == NULL ) {
    7880        _CORE_message_queue_Free_message_buffer(
    7981          the_message_queue,
    8082          the_message
    8183        );
     84        _CORE_message_queue_Release( the_message_queue, lock_context );
    8285        return;
    8386      }
     
    104107         _CORE_message_queue_Get_message_priority( the_message )
    105108      );
     109      _Thread_queue_Extract_critical(
     110        &the_message_queue->Wait_queue,
     111        the_thread,
     112        lock_context
     113      );
     114      #if defined(RTEMS_MULTIPROCESSING)
     115        _Thread_Dispatch_enable( _Per_CPU_Get() );
     116      #endif
    106117      return;
    107118    }
     
    110121
    111122  if ( !wait ) {
    112     _Thread_queue_Release( &the_message_queue->Wait_queue, &lock_context );
     123    _CORE_message_queue_Release( the_message_queue, lock_context );
    113124    executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT;
    114125    return;
     
    126137    timeout,
    127138    CORE_MESSAGE_QUEUE_STATUS_TIMEOUT,
    128     &lock_context
     139    lock_context
    129140  );
     141  #if defined(RTEMS_MULTIPROCESSING)
     142    _Thread_Dispatch_enable( _Per_CPU_Get() );
     143  #endif
    130144}
  • cpukit/score/src/coremsgsubmit.c

    rc654b525 rcc18d7b  
    3939  CORE_message_queue_Submit_types            submit_type,
    4040  bool                                       wait,
    41   Watchdog_Interval                          timeout
     41  Watchdog_Interval                          timeout,
     42  ISR_lock_Context                          *lock_context
    4243)
    4344{
    44   CORE_message_queue_Buffer_control   *the_message;
    45   Thread_Control                      *the_thread;
     45  CORE_message_queue_Buffer_control *the_message;
     46  Thread_Control                    *the_thread;
    4647
    4748  if ( size > the_message_queue->maximum_message_size ) {
     49    _ISR_lock_ISR_enable( lock_context );
    4850    return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
    4951  }
     52
     53  _CORE_message_queue_Acquire_critical( the_message_queue, lock_context );
    5054
    5155  /*
    5256   *  Is there a thread currently waiting on this message queue?
    5357   */
    54   if ( the_message_queue->number_of_pending_messages == 0 ) {
    55     the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
    56     if ( the_thread ) {
    57       _CORE_message_queue_Copy_buffer(
    58         buffer,
    59         the_thread->Wait.return_argument_second.mutable_object,
    60         size
    61       );
    62       *(size_t *) the_thread->Wait.return_argument = size;
    63       the_thread->Wait.count = (uint32_t) submit_type;
    6458
    65       #if defined(RTEMS_MULTIPROCESSING)
    66         if ( !_Objects_Is_local_id( the_thread->Object.id ) )
    67           (*api_message_queue_mp_support) ( the_thread, id );
    68       #endif
    69       return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
    70     }
     59  the_thread = _CORE_message_queue_Dequeue_receiver(
     60    the_message_queue,
     61    buffer,
     62    size,
     63    submit_type,
     64    lock_context
     65  );
     66  if ( the_thread != NULL ) {
     67    #if defined(RTEMS_MULTIPROCESSING)
     68      if ( !_Objects_Is_local_id( the_thread->Object.id ) )
     69        (*api_message_queue_mp_support) ( the_thread, id );
     70
     71      _Thread_Dispatch_enable( _Per_CPU_Get() );
     72    #endif
     73    return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
    7174  }
    7275
     
    7881      _CORE_message_queue_Allocate_message_buffer( the_message_queue );
    7982  if ( the_message ) {
     83    the_message->Contents.size = size;
     84    _CORE_message_queue_Set_message_priority( the_message, submit_type );
    8085    _CORE_message_queue_Copy_buffer(
    8186      buffer,
     
    8388      size
    8489    );
    85     the_message->Contents.size = size;
    86     _CORE_message_queue_Set_message_priority( the_message, submit_type );
    8790
    8891    _CORE_message_queue_Insert_message(
     
    9194       submit_type
    9295    );
     96    _CORE_message_queue_Release( the_message_queue, lock_context );
    9397    return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
    9498  }
    9599
    96100  #if !defined(RTEMS_SCORE_COREMSG_ENABLE_BLOCKING_SEND)
     101    _CORE_message_queue_Release( the_message_queue, lock_context );
    97102    return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
    98103  #else
     
    103108     */
    104109    if ( !wait ) {
     110      _CORE_message_queue_Release( the_message_queue, lock_context );
    105111      return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
    106112    }
     
    111117     */
    112118    if ( _ISR_Is_in_progress() ) {
     119      _CORE_message_queue_Release( the_message_queue, lock_context );
    113120      return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
    114121    }
     
    120127     *  would be to use this variable prior to here.
    121128     */
    122     {
    123       executing->Wait.id = id;
    124       executing->Wait.return_argument_second.immutable_object = buffer;
    125       executing->Wait.option = (uint32_t) size;
    126       executing->Wait.count = submit_type;
     129    executing->Wait.id = id;
     130    executing->Wait.return_argument_second.immutable_object = buffer;
     131    executing->Wait.option = (uint32_t) size;
     132    executing->Wait.count = submit_type;
    127133
    128       _Thread_queue_Enqueue(
    129         &the_message_queue->Wait_queue,
    130         executing,
    131         STATES_WAITING_FOR_MESSAGE,
    132         timeout,
    133         CORE_MESSAGE_QUEUE_STATUS_TIMEOUT
    134       );
    135     }
     134    _Thread_queue_Enqueue_critical(
     135      &the_message_queue->Wait_queue,
     136      executing,
     137      STATES_WAITING_FOR_MESSAGE,
     138      timeout,
     139      CORE_MESSAGE_QUEUE_STATUS_TIMEOUT,
     140      lock_context
     141    );
     142    #if defined(RTEMS_MULTIPROCESSING)
     143      _Thread_Dispatch_enable( _Per_CPU_Get() );
     144    #endif
    136145
    137146    return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT;
  • doc/user/msg.t

    rc654b525 rcc18d7b  
    5151
    5252The maximum length message which can be sent is set
    53 on a per message queue basis.
     53on a per message queue basis.  The message content must be copied in general
     54to/from an internal buffer of the message queue or directly to a peer in
     55certain cases.  This copy operation is performed with interrupts disabled.  So
     56it is advisable to keep the messages as short as possible.
    5457
    5558@subsection Building a Message Queue Attribute Set
Note: See TracChangeset for help on using the changeset viewer.