source: rtems/cpukit/score/src/thread.c @ d7665823

Last change on this file since d7665823 was d7665823, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 24, 2015 at 1:43:19 PM

score: Introduce Thread_queue_Heads

Move the storage for the thread queue heads to the threads. Each thread
provides a set of thread queue heads allocated from a dedicated memory
pool. In case a thread blocks on a queue, then it lends its heads to
the queue. In case the thread unblocks, then it takes a free set of
threads from the queue. Since a thread can block on at most one queue
this works. This mechanism is used in FreeBSD. The motivation for this
change is to reduce the memory demands of the synchronization objects.
On a 32-bit uni-processor configuration the Thread_queue_Control size is
now 8 bytes, compared to 64 bytes in RTEMS 4.10 (other changes reduced
the size as well).

  • Property mode set to 100644
File size: 3.2 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Initialize Thread Handler
5 *  @ingroup ScoreThread
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2011.
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/threadimpl.h>
22#include <rtems/score/interr.h>
23#include <rtems/score/wkspace.h>
24
25#define THREAD_OFFSET_ASSERT( field ) \
26  RTEMS_STATIC_ASSERT( \
27    offsetof( Thread_Control, field ) == offsetof( Thread_Proxy_control, field ), \
28    field \
29  )
30
31THREAD_OFFSET_ASSERT( Object );
32THREAD_OFFSET_ASSERT( current_state );
33THREAD_OFFSET_ASSERT( current_priority );
34THREAD_OFFSET_ASSERT( real_priority );
35THREAD_OFFSET_ASSERT( priority_generation );
36THREAD_OFFSET_ASSERT( priority_restore_hint );
37THREAD_OFFSET_ASSERT( resource_count );
38THREAD_OFFSET_ASSERT( Wait );
39THREAD_OFFSET_ASSERT( Timer );
40#if defined(RTEMS_MULTIPROCESSING)
41THREAD_OFFSET_ASSERT( receive_packet );
42#endif
43
44void _Thread_Initialize_information(
45  Thread_Information  *information,
46  Objects_APIs         the_api,
47  uint16_t             the_class,
48  uint32_t             maximum,
49  bool                 is_string,
50  uint32_t             maximum_name_length
51#if defined(RTEMS_MULTIPROCESSING)
52  ,
53  bool                 supports_global
54#endif
55)
56{
57  _Objects_Initialize_information(
58    &information->Objects,
59    the_api,
60    the_class,
61    maximum,
62    _Thread_Control_size,
63    is_string,
64    maximum_name_length
65    #if defined(RTEMS_MULTIPROCESSING)
66      ,
67      supports_global,
68      NULL
69    #endif
70  );
71
72  _Freechain_Initialize(
73    &information->Free_thread_queue_heads,
74    _Workspace_Allocate_or_fatal_error,
75    _Objects_Maximum_per_allocation( maximum ),
76    sizeof( Thread_queue_Heads )
77  );
78}
79
80void _Thread_Handler_initialization(void)
81{
82  rtems_stack_allocate_init_hook stack_allocate_init_hook =
83    rtems_configuration_get_stack_allocate_init_hook();
84  #if defined(RTEMS_MULTIPROCESSING)
85    uint32_t maximum_proxies =
86      _Configuration_MP_table->maximum_proxies;
87  #endif
88
89  if ( rtems_configuration_get_stack_allocate_hook() == NULL ||
90       rtems_configuration_get_stack_free_hook() == NULL)
91    _Terminate(
92      INTERNAL_ERROR_CORE,
93      true,
94      INTERNAL_ERROR_BAD_STACK_HOOK
95    );
96
97  if ( stack_allocate_init_hook != NULL )
98    (*stack_allocate_init_hook)( rtems_configuration_get_stack_space_size() );
99
100  #if defined(RTEMS_MULTIPROCESSING)
101    _Thread_MP_Handler_initialization( maximum_proxies );
102  #endif
103
104  /*
105   *  Initialize the internal class of threads.  We need an IDLE thread
106   *  per CPU in an SMP system.  In addition, if this is a loosely
107   *  coupled multiprocessing system, account for the MPCI Server Thread.
108   */
109  _Thread_Initialize_information(
110    &_Thread_Internal_information,
111    OBJECTS_INTERNAL_API,
112    OBJECTS_INTERNAL_THREADS,
113    _Thread_Get_maximum_internal_threads(),
114    false,                      /* true if names for this object are strings */
115    8                           /* maximum length of each object's name */
116    #if defined(RTEMS_MULTIPROCESSING)
117      ,
118      false                       /* true if this is a global object class */
119    #endif
120  );
121
122}
Note: See TracBrowser for help on using the repository browser.