source: rtems/cpukit/libcsupport/src/malloc_deferred.c @ 80cf60e

5
Last change on this file since 80cf60e was 80cf60e, checked in by Sebastian Huber <sebastian.huber@…>, on 04/15/20 at 07:48:32

Canonicalize config.h include

Use the following variant which was already used by most source files:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

  • Property mode set to 100644
File size: 3.6 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Malloc Deferred Support
5 *  @ingroup libcsupport
6 */
7
8/*
9 *  Process free requests deferred because they were from ISR
10 *  or other critical section.
11 *
12 *  COPYRIGHT (c) 1989-2007.
13 *  On-Line Applications Research Corporation (OAR).
14 *
15 *  The license and distribution terms for this file may be
16 *  found in the file LICENSE in this distribution or at
17 *  http://www.rtems.org/license/LICENSE.
18 */
19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#ifdef RTEMS_NEWLIB
25#include <stdlib.h>
26#include <string.h>
27
28#include "malloc_p.h"
29
30#include <rtems/chain.h>
31#include <rtems/score/sysstate.h>
32#include <rtems/score/threaddispatch.h>
33
34static RTEMS_CHAIN_DEFINE_EMPTY( _Malloc_GC_list );
35
36RTEMS_INTERRUPT_LOCK_DEFINE( static, _Malloc_GC_lock, "Malloc GC" )
37
38Malloc_System_state _Malloc_System_state( void )
39{
40  System_state_Codes state = _System_state_Get();
41
42  if ( _System_state_Is_up( state ) ) {
43    if ( _Thread_Dispatch_is_enabled() ) {
44      return MALLOC_SYSTEM_STATE_NORMAL;
45    } else {
46      return MALLOC_SYSTEM_STATE_NO_ALLOCATION;
47    }
48  } else if ( _System_state_Is_before_multitasking( state ) ) {
49    return MALLOC_SYSTEM_STATE_NORMAL;
50  } else {
51    return MALLOC_SYSTEM_STATE_NO_PROTECTION;
52  }
53}
54
55static void *_Malloc_Get_deferred_free( void )
56{
57  rtems_interrupt_lock_context lock_context;
58  void *p;
59
60  rtems_interrupt_lock_acquire( &_Malloc_GC_lock, &lock_context );
61  p = rtems_chain_get_unprotected( &_Malloc_GC_list );
62  rtems_interrupt_lock_release( &_Malloc_GC_lock, &lock_context );
63
64  return p;
65}
66
67void _Malloc_Process_deferred_frees( void )
68{
69  rtems_chain_node *to_be_freed;
70
71  /*
72   *  If some free's have been deferred, then do them now.
73   */
74  while ( ( to_be_freed = _Malloc_Get_deferred_free() ) != NULL ) {
75    free( to_be_freed );
76  }
77}
78
79void *rtems_heap_allocate_aligned_with_boundary(
80  size_t    size,
81  uintptr_t alignment,
82  uintptr_t boundary
83)
84{
85  Heap_Control *heap = RTEMS_Malloc_Heap;
86  void *p;
87
88  switch ( _Malloc_System_state() ) {
89    case MALLOC_SYSTEM_STATE_NORMAL:
90      _RTEMS_Lock_allocator();
91      _Malloc_Process_deferred_frees();
92      p = _Heap_Allocate_aligned_with_boundary(
93        heap,
94        size,
95        alignment,
96        boundary
97      );
98      _RTEMS_Unlock_allocator();
99      break;
100    case MALLOC_SYSTEM_STATE_NO_PROTECTION:
101      p = _Heap_Allocate_aligned_with_boundary(
102        heap,
103        size,
104        alignment,
105        boundary
106      );
107      break;
108    default:
109      /*
110       *  Do not attempt to allocate memory if not in correct system state.
111       */
112      return NULL;
113  }
114
115  if ( p == NULL && alignment == 0 && boundary == 0 ) {
116    p = (*rtems_malloc_extend_handler)( heap, size );
117  }
118
119  /*
120   *  If the user wants us to dirty the allocated memory, then do it.
121   */
122  if ( p != NULL && rtems_malloc_dirty_helper != NULL )
123    (*rtems_malloc_dirty_helper)( p, size );
124
125  return p;
126}
127
128void _Malloc_Deferred_free( void *p )
129{
130  rtems_interrupt_lock_context lock_context;
131  rtems_chain_node *node;
132
133  node = (rtems_chain_node *) p;
134
135  rtems_interrupt_lock_acquire( &_Malloc_GC_lock, &lock_context );
136  rtems_chain_initialize_node( node );
137  rtems_chain_append_unprotected( &_Malloc_GC_list, node );
138  rtems_interrupt_lock_release( &_Malloc_GC_lock, &lock_context );
139}
140
141void *rtems_malloc( size_t size )
142{
143  if ( size == 0 ) {
144    return NULL;
145  }
146
147  return rtems_heap_allocate_aligned_with_boundary( size, 0, 0 );
148}
149
150void *rtems_calloc( size_t nelem, size_t elsize )
151{
152  size_t  length;
153  void   *p;
154
155  length = nelem * elsize;
156  p = rtems_malloc( length );
157  RTEMS_OBFUSCATE_VARIABLE( p );
158  if ( RTEMS_PREDICT_FALSE( p == NULL ) ) {
159    return p;
160  }
161
162  return memset( p, 0, length );
163}
164#endif
Note: See TracBrowser for help on using the repository browser.