GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_utility_memory_free.c Lines: 32 35 91.4 %
Date: 2024-12-12 17:16:36 Branches: 10 12 83.3 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** USBX Component                                                        */
16
/**                                                                       */
17
/**   Utility                                                             */
18
/**                                                                       */
19
/**************************************************************************/
20
/**************************************************************************/
21
22
23
/* Include necessary system files.  */
24
25
#define UX_SOURCE_CODE
26
27
#include "ux_api.h"
28
29
30
/**************************************************************************/
31
/*                                                                        */
32
/*  FUNCTION                                               RELEASE        */
33
/*                                                                        */
34
/*    _ux_utility_memory_free                             PORTABLE C      */
35
/*                                                           6.3.0        */
36
/*  AUTHOR                                                                */
37
/*                                                                        */
38
/*    Chaoqiong Xiao, Microsoft Corporation                               */
39
/*                                                                        */
40
/*  DESCRIPTION                                                           */
41
/*                                                                        */
42
/*    This function frees a previously allocated memory block.            */
43
/*                                                                        */
44
/*  INPUT                                                                 */
45
/*                                                                        */
46
/*    memory                                Pointer to memory block       */
47
/*                                                                        */
48
/*  OUTPUT                                                                */
49
/*                                                                        */
50
/*    None                                                                */
51
/*                                                                        */
52
/*  CALLS                                                                 */
53
/*                                                                        */
54
/*    _ux_utility_mutex_on                  Start system protection       */
55
/*    _ux_utility_mutex_off                 End system protection         */
56
/*                                                                        */
57
/*  CALLED BY                                                             */
58
/*                                                                        */
59
/*    USBX Components                                                     */
60
/*                                                                        */
61
/*  RELEASE HISTORY                                                       */
62
/*                                                                        */
63
/*    DATE              NAME                      DESCRIPTION             */
64
/*                                                                        */
65
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
66
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
67
/*                                            resulting in version 6.1    */
68
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
69
/*                                            added standalone support,   */
70
/*                                            resulting in version 6.1.10 */
71
/*  10-31-2023     Yajun Xia, CQ Xiao       Modified comment(s),          */
72
/*                                            added some error traps,     */
73
/*                                            refined memory management,  */
74
/*                                            resulting in version 6.3.0  */
75
/*                                                                        */
76
/**************************************************************************/
77
319877
VOID  _ux_utility_memory_free(VOID *memory)
78
{
79
UX_MEMORY_BYTE_POOL *pool_ptr;
80
UCHAR               *work_ptr;
81
UCHAR               *temp_ptr;
82
UCHAR               *next_block_ptr;
83
84
ALIGN_TYPE          *free_ptr;
85
UX_MEMORY_BYTE_POOL **byte_pool_ptr;
86
UCHAR               **block_link_ptr;
87
#ifdef UX_ENABLE_MEMORY_POOL_SANITY_CHECK
88
UCHAR               *memory_address;
89
UCHAR               *regular_start, *regular_end;
90
UCHAR               *cache_safe_start, *cache_safe_end;
91
#endif
92
#ifdef UX_ENABLE_MEMORY_STATISTICS
93
UINT                index;
94
#endif
95
96
    /* Get the mutex as this is a critical section.  */
97
319877
    _ux_system_mutex_on(&_ux_system -> ux_system_mutex);
98
99
#ifdef UX_ENABLE_MEMORY_POOL_SANITY_CHECK
100
101
    /* Sanity check, check if the memory is in memory pool.  */
102
    regular_start = (UCHAR *)_ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_start;
103
    regular_end = regular_start + _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_size;
104
    regular_start += UX_MEMORY_BLOCK_HEADER_SIZE;
105
    cache_safe_start = (UCHAR *)_ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_start;
106
    cache_safe_end = cache_safe_start + _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_size;
107
    cache_safe_start += UX_MEMORY_BLOCK_HEADER_SIZE;
108
109
    memory_address = (UCHAR *)memory;
110
    if (!((memory_address >= regular_start    && memory_address < regular_end) ||
111
          (memory_address >= cache_safe_start && memory_address < cache_safe_end)))
112
    {
113
114
        /* Not valid. Release the protection.  */
115
        _ux_system_mutex_off(&_ux_system -> ux_system_mutex);
116
117
        /* Error trap.  */
118
        _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD,
119
                                UX_SYSTEM_CONTEXT_UTILITY, UX_MEMORY_CORRUPTED);
120
121
        /* No action taken.  */
122
        return;
123
    }
124
#endif
125
126
    /* Set the pool pointer to NULL.  */
127
319877
    pool_ptr =  UX_NULL;
128
129
    /* Determine if the memory pointer is valid.  */
130
319877
    work_ptr =  UX_VOID_TO_UCHAR_POINTER_CONVERT(memory);
131
319877
    if (work_ptr != UX_NULL)
132
    {
133
134
        /* Back off the memory pointer to pickup its header.  */
135
319877
        work_ptr =  UX_UCHAR_POINTER_SUB(work_ptr, UX_MEMORY_BLOCK_HEADER_SIZE);
136
137
        /* There is a pointer, pickup the pool pointer address.  */
138
319877
        temp_ptr =  UX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
139
319877
        free_ptr =  UX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(temp_ptr);
140
319877
        if ((*free_ptr) != UX_BYTE_BLOCK_FREE)
141
        {
142
143
            /* Pickup the pool pointer.  */
144
319860
            temp_ptr =  UX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
145
319860
            byte_pool_ptr = UX_UCHAR_TO_INDIRECT_BYTE_POOL_POINTER(temp_ptr);
146
319860
            pool_ptr = *byte_pool_ptr;
147
148
            /* See if we have a valid pool pointer.  */
149
319860
            if ((pool_ptr == UX_NULL) ||
150
319857
                ((pool_ptr != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR]) &&
151
114
                (pool_ptr != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE])))
152
            {
153
154
                /* Release the protection.  */
155
3
                _ux_system_mutex_off(&_ux_system -> ux_system_mutex);
156
157
                /* Error trap: maybe double free/memory issue here!  */
158
3
                _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD,
159
                                         UX_SYSTEM_CONTEXT_UTILITY, UX_MEMORY_CORRUPTED);
160
161
                /* Return to caller.  */
162
3
                return;
163
            }
164
        }
165
        else
166
        {
167
            /* Release the protection.  */
168
17
            _ux_system_mutex_off(&_ux_system -> ux_system_mutex);
169
170
            /* Error trap: maybe double free/memory issue here!  */
171
17
            _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD,
172
                                     UX_SYSTEM_CONTEXT_UTILITY, UX_MEMORY_CORRUPTED);
173
174
            /* Return to caller.  */
175
17
            return;
176
        }
177
    }
178
    else
179
    {
180
181
        /* Release the protection.  */
182
        _ux_system_mutex_off(&_ux_system -> ux_system_mutex);
183
184
        /* Error trap: maybe double free/bad flow here!  */
185
        _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD,
186
                                    UX_SYSTEM_CONTEXT_UTILITY, UX_MEMORY_CORRUPTED);
187
188
        /* Return to caller.  */
189
        return;
190
    }
191
192
    /* At this point, we know that the pool pointer is valid.  */
193
194
    /* Release the memory.  */
195
319857
    temp_ptr =   UX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
196
319857
    free_ptr =   UX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(temp_ptr);
197
319857
    *free_ptr =  UX_BYTE_BLOCK_FREE;
198
199
    /* Update the number of available bytes in the pool.  */
200
319857
    block_link_ptr =  UX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
201
319857
    next_block_ptr =  *block_link_ptr;
202
319857
    pool_ptr -> ux_byte_pool_available =
203
319857
        pool_ptr -> ux_byte_pool_available + UX_UCHAR_POINTER_DIF(next_block_ptr, work_ptr);
204
205
    /* Determine if the free block is prior to current search pointer.  */
206
319857
    if (work_ptr < (pool_ptr -> ux_byte_pool_search))
207
    {
208
209
        /* Yes, update the search pointer to the released block.  */
210
7202
        pool_ptr -> ux_byte_pool_search =  work_ptr;
211
    }
212
213
#ifdef UX_ENABLE_MEMORY_STATISTICS
214
    if (((UCHAR*)memory >= _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_start) &&
215
        ((UCHAR*)memory < (_ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_start + _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_size)))
216
        index = UX_MEMORY_BYTE_POOL_REGULAR;
217
    else
218
        index = UX_MEMORY_BYTE_POOL_CACHE_SAFE;
219
220
    _ux_system -> ux_system_memory_byte_pool[index] -> ux_byte_pool_alloc_count --;
221
    _ux_system -> ux_system_memory_byte_pool[index] -> ux_byte_pool_alloc_total -= UX_UCHAR_POINTER_DIF(next_block_ptr, work_ptr);
222
#endif
223
224
    /* Release the protection.  */
225
319857
    _ux_system_mutex_off(&_ux_system -> ux_system_mutex);
226
227
    /* Return to caller.  */
228
319857
    return;
229
}
230