source: rtems/cpukit/score/src/coremsg.c @ 7e66865e

5
Last change on this file since 7e66865e was 7e66865e, checked in by Sebastian Huber <sebastian.huber@…>, on 04/29/16 at 09:05:36

score: Move message notification

Move message notification to end of critical section and delegate the
message queue release to the notification handler. It may do more
complex notification actions out of the critical section.

Update #2555.

  • Property mode set to 100644
File size: 3.3 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Initialize a Message Queue
5 *  @ingroup ScoreMessageQueue
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2009.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/coremsgimpl.h>
22#include <rtems/score/wkspace.h>
23
24/*
25 *  size_t_mult32_with_overflow
26 *
27 *  This method multiplies two size_t 32-bit numbers and checks
28 *  for overflow.  It returns false if an overflow occurred and
29 *  the result is bad.
30 */
31static inline bool size_t_mult32_with_overflow(
32  size_t  a,
33  size_t  b,
34  size_t *c
35)
36{
37  long long x = (long long)a*b;
38
39  if ( x > SIZE_MAX )
40    return false;
41  *c = (size_t) x;
42  return true;
43}
44
45bool _CORE_message_queue_Initialize(
46  CORE_message_queue_Control     *the_message_queue,
47  CORE_message_queue_Disciplines  discipline,
48  uint32_t                        maximum_pending_messages,
49  size_t                          maximum_message_size
50)
51{
52  size_t message_buffering_required = 0;
53  size_t allocated_message_size;
54
55  the_message_queue->maximum_pending_messages   = maximum_pending_messages;
56  the_message_queue->number_of_pending_messages = 0;
57  the_message_queue->maximum_message_size       = maximum_message_size;
58  _CORE_message_queue_Set_notify( the_message_queue, NULL );
59
60  allocated_message_size = maximum_message_size;
61
62  /*
63   * Check if allocated_message_size is aligned to uintptr-size boundary.
64   * If not, it will increase allocated_message_size to multiplicity of pointer
65   * size.
66   */
67  if (allocated_message_size & (sizeof(uintptr_t) - 1)) {
68    allocated_message_size += sizeof(uintptr_t);
69    allocated_message_size &= ~(sizeof(uintptr_t) - 1);
70  }
71
72  /*
73   * Check for an overflow. It can occur while increasing allocated_message_size
74   * to multiplicity of uintptr_t above.
75   */
76  if (allocated_message_size < maximum_message_size)
77    return false;
78
79  /*
80   *  Calculate how much total memory is required for message buffering and
81   *  check for overflow on the multiplication.
82   */
83  if ( !size_t_mult32_with_overflow(
84        (size_t) maximum_pending_messages,
85        allocated_message_size + sizeof(CORE_message_queue_Buffer_control),
86        &message_buffering_required ) )
87    return false;
88
89  /*
90   *  Attempt to allocate the message memory
91   */
92  the_message_queue->message_buffers = (CORE_message_queue_Buffer *)
93     _Workspace_Allocate( message_buffering_required );
94
95  if (the_message_queue->message_buffers == 0)
96    return false;
97
98  /*
99   *  Initialize the pool of inactive messages, pending messages,
100   *  and set of waiting threads.
101   */
102  _Chain_Initialize (
103    &the_message_queue->Inactive_messages,
104    the_message_queue->message_buffers,
105    (size_t) maximum_pending_messages,
106    allocated_message_size + sizeof( CORE_message_queue_Buffer_control )
107  );
108
109  _Chain_Initialize_empty( &the_message_queue->Pending_messages );
110
111  _Thread_queue_Initialize( &the_message_queue->Wait_queue );
112
113  if ( discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY ) {
114    the_message_queue->operations = &_Thread_queue_Operations_priority;
115  } else {
116    the_message_queue->operations = &_Thread_queue_Operations_FIFO;
117  }
118
119  return true;
120}
Note: See TracBrowser for help on using the repository browser.