2020#include "ompi_config.h"
2121
2222#include "ompi/class/ompi_free_list.h"
23+ #include "opal/include/opal/align.h"
2324#include "opal/sys/cache.h"
2425#include "opal/util/output.h"
2526#include "ompi/mca/mpool/mpool.h"
2627
27- static inline size_t align_to (size_t val , size_t alignment );
28- static inline size_t align_to (size_t val , size_t alignment )
29- {
30- size_t mod ;
31-
32- if (0 == alignment )
33- return val ;
34-
35- mod = val % alignment ;
36-
37- if (mod )
38- val += (alignment - mod );
39-
40- return val ;
41- }
42-
4328static void ompi_free_list_construct (ompi_free_list_t * fl );
4429static void ompi_free_list_destruct (ompi_free_list_t * fl );
4530
@@ -49,6 +34,7 @@ OBJ_CLASS_INSTANCE(ompi_free_list_t, opal_atomic_lifo_t,
4934struct ompi_free_list_memory_t {
5035 opal_list_item_t super ;
5136 mca_mpool_base_registration_t * registration ;
37+ void * base_ptr ;
5238};
5339typedef struct ompi_free_list_memory_t ompi_free_list_memory_t ;
5440static OBJ_CLASS_INSTANCE (ompi_free_list_memory_t ,
@@ -69,7 +55,6 @@ static void ompi_free_list_construct(ompi_free_list_t* fl)
6955 fl -> fl_num_waiting = 0 ;
7056 fl -> fl_elem_size = sizeof (ompi_free_list_item_t );
7157 fl -> fl_elem_class = OBJ_CLASS (ompi_free_list_item_t );
72- fl -> fl_header_space = 0 ;
7358 fl -> fl_alignment = 0 ;
7459 fl -> fl_mpool = 0 ;
7560 OBJ_CONSTRUCT (& (fl -> fl_allocations ), opal_list_t );
@@ -78,6 +63,7 @@ static void ompi_free_list_construct(ompi_free_list_t* fl)
7863static void ompi_free_list_destruct (ompi_free_list_t * fl )
7964{
8065 opal_list_item_t * item ;
66+ ompi_free_list_memory_t * fl_mem ;
8167
8268#if 0 && OMPI_ENABLE_DEBUG
8369 if (opal_list_get_size (& fl -> super ) != fl -> fl_num_allocated ) {
@@ -87,21 +73,15 @@ static void ompi_free_list_destruct(ompi_free_list_t* fl)
8773 }
8874#endif
8975
90- if (NULL != fl -> fl_mpool ) {
91- ompi_free_list_memory_t * fl_mem ;
92-
93- while (NULL != (item = opal_list_remove_first (& (fl -> fl_allocations )))) {
94- /* destruct the item (we constructed it), then free the memory chunk */
95- OBJ_DESTRUCT (item );
96- fl_mem = (ompi_free_list_memory_t * ) item ;
97- fl -> fl_mpool -> mpool_free (fl -> fl_mpool , item , fl_mem -> registration );
98- }
99- } else {
100- while (NULL != (item = opal_list_remove_first (& (fl -> fl_allocations )))) {
101- /* destruct the item (we constructed it), then free the memory chunk */
102- OBJ_DESTRUCT (item );
103- free (item );
76+ while (NULL != (item = opal_list_remove_first (& (fl -> fl_allocations )))) {
77+ fl_mem = (ompi_free_list_memory_t * )item ;
78+ if (fl -> fl_mpool != NULL ) {
79+ fl -> fl_mpool -> mpool_free (fl -> fl_mpool , fl_mem -> base_ptr ,
80+ fl_mem -> registration );
10481 }
82+ /* destruct the item (we constructed it), then free the memory chunk */
83+ OBJ_DESTRUCT (item );
84+ free (item );
10585 }
10686
10787 OBJ_DESTRUCT (& fl -> fl_allocations );
@@ -112,14 +92,17 @@ static void ompi_free_list_destruct(ompi_free_list_t* fl)
11292int ompi_free_list_init_ex (
11393 ompi_free_list_t * flist ,
11494 size_t elem_size ,
115- size_t header_space ,
11695 size_t alignment ,
11796 opal_class_t * elem_class ,
11897 int num_elements_to_alloc ,
11998 int max_elements_to_alloc ,
12099 int num_elements_per_alloc ,
121100 mca_mpool_base_module_t * mpool )
122101{
102+ /* alignment must be more than zero and power of two */
103+ if (alignment <= 1 || (alignment & (alignment - 1 )))
104+ return OMPI_ERROR ;
105+
123106 if (elem_size > flist -> fl_elem_size )
124107 flist -> fl_elem_size = elem_size ;
125108 if (elem_class )
@@ -128,61 +111,75 @@ int ompi_free_list_init_ex(
128111 flist -> fl_num_allocated = 0 ;
129112 flist -> fl_num_per_alloc = num_elements_per_alloc ;
130113 flist -> fl_mpool = mpool ;
131- flist -> fl_header_space = header_space ;
132114 flist -> fl_alignment = alignment ;
133- flist -> fl_elem_size = align_to (flist -> fl_elem_size , flist -> fl_alignment );
134115 if (num_elements_to_alloc )
135116 return ompi_free_list_grow (flist , num_elements_to_alloc );
136117 return OMPI_SUCCESS ;
137118}
138119
139120int ompi_free_list_grow (ompi_free_list_t * flist , size_t num_elements )
140121{
141- unsigned char * ptr ;
122+ unsigned char * ptr , * mpool_alloc_ptr = NULL ;
142123 ompi_free_list_memory_t * alloc_ptr ;
143- size_t i , alloc_size ;
144- mca_mpool_base_registration_t * user_out = NULL ;
124+ size_t i , alloc_size , head_size , elem_size = 0 ;
125+ mca_mpool_base_registration_t * reg = NULL ;
145126
146- if (flist -> fl_max_to_alloc > 0 )
147- if (flist -> fl_num_allocated + num_elements > flist -> fl_max_to_alloc )
127+ if (flist -> fl_max_to_alloc > 0 )
128+ if (flist -> fl_num_allocated + num_elements > flist -> fl_max_to_alloc )
148129 num_elements = flist -> fl_max_to_alloc - flist -> fl_num_allocated ;
149130
150- if (num_elements == 0 )
131+ if (num_elements == 0 )
151132 return OMPI_ERR_TEMP_OUT_OF_RESOURCE ;
152133
153- alloc_size = num_elements * flist -> fl_elem_size +
154- sizeof (ompi_free_list_memory_t ) + flist -> fl_header_space +
134+ head_size = (NULL == flist -> fl_mpool ) ? flist -> fl_elem_size :
135+ flist -> fl_elem_class -> cls_sizeof ;
136+ head_size = OPAL_ALIGN (head_size , flist -> fl_alignment , size_t );
137+
138+ /* calculate head allocation size */
139+ alloc_size = num_elements * head_size + sizeof (ompi_free_list_memory_t ) +
155140 flist -> fl_alignment ;
156141
157- if (NULL != flist -> fl_mpool )
158- alloc_ptr = (ompi_free_list_memory_t * )flist -> fl_mpool -> mpool_alloc (flist -> fl_mpool ,
159- alloc_size , 0 , MCA_MPOOL_FLAGS_CACHE_BYPASS , & user_out );
160- else
161- alloc_ptr = (ompi_free_list_memory_t * )malloc (alloc_size );
142+ alloc_ptr = (ompi_free_list_memory_t * )malloc (alloc_size );
162143
163144 if (NULL == alloc_ptr )
164145 return OMPI_ERR_TEMP_OUT_OF_RESOURCE ;
165146
166- /* make the alloc_ptr a list item, save the chunk in the allocations list, and
167- have ptr point to memory right after the list item structure */
168- OBJ_CONSTRUCT (alloc_ptr , ompi_free_list_memory_t );
169- opal_list_append (& (flist -> fl_allocations ), (opal_list_item_t * ) alloc_ptr );
147+ /* allocate the rest from the mpool */
148+ if (flist -> fl_mpool != NULL ) {
149+ elem_size = OPAL_ALIGN (flist -> fl_elem_size -
150+ flist -> fl_elem_class -> cls_sizeof , flist -> fl_alignment , size_t );
151+ if (elem_size != 0 ) {
152+ mpool_alloc_ptr = flist -> fl_mpool -> mpool_alloc (flist -> fl_mpool ,
153+ num_elements * elem_size , flist -> fl_alignment ,
154+ MCA_MPOOL_FLAGS_CACHE_BYPASS , & reg );
155+ if (NULL == mpool_alloc_ptr ) {
156+ free (alloc_ptr );
157+ return OMPI_ERR_TEMP_OUT_OF_RESOURCE ;
158+ }
159+ }
160+ }
170161
171- alloc_ptr -> registration = user_out ;
162+ /* make the alloc_ptr a list item, save the chunk in the allocations list,
163+ * and have ptr point to memory right after the list item structure */
164+ OBJ_CONSTRUCT (alloc_ptr , ompi_free_list_memory_t );
165+ opal_list_append (& (flist -> fl_allocations ), (opal_list_item_t * )alloc_ptr );
172166
173- ptr = (unsigned char * ) alloc_ptr + sizeof (ompi_free_list_memory_t );
167+ alloc_ptr -> registration = reg ;
168+ alloc_ptr -> base_ptr = mpool_alloc_ptr ;
174169
175- ptr = (unsigned char * )( align_to (( size_t ) ptr + flist -> fl_header_space ,
176- flist -> fl_alignment ) - flist -> fl_header_space );
170+ ptr = (unsigned char * )alloc_ptr + sizeof ( ompi_free_list_memory_t );
171+ ptr = OPAL_ALIGN_PTR ( ptr , flist -> fl_alignment , unsigned char * );
177172
178173 for (i = 0 ; i < num_elements ; i ++ ) {
179174 ompi_free_list_item_t * item = (ompi_free_list_item_t * )ptr ;
180- item -> user_data = user_out ;
175+ item -> registration = reg ;
176+ item -> ptr = mpool_alloc_ptr ;
181177
182178 OBJ_CONSTRUCT_INTERNAL (item , flist -> fl_elem_class );
183179
184180 opal_atomic_lifo_push (& (flist -> super ), & (item -> super ));
185- ptr += flist -> fl_elem_size ;
181+ ptr += head_size ;
182+ mpool_alloc_ptr += elem_size ;
186183 }
187184
188185 flist -> fl_num_allocated += num_elements ;
0 commit comments