* @brief This function will create a mempool object and allocate the memory pool from * heap. * * @param name is the name of memory pool. * * @param block_count is the count of blocks in memory pool. * * @param block_size is the size for each block. * * @return the created mempool object */
| 174 | * @return the created mempool object |
| 175 | */ |
| 176 | rt_mp_t rt_mp_create(const char *name, |
| 177 | rt_size_t block_count, |
| 178 | rt_size_t block_size) |
| 179 | { |
| 180 | rt_uint8_t *block_ptr; |
| 181 | struct rt_mempool *mp; |
| 182 | rt_size_t offset; |
| 183 | |
| 184 | RT_DEBUG_NOT_IN_INTERRUPT; |
| 185 | |
| 186 | /* parameter check */ |
| 187 | RT_ASSERT(name != RT_NULL); |
| 188 | RT_ASSERT(block_count > 0 && block_size > 0); |
| 189 | |
| 190 | /* allocate object */ |
| 191 | mp = (struct rt_mempool *)rt_object_allocate(RT_Object_Class_MemPool, name); |
| 192 | /* allocate object failed */ |
| 193 | if (mp == RT_NULL) |
| 194 | return RT_NULL; |
| 195 | |
| 196 | /* initialize memory pool */ |
| 197 | block_size = RT_ALIGN(block_size, RT_ALIGN_SIZE); |
| 198 | mp->block_size = block_size; |
| 199 | mp->size = (block_size + sizeof(rt_uint8_t *)) * block_count; |
| 200 | |
| 201 | /* allocate memory */ |
| 202 | mp->start_address = rt_malloc((block_size + sizeof(rt_uint8_t *)) * |
| 203 | block_count); |
| 204 | if (mp->start_address == RT_NULL) |
| 205 | { |
| 206 | /* no memory, delete memory pool object */ |
| 207 | rt_object_delete(&(mp->parent)); |
| 208 | |
| 209 | return RT_NULL; |
| 210 | } |
| 211 | |
| 212 | mp->block_total_count = block_count; |
| 213 | mp->block_free_count = mp->block_total_count; |
| 214 | |
| 215 | /* initialize suspended thread list */ |
| 216 | rt_list_init(&(mp->suspend_thread)); |
| 217 | |
| 218 | /* initialize free block list */ |
| 219 | block_ptr = (rt_uint8_t *)mp->start_address; |
| 220 | for (offset = 0; offset < mp->block_total_count; offset ++) |
| 221 | { |
| 222 | *(rt_uint8_t **)(block_ptr + offset * (block_size + sizeof(rt_uint8_t *))) |
| 223 | = block_ptr + (offset + 1) * (block_size + sizeof(rt_uint8_t *)); |
| 224 | } |
| 225 | |
| 226 | *(rt_uint8_t **)(block_ptr + (offset - 1) * (block_size + sizeof(rt_uint8_t *))) |
| 227 | = RT_NULL; |
| 228 | |
| 229 | mp->block_list = block_ptr; |
| 230 | rt_spin_lock_init(&(mp->spinlock)); |
| 231 | |
| 232 | return mp; |
| 233 | } |