1 /*---------------------------------------------------------------------------* 2 Project: OS Library 3 File: OSSync.h 4 5 Copyright (C) 2010-2011 Nintendo. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 *---------------------------------------------------------------------------*/ 14 15 #ifndef __OSSYNC_H__ 16 #define __OSSYNC_H__ 17 18 #include <types.h> 19 #include <cafe/os/OSCore.h> 20 #include <cafe/os/OSTime.h> 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 #define OS_CORE_MAIN (1) 27 #define OS_CORE_SUB1 (0) 28 #define OS_CORE_SUB2 (2) 29 30 #define OS_CORE_SUB1_MASK (1 << 0) 31 #define OS_CORE_MAIN_MASK (1 << 1) 32 #define OS_CORE_SUB2_MASK (1 << 2) 33 #define OS_CORE_ALL_MASK (OS_CORE_SUB1_MASK | OS_CORE_MAIN_MASK | OS_CORE_SUB2_MASK) 34 35 #define OS_WAIT_CORE_SUB1 (1 << 0) 36 #define OS_WAIT_CORE_MAIN (1 << 1) 37 #define OS_WAIT_CORE_SUB2 (1 << 2) 38 39 #define OS_WAIT_CORE_NONE (0) 40 #define OS_WAIT_CORE_ALL (OS_WAIT_CORE_SUB1 | OS_WAIT_CORE_MAIN | OS_WAIT_CORE_SUB2) 41 42 // 43 // Basic synchonization types 44 // 45 46 typedef u32 OSSpinLockID; 47 typedef u32 OSEventID; 48 typedef u32 OSRendezvousID; 49 50 // 51 // SpinLocks 52 // 53 SET_STRUCT_ALIGN(16) 54 typedef struct 55 { 56 u32 spinlock; 57 OSSpinLockID spinlock_id; 58 u32 recursionCount; // allow recursive locking 59 u32 interrupts_enabled; 60 } ATTRIB_STRUCT_ALIGN(16) OSSpinLock; 61 SET_STRUCT_ALIGN(1) 62 63 void OSInitSpinLock(OSSpinLock *spinlock); 64 BOOL OSAcquireSpinLock(OSSpinLock *spinlock); 65 BOOL OSTryAcquireSpinLock(OSSpinLock *spinlock); 66 BOOL OSTryAcquireSpinLockWithTimeout(OSSpinLock *spinlock, OSTimeNanoseconds timeout); 67 BOOL OSReleaseSpinLock(OSSpinLock *spinlock); 68 69 // 70 // OSUninterruptibleSpinLock 71 // Spinlocks which disable then re-enable interrupts to prevent priority inversion problems. 72 // 73 // (1) Upon return from the "Acquire" functions, if the result is TRUE then interrupts are 74 // DISABLED. 75 // 76 // (2) It is EXTREMELY IMPORTANT that code which follows the uninterruptible spinlock acquire 77 // not run for long periods of time. No more than 1000 cycles would be a good rule-of-thumb. 78 // 79 // (3) DO NOT switch threads (or call functions which switch threads) with interrupts 80 // disabled because interrupt-disabling is per-thread and this is usually not 81 // what the originating thread intends to happen. 82 83 BOOL OSUninterruptibleSpinLock_Acquire(OSSpinLock *inSpinlock); 84 BOOL OSUninterruptibleSpinLock_TryAcquire(OSSpinLock *inSpinLock); 85 BOOL OSUninterruptibleSpinLock_TryAcquireWithTimeout(OSSpinLock *inSpinLock, OSTimeNanoseconds timeout); 86 BOOL OSUninterruptibleSpinLock_Release(OSSpinLock *inSpinlock); 87 88 // 89 // Rendezvous 90 // 91 92 typedef struct 93 { 94 volatile u32 core[MAX_SYSTEM_CORES]; 95 OSRendezvousID rendezvous_id; 96 } OSRendezvous; 97 98 void OSInitRendezvous(OSRendezvous *ren); 99 BOOL OSWaitRendezvous(OSRendezvous *ren, u32 wmask); 100 BOOL OSWaitRendezvousWithTimeout(OSRendezvous *ren, u32 wmask, OSTimeNanoseconds timeout); 101 102 103 // 104 // Misc. 105 // 106 107 // Wait until all memory writes have flushed to ram 108 // (Extremely expensive, can be many 100s of cycles) 109 void OSMemoryBarrier(void); 110 111 // Wait until all memory writes have flushed to other cores 112 void OSCoherencyBarrier(void); 113 114 #ifdef __cplusplus 115 } 116 #endif 117 118 #endif // __OSSYNC_H__ 119 120