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