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 /** Module Manager */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define TX_SOURCE_CODE
23
24 #include "txm_module.h"
25
26 /**************************************************************************/
27 /* */
28 /* FUNCTION RELEASE */
29 /* */
30 /* _txm_module_manager_object_allocate PORTABLE C */
31 /* 6.1 */
32 /* AUTHOR */
33 /* */
34 /* Scott Larson, Microsoft Corporation */
35 /* */
36 /* DESCRIPTION */
37 /* */
38 /* This function allocates memory for an object from the memory pool */
39 /* supplied to txm_module_manager_initialize. */
40 /* */
41 /* INPUT */
42 /* */
43 /* object_ptr Destination of object pointer on */
44 /* successful allocation */
45 /* object_size Size in bytes of the object to be */
46 /* allocated */
47 /* module_instance The module instance that the */
48 /* object belongs to */
49 /* */
50 /* OUTPUT */
51 /* */
52 /* status Completion status */
53 /* */
54 /* CALLS */
55 /* */
56 /* _txe_mutex_get Get module instance mutex */
57 /* _txe_mutex_put Release module instance mutex */
58 /* _txe_byte_allocate Allocate object from pool */
59 /* */
60 /* CALLED BY */
61 /* */
62 /* Application code */
63 /* */
64 /* RELEASE HISTORY */
65 /* */
66 /* DATE NAME DESCRIPTION */
67 /* */
68 /* 09-30-2020 Scott Larson Initial Version 6.1 */
69 /* */
70 /**************************************************************************/
_txm_module_manager_object_allocate(VOID ** object_ptr_ptr,ULONG object_size,TXM_MODULE_INSTANCE * module_instance)71 UINT _txm_module_manager_object_allocate(VOID **object_ptr_ptr, ULONG object_size, TXM_MODULE_INSTANCE *module_instance)
72 {
73
74 TXM_MODULE_ALLOCATED_OBJECT *object_ptr;
75 UINT return_value;
76
77
78 /* Ensure the object pointer pointer is valid. */
79 if (object_ptr_ptr == (VOID **) TX_NULL)
80 {
81
82 /* The object pointer pointer is invalid, return an error. */
83 return(TXM_MODULE_INVALID_MEMORY);
84 }
85
86 /* Initialize the return pointer to NULL. */
87 *((VOID **) object_ptr_ptr) = TX_NULL;
88
89 /* Get module manager protection mutex. */
90 _txe_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
91
92 /* Determine if an object pool was created. */
93 if (_txm_module_manager_object_pool_created)
94 {
95
96 TXM_MODULE_ALLOCATED_OBJECT *next_object, *previous_object;
97
98 /* Allocate the object requested by the module - adding an extra ULONG in order to
99 store the module instance pointer. */
100 return_value = (ULONG) _txe_byte_allocate(&_txm_module_manager_object_pool, (VOID **) &object_ptr,
101 (ULONG) (object_size + sizeof(TXM_MODULE_ALLOCATED_OBJECT)), TX_NO_WAIT);
102
103 /* Determine if the request was successful. */
104 if (return_value == TX_SUCCESS)
105 {
106 /* Yes, now store the module instance in the allocated memory block. */
107
108 /* Link the allocated memory to the module instance. */
109 if (module_instance -> txm_module_instance_object_list_count++ == 0)
110 {
111 /* The allocated object list is empty. Add object to empty list. */
112 module_instance -> txm_module_instance_object_list_head = object_ptr;
113 object_ptr -> txm_module_allocated_object_next = object_ptr;
114 object_ptr -> txm_module_allocated_object_previous = object_ptr;
115 }
116 else
117 {
118 /* This list is not NULL, add to the end of the list. */
119 next_object = module_instance -> txm_module_instance_object_list_head;
120 previous_object = next_object -> txm_module_allocated_object_previous;
121
122 /* Place the new object in the list. */
123 next_object -> txm_module_allocated_object_previous = object_ptr;
124 previous_object -> txm_module_allocated_object_next = object_ptr;
125
126 /* Setup this object's allocated links. */
127 object_ptr -> txm_module_allocated_object_previous = previous_object;
128 object_ptr -> txm_module_allocated_object_next = next_object;
129 }
130
131 /* Setup the module instance pointer in the allocated object. */
132 object_ptr -> txm_module_allocated_object_module_instance = module_instance;
133
134 /* Set the object size. */
135 object_ptr -> txm_module_object_size = object_size;
136
137 /* Move the object pointer forward. This is what the module is given. */
138 object_ptr++;
139
140 /* Return this pointer to the application. */
141 *((VOID **) object_ptr_ptr) = object_ptr;
142 }
143 }
144 else
145 {
146 /* Set return value to not enabled. */
147 return_value = TX_NOT_AVAILABLE;
148 }
149
150 /* Release the protection mutex. */
151 _txe_mutex_put(&_txm_module_manager_mutex);
152
153 return(return_value);
154 }
155