The Fast Lock is a read/write lock in the WinCE kernel.
Structure:
struct _FAST_LOCK {
PFAST_LOCK pPrevOwned; // Previous node in 2-D queue
PFAST_LOCK pNextOwned; // Next node in 2-D queue
PFAST_LOCK pUpOwned; // Node above in 2-D queue
PFAST_LOCK pDownOwned; // Node below in 2-D queue
BYTE bListedPrio; // priority
BYTE bListed; // is the lockowned by a writer
WORD _unused; //
TWO_D_QUEUEproxyqueue; // 2-D priorityqueue
PTHREAD pOwner; // owner of the syncobject
LONG lLock; // lLock value
DWORD dwContention; // contention count
};
A global fast lock of the process is initialized when aprocess is created, and it is released when a process is deleted.
If AcquireReadLock()/AcquireWriteLock() is called, the currentthread should be blocked. Os will do rescheduling.
If ReleaseReadLock()/ReleaseWriteLock() is called, thecorresponding read/write lock will be released, the blocked thread will bebrought back to running state .
AcquireReadLock()/AcquireWriteLock()
In this function, an interlocked function callsSCHL_WaitForReadLock()/SCHL_WaitForwriteLock()
, the AcquireReadLock is an entry API interface.
SCHL_WaitForReadLock()/SCHL_WaitForWriteLock
In this function, there is an important structure, “PROXY”.The structure is a bridge of connected the fast lock andthe owner thread of sync object.
SetupProxy()put the current thread and fast lock into the “proxy” object . the “proxy”object is a base unit of locked the handle .
If the current thread’s priority is higher than any waiter , and no one has the exclusive lock , so the currentthread is not blocked , else it called the BlockOnFastLock()to lock the current thread.
struct _PROXY {
PPROXY pQPrev; // Previous node in 2-D queue
PPROXY pQNext; // Next node in 2-D queue
PPROXY pQUp; // Node above in 2-D queue
PPROXY pQDown; // Node below in 2-D queue
BYTE prio; // Current prio we're enqueued on (forthread - current priority)
BYTE bType; // Type of object we're blocked on (varioususe for CS/mutex, indicate if the node is in a thread "owned list")
WORD wCount; // Count matching thread's wCount (various usefor CS/mutex, LockCount for mutex, signature for CS)
PPROXY pThLinkNext; // Next proxy for this thread
LPVOID pObject; // Pointer to object we're blocked on
PTHREAD pTh; // Thread "owning" thisproxy
DWORD dwRetVal; // Return value if this is why we wakeup
};
BlockOnFastLock ()
This function’s logic is same with logic of threadreschedule.
The first, take the proxy object back to the fast lock’sproxyqueue, because the proxy object contain the current thread and the fastlock, as others word, take the current thread back to a queue. The proxyqueueis a 2-D queue in the fast lock. It stored the current thread of blocked.
The second, if need, insert the fast lock into the owner’sowned list.
The third, if the current thread back to the proxyqueuesuccessfully, adjust owner priority to run owner thread. The newprio is thehigh thread’s priority in the owner thread’s all sync object owner thread list.The oldprio is priority of the owner thread.
The last, compared the newprio and oldprio, if newprio isless than oldprio , that mean newprio priority is higher than oldprio priority,setthe owner thread’s priority by newprio and run owner thread of sync object.
Sequence diagram:
ReleaseReadLock()/ReleaseWriteLock()
This function can release the Read/Write lock ,it will called the DoReleaseFastLock()to release in the kernel .
DoReleaseFastLock()
Inthis function, the lock is released, and the owner thread of sync object iswake up , and tried to make run .
The fast lock is implemented with one thing in mind, it isfast. There is no nesting support whatsoever. The fast lock can locked theresource fast.