57 lines
1.4 KiB
Plaintext
57 lines
1.4 KiB
Plaintext
R/W locking using 1 R/W spinlock and 1 event.
|
|
|
|
Reading:
|
|
* Take read lock
|
|
* Check if requested cluster is mapped into buffer
|
|
* If yes:
|
|
** Read from the buffer
|
|
* If no:
|
|
** Initiate block read operation
|
|
* Unlock
|
|
|
|
Writing:
|
|
(Start):
|
|
* Take write lock
|
|
* Check for free space in buffer
|
|
* If sufficient:
|
|
** Write current bio into buffer
|
|
** Modify translation maps
|
|
* If insufficient:
|
|
** (Insufficient) Check flush flag (no need for atomic/etc as already within buffer lock)
|
|
** If someone is already flushing:
|
|
*** Unlock
|
|
*** Wait until flushing ends using an event
|
|
*** Goto (Start)
|
|
** If no one is flushing yet:
|
|
*** Set flush flag
|
|
*** Remember current bio and initiate (Flush) operation
|
|
* Unlock
|
|
|
|
After (Flush) operation ends:
|
|
* Take write lock (writers are already blocked, this is to block readers)
|
|
* Clear buffer
|
|
* If the free sequence pointer can be moved without cleaning:
|
|
** Move pointer
|
|
** Perform own remembered write operation
|
|
** Unset flush flag
|
|
** Unlock
|
|
** Wake up waiting writers
|
|
* If not:
|
|
** Initiate cleaning process
|
|
** Unlock
|
|
|
|
After cleaning operation ends:
|
|
* Take write lock
|
|
* Modify translation maps
|
|
* Move free sequence pointer
|
|
* If there are no more pending cleaning operations:
|
|
** Perform own remembered write operation:
|
|
*** Write current bio into buffer
|
|
*** Modify translation maps
|
|
** Unset flush flag
|
|
** Unlock
|
|
** Wake up waiting writers
|
|
* Else:
|
|
** Initiate next cleaning operation
|
|
** Unlock
|