Tue 21 Aug 2007 11:10:29 PM UTC, comment #7:
My sys_arch differs slightly from the unix, and I don't have a unix test bed, so I'm putting what I got, which should be readily translatable to the unix version...
Note that each function that contains a critical section declares a single static semaphore that's local to the function. With this method the critical section is function-local, rather than system-wide, which appears to be the correct semantics, given the code that is current using it.
In sys_arch.h
--------------
#define SYS_ARCH_DECL_PROTECT(lev) static sys_sem_t localsem = (sys_sem_t)0xffffffff; static unsigned protct=0; static thread_handle_t protthread=(thread_handle_t)0xffffffff; if(localsem==(sys_sem_t)0xffffffff) localsem=sys_sem_new(1);
#define SYS_ARCH_PROTECT(lev) sys_arch_protect(localsem, &protct, &protthread)
#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(localsem, &protct, &protthread)
In sys_arch.c
-------------
sys_prot_t sys_arch_protect(sys_sem_t localsem, unsigned protct, thread_handle_t protthread)
{
if(protthread!=currentThreadHandle()) {
//We have a new thread that wants to lock some critical session. Wait until it gets it.
sys_arch_sem_wait(localsem,0);
*protthread = currentThreadHandle();
*protct=1;
} else {
//The thread handle matches, so this thread already has it locked!Bump the count
(*protct)++;
}
return 0;
}
void sys_arch_unprotect(sys_sem_t localsem, unsigned protct, thread_handle_t protthread)
{
LWIP_ASSERT("sys_arch_unprotect: Not the current critical section locker.",
*protthread==currentThreadHandle());
//I have it locked, unprotecting
(*protct)--;
if(*protct==0) {
//reset the thread id
*protthread=0xffffffff;
//release the semaphore
sys_sem_signal(localsem);
}
|