Commit a8d592ef authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Fix wrong spinrw function name exports. Add new spinrw_write_to_read function.

Detail:
  h/spinrw - Fix header file to use the correct names for the write try lock & sleep lock functions.
  s/spinrw - Add new spinrw_write_to_read function, which atomically converts a held write lock to a read lock. This can be useful if you have a long routine which needs to update some state and then perform extra actions based on the new value - if the write occurs at the start of the routine, the write access can then be downgraded to read access, allowing interrupts + concurrent read access, while still making sure the data hasn't changed from what was written.
Admin:
  Tested on OMAP3, OMAP4


Version 0.05. Tagged as 'SyncLib-0_05'
parent eaab0406
/* (0.04)
/* (0.05)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.04
#define Module_MajorVersion_CMHG 0.05
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 06 Jun 2017
#define Module_Date_CMHG 07 May 2018
#define Module_MajorVersion "0.04"
#define Module_Version 4
#define Module_MajorVersion "0.05"
#define Module_Version 5
#define Module_MinorVersion ""
#define Module_Date "06 Jun 2017"
#define Module_Date "07 May 2018"
#define Module_ApplicationDate "06-Jun-17"
#define Module_ApplicationDate "07-May-18"
#define Module_ComponentName "SyncLib"
#define Module_ComponentPath "bsd/RiscOS/Sources/Lib/SyncLib"
#define Module_FullVersion "0.04"
#define Module_HelpVersion "0.04 (06 Jun 2017)"
#define Module_LibraryVersionInfo "0:4"
#define Module_FullVersion "0.05"
#define Module_HelpVersion "0.05 (07 May 2018)"
#define Module_LibraryVersionInfo "0:5"
......@@ -63,7 +63,7 @@ typedef struct
* \arg lock Pointer to spinrwlock block.
* \return Whether the lock succeeded.
*/
bool spinrw_try_write_lock(spinrwlock_t *lock);
bool spinrw_write_try_lock(spinrwlock_t *lock);
/** Wait (forever if necessary) until the lock is not held for reading or
* writing, then claim a write lock and disable IRQs.
......@@ -78,7 +78,7 @@ void spinrw_write_lock(spinrwlock_t *lock);
* Must be entered in privileged mode.
* \arg lock Pointer to spinrwlock block.
*/
void spinrw_sleep_write_lock(spinrwlock_t *lock);
void spinrw_write_sleep_lock(spinrwlock_t *lock);
/** Release a write lock and restore the IRQ disable state to how it was when
* the write lock was claimed.
......@@ -101,4 +101,14 @@ void spinrw_read_lock(spinrwlock_t *lock);
*/
void spinrw_read_unlock(spinrwlock_t *lock);
/** Atomically downgrade a held write lock to a read lock. This is equivalent
* to a call to spinrw_write_unlock followed by spinrw_read_lock, except that
* the atomic nature means that no other threads will be able to gain a write
* lock inbetween the unlock & lock operations, thereby guaranteeing that the
* protected data will not have been changed.
* Must be entered in privileged mode.
* \arg lock Pointer to spinrwlock block.
*/
void spinrw_write_to_read(spinrwlock_t *lock);
#endif
......@@ -65,7 +65,7 @@ Bool_True * 1
IF SupportARMv6 :LAND: NoARMv6 ; i.e. run-time detection is required
EXPORT spinrw_init
spinrw_init ROUT
FunctionEntry "v1-v2"
FunctionEntry "v1-v3"
[ zM
StaticBaseFromSL lr
]
......@@ -76,19 +76,22 @@ spinrw_init ROUT
ADREQ a4, spinrw_write_unlock_uniproc
ADREQ v1, spinrw_read_lock_uniproc
ADREQ v2, spinrw_read_unlock_uniproc
ADREQ v3, spinrw_write_to_read_uniproc
ADRNE a1, spinrw_write_try_lock_smp
ADRNE a2, spinrw_write_lock_smp
ADRNE a3, spinrw_write_sleep_lock_smp
ADRNE a4, spinrw_write_unlock_smp
ADRNE v1, spinrw_read_lock_smp
ADRNEL v2, spinrw_read_unlock_smp
ADRNEL v3, spinrw_write_to_read_smp
Store a1, lr, write_try_lock_fn, ip
Store a2, lr, write_lock_fn, ip
Store a3, lr, write_sleep_lock_fn, ip
Store a4, lr, write_unlock_fn, ip
Store v1, lr, read_lock_fn, ip
Store v2, lr, read_unlock_fn, ip
Return "v1-v2"
Store v3, lr, write_to_read_fn, ip
Return "v1-v3"
ENDIF
......@@ -99,6 +102,7 @@ spinrw_write_sleep_lock * spinrw_write_sleep_lock_uniproc
spinrw_write_unlock * spinrw_write_unlock_uniproc
spinrw_read_lock * spinrw_read_lock_uniproc
spinrw_read_unlock * spinrw_read_unlock_uniproc
spinrw_write_to_read * spinrw_write_to_read_uniproc
ELIF :LNOT: NoARMv6
spinrw_write_try_lock * spinrw_write_try_lock_smp
spinrw_write_lock * spinrw_write_lock_smp
......@@ -106,6 +110,7 @@ spinrw_write_sleep_lock * spinrw_write_sleep_lock_smp
spinrw_write_unlock * spinrw_write_unlock_smp
spinrw_read_lock * spinrw_read_lock_smp
spinrw_read_unlock * spinrw_read_unlock_smp
spinrw_write_to_read * spinrw_write_to_read_smp
ELSE
spinrw_write_try_lock ROUT
[ zM
......@@ -137,6 +142,11 @@ spinrw_read_unlock ROUT
StaticBaseFromSL a4
]
Load pc, a4, read_unlock_fn, ip
spinrw_write_to_read ROUT
[ zM
StaticBaseFromSL a4
]
Load pc, a4, write_to_read_fn, ip
ENDIF
......@@ -340,6 +350,21 @@ spinrw_read_unlock_$variant ROUT
]
Return , LinkNotStacked
spinrw_write_to_read_$variant ROUT
MOV a3, #Mutex_Unlocked
MOV a4, #Mutex_Locked
MetaLock , a4, ip
LDR ip, SavedCPSR
MOV a4, #-Counter_Read
STR a4, Counter
; N.B. pollword remains unchanged (zero), since write lock can't be claimed yet
MetaUnlock ip, a3
[ variant = "smp"
BarrierSync
CPUEventSend
]
Return , LinkNotStacked
]
[ variant = "uniproc"
variant SETS "smp"
......@@ -365,6 +390,8 @@ read_lock_fn
DCD 0
read_unlock_fn
DCD 0
write_to_read_fn
DCD 0
ENDIF
......@@ -375,6 +402,7 @@ read_unlock_fn
EXPORT spinrw_write_unlock
EXPORT spinrw_read_lock
EXPORT spinrw_read_unlock
EXPORT spinrw_write_to_read
END
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment