source: rtems/cpukit/score/src/coremsg.c @ 1e1a91ed

5
Last change on this file since 1e1a91ed was 1e1a91ed, checked in by Sebastian Huber <sebastian.huber@…>, on 03/23/16 at 09:01:31

score: Remove Thread_queue_Queue::operations field

Remove the Thread_queue_Queue::operations field to reduce the size of
this structure. Add a thread queue operations parameter to the
_Thread_queue_First(), _Thread_queue_First_locked(),
_Thread_queue_Enqueue(), _Thread_queue_Dequeue() and
_Thread_queue_Flush() functions. This is a preparation patch to reduce
the size of several synchronization objects.

  • 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, 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.