Thread Scheduling and Symbian OS (SOS) Mutex
SOS Thread
Symbian OS (SOS) thread is built on nanokernel thread to provide support for user mode threads. DThread represents Symbian OS thread. For user, RThread is given, which is a handle to the thread (which is derived from RHandleBase).
Each SOS thread object contains a nanokernel thread object and the kernel schedules this thread. So, each SOS thread will have two stacks, one for user mode thread and another one for nanokernel thread. Apart from this, each SOS thread will also have:
Set of fast and slow executive functions to enable user-mode thread to gain access to kernel functionality.
An exception handler
Trap handler
An exit handler
Active Scheduler
Pointer to owning process
Its heap
SOS Thread State
SOS thread can go to any of below 10 states, which are called as M State.
ECreated: initial state of SOS Thread
EDead: final state of SOS Thread
EReady: not waiting on any SOS kernel wait objects (semaphore, mutex). A thread waiting/suspended on a nanokernel wait object (fast semaphore) can also have this state.
EWaitSemaphore: blocked waiting SOS semaphore.
EWaitSemaphoreSuspended: another thread has explicitly suspended this thread after it blocked on a SOS semaphore.
EWaitMutex: blocked waiting SOS mutex.
EWaitMutexSuspended: another thread has explicitly suspended this thread after it blocked on a SOS mutex.
EWaitMutexPending: woken up from EWaitMutex state, but not yet claimed the mutex.
EWaitCondVar: blocked waiting SOS conditional variable.
EWaitCondVarSuspended: another thread has explicitly suspended this thread after it blocked on a SOS conditional variable.
Each SOS thread will have one member iWaitObj which points to the wait object which it is waiting on, which can be semaphore or mutex or conditional variable.
Notice that, there are 3 states associated with SOS mutex: EWaitMutex, EWaitMutexSuspended and EWaitMutexPending. So, two threads, which are trying to execute same piece of code protected by a mutex will have different behavior with the way they get scheduled when compared with a scenario where a semaphore protects the same piece of code.
Considering a scenario like this:
{
TInt index = 0;
for ( ;index < KLoopCount; index++)
{
mutex.Wait();
//access some global/common data here
mutex.Signal();
}
}
Assuming two threads (lets say ThreadOne and ThreadTwo) execute same function at some point of time. If ThreadOne gets into this function first and acquires the mutex by executing mutex.Wait(), and assuming that, its been preempted by the scheduler by some means. So, ThreadTwo will acquire the CPU and when it enters the same function, it will go to EWaitMutex state when it tries to acquire the mutex, which is been held by the ThreadOne. So, this thread will be in blocked state and at sometimes, ThreadOne will resume its execution when scheduler schedules it. It will release the mutex by executing mutex.Signal() which will change the state of ThreadTwo to EWaitMutexPending. This does not mean that TheradTwo will resume the execution by blocking ThreadOne!
ThreadOne will continue to run till its time slice expires (which is by default 20 milliseconds) or till it terminates or till it blocks/suspends by some means. ThreadTwo wont resume its execution even though ThreadOne has released the mutex on which ThreadTwo was waiting.
If semaphore was used instead of mutex in the above function, then the behavior is different. When ThreadOne releases the semaphore, then ThreadTwo will resume the execution, which was in EWaitSemaphore state. So, ThreasOne will be blocked now. It is because, there are only two thread states associated with SOS semaphore ( EWaitSemaphore , EWaitSemaphoreSuspended ).






> Thread Scheduling and Symbian OS (SOS) Mutex
> Thread Scheduling and Symbian OS (SOS) Mutex
No, it will resume, but as I have mentioned earlier, second thread will be resumed only after the first thread, which is holding the mutex goes to blocked/terminated/sleep mode after releasing the mutex. In this case, as none of the thread will be holding mutex, 2nd thread will resume. U can check this one by inserting User::After(0); after mutex.Signal(); statement, in which case, after releasing the mutex, thread will go to sleep state and other thread will resume now.
Regards Girish
> Thread Scheduling and Symbian OS (SOS) Mutex
Hi Girish, Thanks for the posting.
I am just facing the same condition that you have described in the article. I have released the mutex by calling the signal() from the first thread, and I have even used a User::After() of 2 seconds, but still the the control does not pass to the second thread.
The call to User::After() is not the next statement after signal() but after few statement.
What might be the reason for this ?
Is there any other way that we can force the second thread to take the control ?
Thanks and regards Anand
> Thread Scheduling and Symbian OS (SOS) Mutex
Hi Girish, Sorry you were correct, I had done a mistake by calling wait twice and signalling only once(This was becasue of many threads involved). so I was facing the problem that I have mentioned above. But now it is solved.
Thanks and regards, Anand