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 /**   Block 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_initialize.h"
30 #include "tx_thread.h"
31 #include "tx_timer.h"
32 #include "tx_block_pool.h"
33 
34 
35 /**************************************************************************/
36 /*                                                                        */
37 /*  FUNCTION                                               RELEASE        */
38 /*                                                                        */
39 /*    _txe_block_pool_create                              PORTABLE C      */
40 /*                                                           6.1          */
41 /*  AUTHOR                                                                */
42 /*                                                                        */
43 /*    William E. Lamie, Microsoft Corporation                             */
44 /*                                                                        */
45 /*  DESCRIPTION                                                           */
46 /*                                                                        */
47 /*    This function checks for errors in the create block memory pool     */
48 /*    function call.                                                      */
49 /*                                                                        */
50 /*  INPUT                                                                 */
51 /*                                                                        */
52 /*    pool_ptr                          Pointer to pool control block     */
53 /*    name_ptr                          Pointer to block pool name        */
54 /*    block_size                        Number of bytes in each block     */
55 /*    pool_start                        Address of beginning of pool area */
56 /*    pool_size                         Number of bytes in the block pool */
57 /*    pool_control_block_size           Size of block pool control block  */
58 /*                                                                        */
59 /*  OUTPUT                                                                */
60 /*                                                                        */
61 /*    TX_POOL_ERROR                     Invalid pool pointer              */
62 /*    TX_PTR_ERROR                      Invalid starting address          */
63 /*    TX_SIZE_ERROR                     Invalid pool size                 */
64 /*    TX_CALLER_ERROR                   Invalid caller of pool            */
65 /*    status                            Actual completion status          */
66 /*                                                                        */
67 /*  CALLS                                                                 */
68 /*                                                                        */
69 /*    _tx_block_pool_create             Actual block pool create function */
70 /*    _tx_thread_system_preempt_check   Check for preemption              */
71 /*                                                                        */
72 /*  CALLED BY                                                             */
73 /*                                                                        */
74 /*    Application Code                                                    */
75 /*                                                                        */
76 /*  RELEASE HISTORY                                                       */
77 /*                                                                        */
78 /*    DATE              NAME                      DESCRIPTION             */
79 /*                                                                        */
80 /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
81 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
82 /*                                            resulting in version 6.1    */
83 /*                                                                        */
84 /**************************************************************************/
_txe_block_pool_create(TX_BLOCK_POOL * pool_ptr,CHAR * name_ptr,ULONG block_size,VOID * pool_start,ULONG pool_size,UINT pool_control_block_size)85 UINT  _txe_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,
86                     VOID *pool_start, ULONG pool_size, UINT pool_control_block_size)
87 {
88 
89 TX_INTERRUPT_SAVE_AREA
90 
91 UINT            status;
92 ULONG           i;
93 TX_BLOCK_POOL   *next_pool;
94 #ifndef TX_TIMER_PROCESS_IN_ISR
95 TX_THREAD       *thread_ptr;
96 #endif
97 
98 
99     /* Default status to success.  */
100     status =  TX_SUCCESS;
101 
102     /* Check for an invalid pool pointer.  */
103     if (pool_ptr == TX_NULL)
104     {
105 
106         /* Pool pointer is invalid, return appropriate error code.  */
107         status =  TX_POOL_ERROR;
108     }
109 
110     /* Check for invalid control block size.  */
111     else if (pool_control_block_size != (sizeof(TX_BLOCK_POOL)))
112     {
113 
114         /* Pool pointer is invalid, return appropriate error code.  */
115         status =  TX_POOL_ERROR;
116     }
117     else
118     {
119 
120         /* Disable interrupts.  */
121         TX_DISABLE
122 
123         /* Increment the preempt disable flag.  */
124         _tx_thread_preempt_disable++;
125 
126         /* Restore interrupts.  */
127         TX_RESTORE
128 
129         /* Next see if it is already in the created list.  */
130         next_pool =   _tx_block_pool_created_ptr;
131         for (i = ((ULONG) 0); i < _tx_block_pool_created_count; i++)
132         {
133 
134             /* Determine if this block pool matches the pool in the list.  */
135             if (pool_ptr == next_pool)
136             {
137 
138                 break;
139             }
140             else
141             {
142                 /* Move to the next pool.  */
143                 next_pool =  next_pool -> tx_block_pool_created_next;
144             }
145         }
146 
147         /* Disable interrupts.  */
148         TX_DISABLE
149 
150         /* Decrement the preempt disable flag.  */
151         _tx_thread_preempt_disable--;
152 
153         /* Restore interrupts.  */
154         TX_RESTORE
155 
156         /* Check for preemption.  */
157         _tx_thread_system_preempt_check();
158 
159         /* At this point, check to see if there is a duplicate pool.  */
160         if (pool_ptr == next_pool)
161         {
162 
163             /* Pool is already created, return appropriate error code.  */
164             status =  TX_POOL_ERROR;
165         }
166 
167         /* Check for an invalid starting address.  */
168         else if (pool_start == TX_NULL)
169         {
170 
171             /* Null starting address pointer, return appropriate error.  */
172             status =  TX_PTR_ERROR;
173         }
174         else
175         {
176 
177             /* Check for invalid pool size.  */
178             if ((((block_size/(sizeof(void *)))*(sizeof(void *))) + (sizeof(void *))) >
179                                             ((pool_size/(sizeof(void *)))*(sizeof(void *))))
180             {
181 
182                 /* Not enough memory for one block, return appropriate error.  */
183                 status =  TX_SIZE_ERROR;
184             }
185             else
186             {
187 
188 #ifndef TX_TIMER_PROCESS_IN_ISR
189 
190                 /* Pickup thread pointer.  */
191                 TX_THREAD_GET_CURRENT(thread_ptr)
192 
193                 /* Check for invalid caller of this function.  First check for a calling thread.  */
194                 if (thread_ptr == &_tx_timer_thread)
195                 {
196 
197                     /* Invalid caller of this function, return appropriate error code.  */
198                     status =  TX_CALLER_ERROR;
199                 }
200 #endif
201 
202                 /* Check for interrupt call.  */
203                 if (TX_THREAD_GET_SYSTEM_STATE() != ((ULONG) 0))
204                 {
205 
206                     /* Now, make sure the call is from an interrupt and not initialization.  */
207                     if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
208                     {
209 
210                         /* Invalid caller of this function, return appropriate error code.  */
211                         status =  TX_CALLER_ERROR;
212                     }
213                 }
214             }
215         }
216     }
217 
218     /* Determine if everything is okay.  */
219     if (status == TX_SUCCESS)
220     {
221 
222         /* Call actual block pool create function.  */
223         status =  _tx_block_pool_create(pool_ptr, name_ptr, block_size, pool_start, pool_size);
224     }
225 
226     /* Return completion status.  */
227     return(status);
228 }
229 
230