My memory allocation function originally used a Spin Lock to keep multiple tasks from allocating memory at the same time (manipulating and corrupting data fields).
However, some of my interrupt routines used memory allocation to create a new separate task, and this is where the problem is.
If a task is in the process of allocating memory and is interrupted, and the interrupt tries to allocate memory, the interrupt will loop forever in the SpinLock waiting for a lock.
Because the task that has the lock is actually the same task.
To resolve this problem i created a solution. I call it the MctLock method (Must Complete Task Lock)
It simply disables interrupts and re-enables them when MctUnlock is called if they were previously enabled.
I also use this method for adding, removing and switching tasks.
Here is the code:
Code: Select all
NAKED DWORD API MctLock()
{
__asm
{
pushfd;
pop EAX;
and EAX,0x200;
shr EAX,9;
CLI;
ret;
}
}
NAKED VOID API MctUnlock(DWORD LockValue)
{
__asm
{
push EAX;
mov EAX,[esp+8];
cmp EAX,0;
je DontEnableInterrupts;
STI;
DontEnableInterrupts:
pop EAX;
ret 4;
}
}
I'm worried however that this will cause slow performance, and that some interrupts might not fire at all or be missed since there disabled.
If anyone has seen this issue, how did you resolve this problem?
Any ideals or solutions to this kind of thing?