GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_utility_memory_free.c Lines: 32 35 91.4 %
Date: 2026-03-06 18:57:10 Branches: 10 12 83.3 %

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