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