/*---------------------------------------------------------------------------* Project: OS Library File: OSSync.h Copyright (C) 2010-2011 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ #ifndef __OSSYNC_H__ #define __OSSYNC_H__ #include #include #include #ifdef __cplusplus extern "C" { #endif #define OS_CORE_MAIN (1) #define OS_CORE_SUB1 (0) #define OS_CORE_SUB2 (2) #define OS_CORE_SUB1_MASK (1 << 0) #define OS_CORE_MAIN_MASK (1 << 1) #define OS_CORE_SUB2_MASK (1 << 2) #define OS_CORE_ALL_MASK (OS_CORE_SUB1_MASK | OS_CORE_MAIN_MASK | OS_CORE_SUB2_MASK) #define OS_WAIT_CORE_SUB1 (1 << 0) #define OS_WAIT_CORE_MAIN (1 << 1) #define OS_WAIT_CORE_SUB2 (1 << 2) #define OS_WAIT_CORE_NONE (0) #define OS_WAIT_CORE_ALL (OS_WAIT_CORE_SUB1 | OS_WAIT_CORE_MAIN | OS_WAIT_CORE_SUB2) // // Basic synchonization types // typedef u32 OSSpinLockID; typedef u32 OSEventID; typedef u32 OSRendezvousID; // // SpinLocks // SET_STRUCT_ALIGN(16) typedef struct { u32 spinlock; OSSpinLockID spinlock_id; u32 recursionCount; // allow recursive locking u32 interrupts_enabled; } ATTRIB_STRUCT_ALIGN(16) OSSpinLock; SET_STRUCT_ALIGN(1) void OSInitSpinLock(OSSpinLock *spinlock); BOOL OSAcquireSpinLock(OSSpinLock *spinlock); BOOL OSTryAcquireSpinLock(OSSpinLock *spinlock); BOOL OSTryAcquireSpinLockWithTimeout(OSSpinLock *spinlock, OSTimeNanoseconds timeout); BOOL OSReleaseSpinLock(OSSpinLock *spinlock); // // OSUninterruptibleSpinLock // Spinlocks which disable then re-enable interrupts to prevent priority inversion problems. // // (1) Upon return from the "Acquire" functions, if the result is TRUE then interrupts are // DISABLED. // // (2) It is EXTREMELY IMPORTANT that code which follows the uninterruptible spinlock acquire // not run for long periods of time. No more than 1000 cycles would be a good rule-of-thumb. // // (3) DO NOT switch threads (or call functions which switch threads) with interrupts // disabled because interrupt-disabling is per-thread and this is usually not // what the originating thread intends to happen. BOOL OSUninterruptibleSpinLock_Acquire(OSSpinLock *inSpinlock); BOOL OSUninterruptibleSpinLock_TryAcquire(OSSpinLock *inSpinLock); BOOL OSUninterruptibleSpinLock_TryAcquireWithTimeout(OSSpinLock *inSpinLock, OSTimeNanoseconds timeout); BOOL OSUninterruptibleSpinLock_Release(OSSpinLock *inSpinlock); // // Rendezvous // typedef struct { volatile u32 core[MAX_SYSTEM_CORES]; OSRendezvousID rendezvous_id; } OSRendezvous; void OSInitRendezvous(OSRendezvous *ren); BOOL OSWaitRendezvous(OSRendezvous *ren, u32 wmask); BOOL OSWaitRendezvousWithTimeout(OSRendezvous *ren, u32 wmask, OSTimeNanoseconds timeout); // // Misc. // // Wait until all memory writes have flushed to ram // (Extremely expensive, can be many 100s of cycles) void OSMemoryBarrier(void); // Wait until all memory writes have flushed to other cores void OSCoherencyBarrier(void); #ifdef __cplusplus } #endif #endif // __OSSYNC_H__