Introduce syncArbitrateAddress/WithTimeout (replaces __sync_get_arbiter)
This commit is contained in:
parent
528f8feb0b
commit
9c1c847388
@ -915,16 +915,7 @@ Result svcCreateAddressArbiter(Handle *arbiter);
|
||||
* @param addr A pointer to a s32 value.
|
||||
* @param type Type of action to be performed by the arbiter
|
||||
* @param value Number of threads to signal if using @ref ARBITRATION_SIGNAL, or the value used for comparison.
|
||||
*
|
||||
* This will perform an arbitration based on #type. The comparisons are done between #value and the value at the address #addr.
|
||||
*
|
||||
* @code
|
||||
* s32 val=0;
|
||||
* // Does *nothing* since val >= 0
|
||||
* svcCreateAddressArbiter(arbiter,&val,ARBITRATION_WAIT_IF_LESS_THAN,0,0);
|
||||
* // Thread will wait for a signal or wake up after 10000000 nanoseconds because val < 1.
|
||||
* svcCreateAddressArbiter(arbiter,&val,ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT,1,10000000ULL);
|
||||
* @endcode
|
||||
* @warning Please use \ref syncArbitrateAddress or \ref syncArbitrateAddressWithTimeout instead.
|
||||
*/
|
||||
Result svcArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value, s64 nanoseconds);
|
||||
|
||||
|
@ -126,10 +126,36 @@ static inline bool __strexb(u8* addr, u8 val)
|
||||
#define AtomicSwap(ptr, value) __atomic_exchange_n((u32*)(ptr), (value), __ATOMIC_SEQ_CST)
|
||||
|
||||
/**
|
||||
* @brief Retrieves the synchronization subsystem's address arbiter handle.
|
||||
* @return The synchronization subsystem's address arbiter handle.
|
||||
* @brief Function used to implement user-mode synchronization primitives.
|
||||
* @param addr Pointer to a signed 32-bit value whose address will be used to identify waiting threads.
|
||||
* @param type Type of action to be performed by the arbiter
|
||||
* @param value Number of threads to signal if using @ref ARBITRATION_SIGNAL, or the value used for comparison.
|
||||
*
|
||||
* This will perform an arbitration based on #type. The comparisons are done between #value and the value at the address #addr.
|
||||
*
|
||||
* @code
|
||||
* s32 val=0;
|
||||
* // Does *nothing* since val >= 0
|
||||
* syncArbitrateAddress(&val,ARBITRATION_WAIT_IF_LESS_THAN,0);
|
||||
* @endcode
|
||||
*/
|
||||
Handle __sync_get_arbiter(void);
|
||||
Result syncArbitrateAddress(s32* addr, ArbitrationType type, s32 value);
|
||||
|
||||
/**
|
||||
* @brief Function used to implement user-mode synchronization primitives (with timeout).
|
||||
* @param addr Pointer to a signed 32-bit value whose address will be used to identify waiting threads.
|
||||
* @param type Type of action to be performed by the arbiter (must use \ref ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT or \ref ARBITRATION_DECREMENT_AND_WAIT_IF_LESS_THAN_TIMEOUT)
|
||||
* @param value Number of threads to signal if using @ref ARBITRATION_SIGNAL, or the value used for comparison.
|
||||
*
|
||||
* This will perform an arbitration based on #type. The comparisons are done between #value and the value at the address #addr.
|
||||
*
|
||||
* @code
|
||||
* s32 val=0;
|
||||
* // Thread will wait for a signal or wake up after 10000000 nanoseconds because val < 1.
|
||||
* syncArbitrateAddressWithTimeout(&val,ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT,1,10000000LL);
|
||||
* @endcode
|
||||
*/
|
||||
Result syncArbitrateAddressWithTimeout(s32* addr, ArbitrationType type, s32 value, s64 timeout_ns);
|
||||
|
||||
/**
|
||||
* @brief Initializes a light lock.
|
||||
|
@ -28,8 +28,6 @@ static vu8* gspEventData;
|
||||
|
||||
static void gspEventThreadMain(void *arg);
|
||||
|
||||
Handle __sync_get_arbiter(void);
|
||||
|
||||
Result gspInit(void)
|
||||
{
|
||||
Result res=0;
|
||||
@ -103,7 +101,7 @@ GSPGPU_Event gspWaitForAnyEvent(void)
|
||||
}
|
||||
} while (__strex(&gspLastEvent, -1));
|
||||
if (x < 0)
|
||||
svcArbitrateAddress(__sync_get_arbiter(), (u32)&gspLastEvent, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0);
|
||||
syncArbitrateAddress(&gspLastEvent, ARBITRATION_WAIT_IF_LESS_THAN, 0);
|
||||
} while (x < 0);
|
||||
return (GSPGPU_Event)x;
|
||||
}
|
||||
@ -177,7 +175,7 @@ void gspEventThreadMain(void *arg)
|
||||
do
|
||||
__ldrex(&gspLastEvent);
|
||||
while (__strex(&gspLastEvent, curEvt));
|
||||
svcArbitrateAddress(__sync_get_arbiter(), (u32)&gspLastEvent, ARBITRATION_SIGNAL, 1, 0);
|
||||
syncArbitrateAddress(&gspLastEvent, ARBITRATION_SIGNAL, 1);
|
||||
gspEventCounts[curEvt]++;
|
||||
}
|
||||
}
|
||||
|
@ -16,9 +16,14 @@ void __sync_fini(void)
|
||||
svcCloseHandle(arbiter);
|
||||
}
|
||||
|
||||
Handle __sync_get_arbiter(void)
|
||||
Result syncArbitrateAddress(s32* addr, ArbitrationType type, s32 value)
|
||||
{
|
||||
return arbiter;
|
||||
return svcArbitrateAddress(arbiter, (u32)addr, type, value, 0);
|
||||
}
|
||||
|
||||
Result syncArbitrateAddressWithTimeout(s32* addr, ArbitrationType type, s32 value, s64 timeout_ns)
|
||||
{
|
||||
return svcArbitrateAddress(arbiter, (u32)addr, type, value, timeout_ns);
|
||||
}
|
||||
|
||||
void LightLock_Init(LightLock* lock)
|
||||
@ -51,7 +56,7 @@ void LightLock_Lock(LightLock* lock)
|
||||
while (bAlreadyLocked)
|
||||
{
|
||||
// Wait for the lock holder thread to wake us up
|
||||
svcArbitrateAddress(arbiter, (u32)lock, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0);
|
||||
syncArbitrateAddress(lock, ARBITRATION_WAIT_IF_LESS_THAN, 0);
|
||||
|
||||
// Try to lock again
|
||||
do
|
||||
@ -97,7 +102,7 @@ void LightLock_Unlock(LightLock* lock)
|
||||
|
||||
if (val > 1)
|
||||
// Wake up exactly one thread
|
||||
svcArbitrateAddress(arbiter, (u32)lock, ARBITRATION_SIGNAL, 1, 0);
|
||||
syncArbitrateAddress(lock, ARBITRATION_SIGNAL, 1);
|
||||
}
|
||||
|
||||
void RecursiveLock_Init(RecursiveLock* lock)
|
||||
@ -180,9 +185,9 @@ void LightEvent_Clear(LightEvent* event)
|
||||
void LightEvent_Pulse(LightEvent* event)
|
||||
{
|
||||
if (event->state == -2)
|
||||
svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_SIGNAL, -1, 0);
|
||||
syncArbitrateAddress(&event->state, ARBITRATION_SIGNAL, -1);
|
||||
else if (event->state == -1)
|
||||
svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_SIGNAL, 1, 0);
|
||||
syncArbitrateAddress(&event->state, ARBITRATION_SIGNAL, 1);
|
||||
else
|
||||
LightEvent_Clear(event);
|
||||
}
|
||||
@ -192,12 +197,12 @@ void LightEvent_Signal(LightEvent* event)
|
||||
if (event->state == -1)
|
||||
{
|
||||
LightEvent_SetState(event, 0);
|
||||
svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_SIGNAL, 1, 0);
|
||||
syncArbitrateAddress(&event->state, ARBITRATION_SIGNAL, 1);
|
||||
} else if (event->state == -2)
|
||||
{
|
||||
LightLock_Lock(&event->lock);
|
||||
LightEvent_SetState(event, 1);
|
||||
svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_SIGNAL, -1, 0);
|
||||
syncArbitrateAddress(&event->state, ARBITRATION_SIGNAL, -1);
|
||||
LightLock_Unlock(&event->lock);
|
||||
}
|
||||
}
|
||||
@ -215,7 +220,7 @@ void LightEvent_Wait(LightEvent* event)
|
||||
{
|
||||
if (event->state == -2)
|
||||
{
|
||||
svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0);
|
||||
syncArbitrateAddress(&event->state, ARBITRATION_WAIT_IF_LESS_THAN, 0);
|
||||
return;
|
||||
}
|
||||
if (event->state != -1)
|
||||
@ -225,7 +230,7 @@ void LightEvent_Wait(LightEvent* event)
|
||||
if (event->state == 0 && LightEvent_TryReset(event))
|
||||
return;
|
||||
}
|
||||
svcArbitrateAddress(arbiter, (u32)event, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0);
|
||||
syncArbitrateAddress(&event->state, ARBITRATION_WAIT_IF_LESS_THAN, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +259,7 @@ void LightSemaphore_Acquire(LightSemaphore* semaphore, s32 count)
|
||||
num_threads_acq = (s16)__ldrexh((u16 *)&semaphore->num_threads_acq);
|
||||
while (__strexh((u16 *)&semaphore->num_threads_acq, num_threads_acq + 1));
|
||||
|
||||
svcArbitrateAddress(arbiter, (u32)semaphore, ARBITRATION_WAIT_IF_LESS_THAN, count, 0);
|
||||
syncArbitrateAddress(&semaphore->current_count, ARBITRATION_WAIT_IF_LESS_THAN, count);
|
||||
|
||||
do
|
||||
num_threads_acq = (s16)__ldrexh((u16 *)&semaphore->num_threads_acq);
|
||||
@ -275,5 +280,5 @@ void LightSemaphore_Release(LightSemaphore* semaphore, s32 count)
|
||||
} while (__strex(&semaphore->current_count, new_count));
|
||||
|
||||
if(old_count <= 0 || semaphore->num_threads_acq > 0)
|
||||
svcArbitrateAddress(arbiter, (u32)semaphore, ARBITRATION_SIGNAL, count, 0);
|
||||
syncArbitrateAddress(&semaphore->current_count, ARBITRATION_SIGNAL, count);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user