Mutex for task scheduler.

@bperrybap, thanks for the post.

I'm protecting particular resources and I don't want to block out other threads
...
For example, when a processor supports interrupts levels it is VERY useful to allow interrupts to nest
and interrupt each other because often the ISRs don't deal with the same resources.

If you are worried about the atomicity blocking ISR functions, not the actual mutex lock, then this is not the case. I have built this with interrupt routines in mind; the atomic blocking is only utilised during an unlock / lock operation or when reading the owner of a mutex/lock.

The atomic functionality is actually only there for ISR interaction. I'll explain below.

[Note] The API has slightly changed from what is above, m_Restore, m_Force, m_None are now the AtomicBlock definitions: Atomic_RestoreState, Atomic_Force, and Atomic_None.

Atomic_None is a recent addition to the AtomicBlock library which prevents it from emitting any blocking code. So a library, like the mutex, can be programmed around atomicity and have it disabled when not needed.

If you have data shared between only task scheduler 'tasks' ( not touched by ISR ), then you can safely use:

HMUTEX h_MyMutex = createMutex( Atomic_None );

An ISR+ISR or ISR+Task interaction would require a mutex with blocking capabilities.

ISR+Task is interesting as only the task would require blocking capabilities, the ISR has interrupts disabled by default ( I know for AVR anyway, ARM interrupts may operate differently. )

//Create a mutex with blocking capabilities.
HMUTEX h_TaskHandle = createMutex( Atomic_Force );

//ISR needs no atomic guarantee.
HMUTEX h_ISRHandle = duplicateHandle( h_TaskHandle, Atomic_None );

void loop(){
  if( acquireMutex( h_TaskHandle ) ){
    releaseMutex( h_TaskHandle );
  }
}

void ISR(){
  if( acquireMutex( h_ISRHandle ) ){
    releaseMutex( h_ISRHandle );
  }
}

This example is incomplete. It is to show mutex creation.

Here both the ISR and loop() funciton use the same mutex, just with different atomic contracts.

If an ISR is needed to be blocked entirely, the AtomicBlock library ( link in my sig ) is perfect for that.

I'll post the updated version ASAP, just doing a quick test.