source: rtems/cpukit/score/src/coremsg.c @ d658a9b

4.115
Last change on this file since d658a9b was d658a9b, checked in by Joel Sherrill <joel.sherrill@…>, on 08/31/12 at 14:58:42

coremsg.c: Clean up and comment improvement

This code was reviewed as part of coverage analysis improvements. The
uncovered range had unclear documentation and the code itself was also
cleaned up to be easier to understand.

Author: Krzysztof Mięsowicz <krzysztof.miesowicz@…>

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 *  CORE Message Queue Handler
3 *
4 *  DESCRIPTION:
5 *
6 *  This package is the implementation of the CORE Message Queue Handler.
7 *  This core object provides task synchronization and communication functions
8 *  via messages passed to queue objects.
9 *
10 *  COPYRIGHT (c) 1989-2009.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16 */
17
18#if HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include <rtems/system.h>
23#include <rtems/score/chain.h>
24#include <rtems/score/isr.h>
25#include <rtems/score/object.h>
26#include <rtems/score/coremsg.h>
27#include <rtems/score/states.h>
28#include <rtems/score/thread.h>
29#include <rtems/score/wkspace.h>
30
31/*
32 *  size_t_mult32_with_overflow
33 *
34 *  This method multiplies two size_t 32-bit numbers and checks
35 *  for overflow.  It returns false if an overflow occurred and
36 *  the result is bad.
37 */
38static inline bool size_t_mult32_with_overflow(
39  size_t  a,
40  size_t  b,
41  size_t *c
42)
43{
44  long long x = (long long)a*b;
45
46  if ( x > SIZE_MAX )
47    return false;
48  *c = (size_t) x;
49  return true;
50}
51
52/*
53 *  _CORE_message_queue_Initialize
54 *
55 *  This routine initializes a newly created message queue based on the
56 *  specified data.
57 *
58 *  Input parameters:
59 *    the_message_queue            - the message queue to initialize
60 *    the_class                    - the API specific object class
61 *    the_message_queue_attributes - the message queue's attributes
62 *    maximum_pending_messages     - maximum message and reserved buffer count
63 *    maximum_message_size         - maximum size of each message
64 *
65 *  Output parameters:
66 *    true   - if the message queue is initialized
67 *    false  - if the message queue is NOT initialized
68 */
69
70bool _CORE_message_queue_Initialize(
71  CORE_message_queue_Control    *the_message_queue,
72  CORE_message_queue_Attributes *the_message_queue_attributes,
73  uint32_t                       maximum_pending_messages,
74  size_t                         maximum_message_size
75)
76{
77  size_t message_buffering_required = 0;
78  size_t allocated_message_size;
79
80  the_message_queue->maximum_pending_messages   = maximum_pending_messages;
81  the_message_queue->number_of_pending_messages = 0;
82  the_message_queue->maximum_message_size       = maximum_message_size;
83  _CORE_message_queue_Set_notify( the_message_queue, NULL, NULL );
84
85  allocated_message_size = maximum_message_size;
86
87  /*
88   * Check if allocated_message_size is aligned to uintptr-size boundary.
89   * If not, it will increase allocated_message_size to multiplicity of pointer
90   * size.
91   */
92  if (allocated_message_size & (sizeof(uintptr_t) - 1)) {
93    allocated_message_size += sizeof(uintptr_t);
94    allocated_message_size &= ~(sizeof(uintptr_t) - 1);
95  }
96
97  /*
98   * Check for an overflow. It can occur while increasing allocated_message_size
99   * to multiplicity of uintptr_t above.
100   */
101  if (allocated_message_size < maximum_message_size)
102    return false;
103
104  /*
105   *  Calculate how much total memory is required for message buffering and
106   *  check for overflow on the multiplication.
107   */
108  if ( !size_t_mult32_with_overflow(
109        (size_t) maximum_pending_messages,
110        allocated_message_size + sizeof(CORE_message_queue_Buffer_control),
111        &message_buffering_required ) )
112    return false;
113
114  /*
115   *  Attempt to allocate the message memory
116   */
117  the_message_queue->message_buffers = (CORE_message_queue_Buffer *)
118     _Workspace_Allocate( message_buffering_required );
119
120  if (the_message_queue->message_buffers == 0)
121    return false;
122
123  /*
124   *  Initialize the pool of inactive messages, pending messages,
125   *  and set of waiting threads.
126   */
127  _Chain_Initialize (
128    &the_message_queue->Inactive_messages,
129    the_message_queue->message_buffers,
130    (size_t) maximum_pending_messages,
131    allocated_message_size + sizeof( CORE_message_queue_Buffer_control )
132  );
133
134  _Chain_Initialize_empty( &the_message_queue->Pending_messages );
135
136  _Thread_queue_Initialize(
137    &the_message_queue->Wait_queue,
138    _CORE_message_queue_Is_priority( the_message_queue_attributes ) ?
139       THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
140    STATES_WAITING_FOR_MESSAGE,
141    CORE_MESSAGE_QUEUE_STATUS_TIMEOUT
142  );
143
144  return true;
145}
Note: See TracBrowser for help on using the repository browser.