Why are _mem_test and _mem_free changing the same pointers in the memory pool?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Why are _mem_test and _mem_free changing the same pointers in the memory pool?

727 Views
donmarquardt
Contributor I

From _mem_free (this is in all versions of MQX I have access to ...)

/* Reset the _mem_test pointers */
mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK = (STOREBLOCK_STRUCT_PTR) mem_pool_ptr->POOL_PTR;
mem_pool_ptr->POOL_FREE_CHECK_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR;

_INT_ENABLE();

And from _mem_test

  next_block_ptr = NEXT_PHYS(mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK);
  if (next_block_ptr->PREVBLOCK != mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK){
     mem_pool_ptr->POOL_BLOCK_IN_ERROR = next_block_ptr;
     _int_enable();
     result = MQX_CORRUPT_STORAGE_POOL;
     break;
  } /* Endif */
  mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK = next_block_ptr;

The problem, if I understand correctly, is that if _mem_free gets called from another task while _mem_test is running, the "POOL_PHYSICAL_CHECK_BLOCK" gets reset to the beginning of the pool and the _mem_test starts over again.

The MQX Manual states...

The function can be called by only one task at a time because it keeps state-inprogress

variables that MQX controls. This mechanism lets other tasks allocate

and free memory while _mem_test() runs.

In the case of my system this means that my call to _mem_test never completes.

Does anyone have a solution that does not disable interrupts for the duration of the _mem_test?

0 Kudos
4 Replies

483 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Don Marquardt,

Actually in _mem_free() and _mem_test(), the interrupt is disabled before the code starts to operate on the pointers, so when one task is running the _mem_test() while another invokes _mem_free(), the task switch would not happen when interrupt is disbaled, so I think you needn't worry about the case that _mem_free gets called from another task while _mem_test is running.

Hope that helps,


Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

483 Views
donmarquardt
Contributor I

I understand that. The problem is that although the pointers are being used "safely", if your system is doing a lot of mem allocs and frees, the pointer gets reset to the beginning of the free pool each time free is called.

That means that mem_test starts over at the beginning of the pool and potentially never finishes.

0 Kudos

483 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Don Marquardt,

Actually I am a little bit confused why you said "That means that mem_test starts over at the beginning of the pool and potentially never finishes." I agree _mem_test() starts from the beginning of the checking pointers when it is invoked after some task invokes _mem_free()  , but  during _mem_test() running, the context would not switch to other tasks , so _mem_alloc and _mem_free would not be possibly invoked during that period until _mem_test() is finished or task switching API is called explicitly in _mem_test() , so I don't understand in which case _mem_test() would never finish. Would you please help to clarify? Thanks for your patience!!

Have a nice weekend!!

B.R

Kan

0 Kudos

483 Views
donmarquardt
Contributor I

The issue is that both mem_test and mem_free reset the pointer(POOL_PHYSICAL_CHECK_BLOCK) used by mem_test.

at approx line 93 in mem_tesp.c...

  mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK = next_block_ptr;
  _int_enable();

   } /* Endwhile */

and in mem_free.c at approx line 243

   /* Reset the _mem_test pointers */

   mem_pool_ptr->POOL_PHYSICAL_CHECK_BLOCK =

      (STOREBLOCK_STRUCT_PTR)mem_pool_ptr->POOL_PTR;

So what happens is that mem_test will potentially start over again.

0 Kudos