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 /** ThreadX Component                                                     */
16 /**                                                                       */
17 /**   Byte Pool                                                           */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define TX_SOURCE_CODE
23 
24 
25 /* Include necessary system files.  */
26 
27 #include "tx_api.h"
28 #include "tx_trace.h"
29 #include "tx_byte_pool.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _tx_byte_pool_create                                PORTABLE C      */
37 /*                                                           6.1          */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    William E. Lamie, Microsoft Corporation                             */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function creates a pool of memory bytes in the specified       */
45 /*    memory area.                                                        */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    pool_ptr                          Pointer to pool control block     */
50 /*    name_ptr                          Pointer to byte pool name         */
51 /*    pool_start                        Address of beginning of pool area */
52 /*    pool_size                         Number of bytes in the byte pool  */
53 /*                                                                        */
54 /*  OUTPUT                                                                */
55 /*                                                                        */
56 /*    TX_SUCCESS                        Successful completion status      */
57 /*                                                                        */
58 /*  CALLS                                                                 */
59 /*                                                                        */
60 /*    None                                                                */
61 /*                                                                        */
62 /*  CALLED BY                                                             */
63 /*                                                                        */
64 /*    Application Code                                                    */
65 /*                                                                        */
66 /*  RELEASE HISTORY                                                       */
67 /*                                                                        */
68 /*    DATE              NAME                      DESCRIPTION             */
69 /*                                                                        */
70 /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
71 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
72 /*                                            resulting in version 6.1    */
73 /*                                                                        */
74 /**************************************************************************/
_tx_byte_pool_create(TX_BYTE_POOL * pool_ptr,CHAR * name_ptr,VOID * pool_start,ULONG pool_size)75 UINT  _tx_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start, ULONG pool_size)
76 {
77 
78 TX_INTERRUPT_SAVE_AREA
79 
80 UCHAR               *block_ptr;
81 UCHAR               **block_indirect_ptr;
82 UCHAR               *temp_ptr;
83 TX_BYTE_POOL        *next_pool;
84 TX_BYTE_POOL        *previous_pool;
85 ALIGN_TYPE          *free_ptr;
86 
87 
88     /* Initialize the byte pool control block to all zeros.  */
89     TX_MEMSET(pool_ptr, 0, (sizeof(TX_BYTE_POOL)));
90 
91     /* Round the pool size down to something that is evenly divisible by
92        an ULONG.  */
93     pool_size =   (pool_size/(sizeof(ALIGN_TYPE))) * (sizeof(ALIGN_TYPE));
94 
95     /* Setup the basic byte pool fields.  */
96     pool_ptr -> tx_byte_pool_name =              name_ptr;
97 
98     /* Save the start and size of the pool.  */
99     pool_ptr -> tx_byte_pool_start =   TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
100     pool_ptr -> tx_byte_pool_size =    pool_size;
101 
102     /* Setup memory list to the beginning as well as the search pointer.  */
103     pool_ptr -> tx_byte_pool_list =    TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
104     pool_ptr -> tx_byte_pool_search =  TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
105 
106     /* Initially, the pool will have two blocks.  One large block at the
107        beginning that is available and a small allocated block at the end
108        of the pool that is there just for the algorithm.  Be sure to count
109        the available block's header in the available bytes count.  */
110     pool_ptr -> tx_byte_pool_available =   pool_size - ((sizeof(VOID *)) + (sizeof(ALIGN_TYPE)));
111     pool_ptr -> tx_byte_pool_fragments =   ((UINT) 2);
112 
113     /* Each block contains a "next" pointer that points to the next block in the pool followed by a ALIGN_TYPE
114        field that contains either the constant TX_BYTE_BLOCK_FREE (if the block is free) or a pointer to the
115        owning pool (if the block is allocated).  */
116 
117     /* Calculate the end of the pool's memory area.  */
118     block_ptr =  TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
119     block_ptr =  TX_UCHAR_POINTER_ADD(block_ptr, pool_size);
120 
121     /* Backup the end of the pool pointer and build the pre-allocated block.  */
122     block_ptr =  TX_UCHAR_POINTER_SUB(block_ptr, (sizeof(ALIGN_TYPE)));
123 
124     /* Cast the pool pointer into a ULONG.  */
125     temp_ptr =             TX_BYTE_POOL_TO_UCHAR_POINTER_CONVERT(pool_ptr);
126     block_indirect_ptr =   TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
127     *block_indirect_ptr =  temp_ptr;
128 
129     block_ptr =            TX_UCHAR_POINTER_SUB(block_ptr, (sizeof(UCHAR *)));
130     block_indirect_ptr =   TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
131     *block_indirect_ptr =  TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
132 
133     /* Now setup the large available block in the pool.  */
134     temp_ptr =             TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
135     block_indirect_ptr =   TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(temp_ptr);
136     *block_indirect_ptr =  block_ptr;
137     block_ptr =            TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
138     block_ptr =            TX_UCHAR_POINTER_ADD(block_ptr, (sizeof(UCHAR *)));
139     free_ptr =             TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(block_ptr);
140     *free_ptr =            TX_BYTE_BLOCK_FREE;
141 
142     /* Clear the owner id.  */
143     pool_ptr -> tx_byte_pool_owner =  TX_NULL;
144 
145     /* Disable interrupts to place the byte pool on the created list.  */
146     TX_DISABLE
147 
148     /* Setup the byte pool ID to make it valid.  */
149     pool_ptr -> tx_byte_pool_id =  TX_BYTE_POOL_ID;
150 
151     /* Place the byte pool on the list of created byte pools.  First,
152        check for an empty list.  */
153     if (_tx_byte_pool_created_count == TX_EMPTY)
154     {
155 
156         /* The created byte pool list is empty.  Add byte pool to empty list.  */
157         _tx_byte_pool_created_ptr =                  pool_ptr;
158         pool_ptr -> tx_byte_pool_created_next =      pool_ptr;
159         pool_ptr -> tx_byte_pool_created_previous =  pool_ptr;
160     }
161     else
162     {
163 
164         /* This list is not NULL, add to the end of the list.  */
165         next_pool =      _tx_byte_pool_created_ptr;
166         previous_pool =  next_pool -> tx_byte_pool_created_previous;
167 
168         /* Place the new byte pool in the list.  */
169         next_pool -> tx_byte_pool_created_previous =  pool_ptr;
170         previous_pool -> tx_byte_pool_created_next =  pool_ptr;
171 
172         /* Setup this byte pool's created links.  */
173         pool_ptr -> tx_byte_pool_created_previous =  previous_pool;
174         pool_ptr -> tx_byte_pool_created_next =      next_pool;
175     }
176 
177     /* Increment the number of created byte pools.  */
178     _tx_byte_pool_created_count++;
179 
180     /* Optional byte pool create extended processing.  */
181     TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
182 
183     /* If trace is enabled, register this object.  */
184     TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_BYTE_POOL, pool_ptr, name_ptr, pool_size, 0)
185 
186     /* If trace is enabled, insert this event into the trace buffer.  */
187     TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_CREATE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(pool_start), pool_size, TX_POINTER_TO_ULONG_CONVERT(&block_ptr), TX_TRACE_BYTE_POOL_EVENTS)
188 
189     /* Log this kernel call.  */
190     TX_EL_BYTE_POOL_CREATE_INSERT
191 
192     /* Restore interrupts.  */
193     TX_RESTORE
194 
195     /* Return TX_SUCCESS.  */
196     return(TX_SUCCESS);
197 }
198 
199