@@ -75,7 +75,9 @@ static void mod_resource_init(struct processing_module *mod)
7575{
7676 struct module_data * md = & mod -> priv ;
7777 /* Init memory list */
78+ md -> resources .lvl2_active = false;
7879 list_init (& md -> resources .res_list );
80+ list_init (& md -> resources .lvl2_res_list );
7981 list_init (& md -> resources .free_cont_list );
8082 list_init (& md -> resources .cont_chunk_list );
8183 md -> resources .heap_usage = 0 ;
@@ -207,7 +209,10 @@ void *mod_balloc_align(struct processing_module *mod, size_t size, size_t alignm
207209 container -> ptr = ptr ;
208210 container -> size = size ;
209211 container -> type = MOD_RES_HEAP ;
210- list_item_prepend (& container -> list , & res -> res_list );
212+ if (res -> lvl2_active )
213+ list_item_prepend (& container -> list , & res -> lvl2_res_list );
214+ else
215+ list_item_prepend (& container -> list , & res -> res_list );
211216
212217 res -> heap_usage += size ;
213218 if (res -> heap_usage > res -> heap_high_water_mark )
@@ -258,7 +263,10 @@ void *mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size,
258263 container -> ptr = ptr ;
259264 container -> size = size ;
260265 container -> type = MOD_RES_HEAP ;
261- list_item_prepend (& container -> list , & res -> res_list );
266+ if (res -> lvl2_active )
267+ list_item_prepend (& container -> list , & res -> lvl2_res_list );
268+ else
269+ list_item_prepend (& container -> list , & res -> res_list );
262270
263271 res -> heap_usage += size ;
264272 if (res -> heap_usage > res -> heap_high_water_mark )
@@ -298,7 +306,10 @@ mod_data_blob_handler_new(struct processing_module *mod)
298306 container -> bhp = bhp ;
299307 container -> size = 0 ;
300308 container -> type = MOD_RES_BLOB_HANDLER ;
301- list_item_prepend (& container -> list , & res -> res_list );
309+ if (res -> lvl2_active )
310+ list_item_prepend (& container -> list , & res -> lvl2_res_list );
311+ else
312+ list_item_prepend (& container -> list , & res -> res_list );
302313
303314 return bhp ;
304315}
@@ -334,7 +345,10 @@ const void *mod_fast_get(struct processing_module *mod, const void * const dram_
334345 container -> sram_ptr = ptr ;
335346 container -> size = 0 ;
336347 container -> type = MOD_RES_FAST_GET ;
337- list_item_prepend (& container -> list , & res -> res_list );
348+ if (res -> lvl2_active )
349+ list_item_prepend (& container -> list , & res -> lvl2_res_list );
350+ else
351+ list_item_prepend (& container -> list , & res -> res_list );
338352
339353 return ptr ;
340354}
@@ -375,15 +389,29 @@ int mod_free(struct processing_module *mod, const void *ptr)
375389{
376390 struct module_resources * res = & mod -> priv .resources ;
377391 struct module_resource * container ;
378- struct list_item * res_list ;
392+ struct list_item * iterator ;
379393
380394 MEM_API_CHECK_THREAD (res );
381395 if (!ptr )
382396 return 0 ;
383397
398+ if (res -> lvl2_active ) {
399+ /* If level 2 is active, search it first */
400+ list_for_item (iterator , & res -> lvl2_res_list ) {
401+ container = container_of (iterator , struct module_resource , list );
402+ if (container -> ptr == ptr ) {
403+ int ret = free_contents (mod , container );
404+
405+ list_item_del (& container -> list );
406+ container_put (mod , container );
407+ return ret ;
408+ }
409+ }
410+ }
411+
384412 /* Find which container keeps this memory */
385- list_for_item (res_list , & res -> res_list ) {
386- container = container_of (res_list , struct module_resource , list );
413+ list_for_item (iterator , & res -> res_list ) {
414+ container = container_of (iterator , struct module_resource , list );
387415 if (container -> ptr == ptr ) {
388416 int ret = free_contents (mod , container );
389417
@@ -415,6 +443,52 @@ void mod_fast_put(struct processing_module *mod, const void *sram_ptr)
415443EXPORT_SYMBOL (mod_fast_put );
416444#endif
417445
446+ /**
447+ * Activate second allocation level. All allocations after this call
448+ * are considered 2nd level allocations. The all the 2nd level
449+ * allocations can freed with a single mod_free_all_lvl2() call.
450+ *
451+ * @param mod Pointer to module to start 2nd level allocations.
452+ */
453+ void mod_alloc_lvl2_init (struct processing_module * mod )
454+ {
455+ struct module_resources * res = & mod -> priv .resources ;
456+
457+ #if defined(__ZEPHYR__ )
458+ __ASSERT (!res -> lvl2_active , "Level 2 allocations already activated" );
459+ #endif
460+ res -> lvl2_active = true;
461+ }
462+
463+ /**
464+ * Free all second level allocations and turn off level 2 allocation.
465+ * Another mod_alloc_lvl2_init() call activates 2nd level again.
466+ *
467+ * @param mod Pointer to module to free 2nd level allocations.
468+ */
469+ void mod_free_all_lvl2 (struct processing_module * mod )
470+ {
471+ struct module_resources * res = & mod -> priv .resources ;
472+ struct list_item * iterator ;
473+ struct list_item * _iterator ;
474+
475+ MEM_API_CHECK_THREAD (res );
476+
477+ if (!res -> lvl2_active )
478+ return ;
479+
480+ /* Free all contents found in lvl2 containers */
481+ list_for_item_safe (iterator , _iterator , & res -> lvl2_res_list ) {
482+ struct module_resource * container =
483+ container_of (iterator , struct module_resource , list );
484+
485+ free_contents (mod , container );
486+ list_item_del (& container -> list );
487+ container_put (mod , container );
488+ }
489+ res -> lvl2_active = false;
490+ }
491+
418492int module_prepare (struct processing_module * mod ,
419493 struct sof_source * * sources , int num_of_sources ,
420494 struct sof_sink * * sinks , int num_of_sinks )
0 commit comments