mirror of https://github.com/zeldaret/tp.git
				
				
				
			
		
			
				
	
	
		
			249 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			249 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
//
 | 
						|
// Generated By: dol2asm
 | 
						|
// Translation Unit: OSMutex
 | 
						|
//
 | 
						|
 | 
						|
#include "dolphin/os/OSMutex.h"
 | 
						|
#include "dol2asm.h"
 | 
						|
#include "dolphin/os/OS.h"
 | 
						|
 | 
						|
#define PushTail(queue, mutex, link)                                                               \
 | 
						|
    do {                                                                                           \
 | 
						|
        OSMutex* __prev;                                                                           \
 | 
						|
                                                                                                   \
 | 
						|
        __prev = (queue)->tail;                                                                    \
 | 
						|
        if (__prev == NULL)                                                                        \
 | 
						|
            (queue)->head = (mutex);                                                               \
 | 
						|
        else                                                                                       \
 | 
						|
            __prev->link.next = (mutex);                                                           \
 | 
						|
        (mutex)->link.prev = __prev;                                                               \
 | 
						|
        (mutex)->link.next = NULL;                                                                 \
 | 
						|
        (queue)->tail = (mutex);                                                                   \
 | 
						|
    } while (0)
 | 
						|
 | 
						|
#define PopHead(queue, mutex, link)                                                                \
 | 
						|
    do {                                                                                           \
 | 
						|
        OSMutex* __next;                                                                           \
 | 
						|
                                                                                                   \
 | 
						|
        (mutex) = (queue)->head;                                                                   \
 | 
						|
        __next = (mutex)->link.next;                                                               \
 | 
						|
        if (__next == NULL)                                                                        \
 | 
						|
            (queue)->tail = NULL;                                                                  \
 | 
						|
        else                                                                                       \
 | 
						|
            __next->link.prev = NULL;                                                              \
 | 
						|
        (queue)->head = __next;                                                                    \
 | 
						|
    } while (0)
 | 
						|
 | 
						|
#define PopItem(queue, mutex, link)                                                                \
 | 
						|
    do {                                                                                           \
 | 
						|
        OSMutex* __next;                                                                           \
 | 
						|
        OSMutex* __prev;                                                                           \
 | 
						|
                                                                                                   \
 | 
						|
        __next = (mutex)->link.next;                                                               \
 | 
						|
        __prev = (mutex)->link.prev;                                                               \
 | 
						|
                                                                                                   \
 | 
						|
        if (__next == NULL)                                                                        \
 | 
						|
            (queue)->tail = __prev;                                                                \
 | 
						|
        else                                                                                       \
 | 
						|
            __next->link.prev = __prev;                                                            \
 | 
						|
                                                                                                   \
 | 
						|
        if (__prev == NULL)                                                                        \
 | 
						|
            (queue)->head = __next;                                                                \
 | 
						|
        else                                                                                       \
 | 
						|
            __prev->link.next = __next;                                                            \
 | 
						|
    } while (0)
 | 
						|
 | 
						|
//
 | 
						|
// Declarations:
 | 
						|
//
 | 
						|
 | 
						|
/* 8033F008-8033F040 339948 0038+00 0/0 12/12 0/0 .text            OSInitMutex */
 | 
						|
void OSInitMutex(OSMutex* mutex) {
 | 
						|
    OSInitThreadQueue(&mutex->queue);
 | 
						|
    mutex->thread = 0;
 | 
						|
    mutex->count = 0;
 | 
						|
}
 | 
						|
 | 
						|
/* 8033F040-8033F11C 339980 00DC+00 1/1 62/62 0/0 .text            OSLockMutex */
 | 
						|
void OSLockMutex(OSMutex* mutex) {
 | 
						|
    BOOL enabled = OSDisableInterrupts();
 | 
						|
    OSThread* currentThread = OSGetCurrentThread();
 | 
						|
    OSThread* ownerThread;
 | 
						|
 | 
						|
    while (TRUE) {
 | 
						|
        ownerThread = ((OSMutex*)mutex)->thread;
 | 
						|
        if (ownerThread == 0) {
 | 
						|
            mutex->thread = currentThread;
 | 
						|
            mutex->count++;
 | 
						|
            PushTail(¤tThread->owned_mutexes, mutex, link);
 | 
						|
            break;
 | 
						|
        } else if (ownerThread == currentThread) {
 | 
						|
            mutex->count++;
 | 
						|
            break;
 | 
						|
        } else {
 | 
						|
            currentThread->mutex = mutex;
 | 
						|
            __OSPromoteThread(mutex->thread, currentThread->effective_priority);
 | 
						|
            OSSleepThread(&mutex->queue);
 | 
						|
            currentThread->mutex = 0;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    OSRestoreInterrupts(enabled);
 | 
						|
}
 | 
						|
 | 
						|
/* 8033F11C-8033F1E4 339A5C 00C8+00 0/0 71/71 0/0 .text            OSUnlockMutex */
 | 
						|
void OSUnlockMutex(OSMutex* mutex) {
 | 
						|
    BOOL enabled = OSDisableInterrupts();
 | 
						|
    OSThread* currentThread = OSGetCurrentThread();
 | 
						|
 | 
						|
    if (mutex->thread == currentThread && --mutex->count == 0) {
 | 
						|
        PopItem(¤tThread->owned_mutexes, mutex, link);
 | 
						|
        mutex->thread = NULL;
 | 
						|
        if ((s32)currentThread->effective_priority < (s32)currentThread->base_priority) {
 | 
						|
            currentThread->effective_priority = __OSGetEffectivePriority(currentThread);
 | 
						|
        }
 | 
						|
 | 
						|
        OSWakeupThread(&mutex->queue);
 | 
						|
    }
 | 
						|
    OSRestoreInterrupts(enabled);
 | 
						|
}
 | 
						|
 | 
						|
/* 8033F1E4-8033F254 339B24 0070+00 0/0 2/2 0/0 .text            __OSUnlockAllMutex */
 | 
						|
void __OSUnlockAllMutex(OSThread* thread) {
 | 
						|
    OSMutex* mutex;
 | 
						|
 | 
						|
    while (thread->owned_mutexes.head) {
 | 
						|
        PopHead(&thread->owned_mutexes, mutex, link);
 | 
						|
        mutex->count = 0;
 | 
						|
        mutex->thread = NULL;
 | 
						|
        OSWakeupThread(&mutex->queue);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* 8033F254-8033F310 339B94 00BC+00 0/0 9/9 0/0 .text            OSTryLockMutex */
 | 
						|
 | 
						|
BOOL OSTryLockMutex(OSMutex* mutex) {
 | 
						|
    BOOL enabled = OSDisableInterrupts();
 | 
						|
    OSThread* currentThread = OSGetCurrentThread();
 | 
						|
    BOOL locked;
 | 
						|
    if (mutex->thread == 0) {
 | 
						|
        mutex->thread = currentThread;
 | 
						|
        mutex->count++;
 | 
						|
        PushTail(¤tThread->owned_mutexes, mutex, link);
 | 
						|
        locked = TRUE;
 | 
						|
    } else if (mutex->thread == currentThread) {
 | 
						|
        mutex->count++;
 | 
						|
        locked = TRUE;
 | 
						|
    } else {
 | 
						|
        locked = FALSE;
 | 
						|
    }
 | 
						|
    OSRestoreInterrupts(enabled);
 | 
						|
    return locked;
 | 
						|
}
 | 
						|
 | 
						|
/* 8033F310-8033F330 339C50 0020+00 0/0 1/1 0/0 .text            OSInitCond */
 | 
						|
void OSInitCond(OSCond* cond) { OSInitThreadQueue(&cond->queue); }
 | 
						|
 | 
						|
/* 8033F330-8033F404 339C70 00D4+00 0/0 1/1 0/0 .text            OSWaitCond */
 | 
						|
void OSWaitCond(OSCond* cond, OSMutex* mutex) {
 | 
						|
    BOOL enabled = OSDisableInterrupts();
 | 
						|
    OSThread* currentThread = OSGetCurrentThread();
 | 
						|
    s32 count;
 | 
						|
 | 
						|
    if (mutex->thread == currentThread) {
 | 
						|
        count = mutex->count;
 | 
						|
        mutex->count = 0;
 | 
						|
        PopItem(¤tThread->owned_mutexes, mutex, link);
 | 
						|
        mutex->thread = NULL;
 | 
						|
 | 
						|
        if (currentThread->effective_priority < (s32)currentThread->base_priority) {
 | 
						|
            currentThread->effective_priority = __OSGetEffectivePriority(currentThread);
 | 
						|
        }
 | 
						|
 | 
						|
        OSDisableScheduler();
 | 
						|
        OSWakeupThread(&mutex->queue);
 | 
						|
        OSEnableScheduler();
 | 
						|
        OSSleepThread(&cond->queue);
 | 
						|
        OSLockMutex(mutex);
 | 
						|
        mutex->count = count;
 | 
						|
    }
 | 
						|
 | 
						|
    OSRestoreInterrupts(enabled);
 | 
						|
}
 | 
						|
 | 
						|
/* 8033F404-8033F424 339D44 0020+00 0/0 5/5 0/0 .text            OSSignalCond */
 | 
						|
void OSSignalCond(OSCond* cond) {
 | 
						|
    OSWakeupThread(&cond->queue);
 | 
						|
}
 | 
						|
 | 
						|
static BOOL IsMember(OSMutexQueue* queue, OSMutex* mutex) {
 | 
						|
    OSMutex* member;
 | 
						|
 | 
						|
    for (member = queue->head; member; member = member->link.next) {
 | 
						|
        if (mutex == member)
 | 
						|
            return TRUE;
 | 
						|
    }
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/* 8033F424-8033F524 339D64 0100+00 1/1 0/0 0/0 .text            __OSCheckMutex */
 | 
						|
BOOL __OSCheckMutex(OSMutex* mutex) {
 | 
						|
    OSThread* thread;
 | 
						|
    OSThreadQueue* queue;
 | 
						|
    OSPriority priority = 0;
 | 
						|
 | 
						|
    queue = &mutex->queue;
 | 
						|
    if (!(queue->head == NULL || queue->head->link.prev == NULL))
 | 
						|
        return FALSE;
 | 
						|
    if (!(queue->tail == NULL || queue->tail->link.next == NULL))
 | 
						|
        return FALSE;
 | 
						|
    for (thread = queue->head; thread; thread = thread->link.next) {
 | 
						|
        if (!(thread->link.next == NULL || thread == thread->link.next->link.prev))
 | 
						|
            return FALSE;
 | 
						|
        if (!(thread->link.prev == NULL || thread == thread->link.prev->link.next))
 | 
						|
            return FALSE;
 | 
						|
 | 
						|
        if (thread->state != OS_THREAD_STATE_WAITING)
 | 
						|
            return FALSE;
 | 
						|
 | 
						|
        if (thread->effective_priority < priority)
 | 
						|
            return FALSE;
 | 
						|
        priority = thread->effective_priority;
 | 
						|
    }
 | 
						|
 | 
						|
    if (mutex->thread) {
 | 
						|
        if (mutex->count <= 0)
 | 
						|
            return FALSE;
 | 
						|
    } else {
 | 
						|
        if (0 != mutex->count)
 | 
						|
            return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/* 8033F524-8033F55C 339E64 0038+00 0/0 1/1 0/0 .text            __OSCheckDeadLock */
 | 
						|
BOOL __OSCheckDeadLock(OSThread* thread) {
 | 
						|
    OSMutex* mutex;
 | 
						|
 | 
						|
    mutex = thread->mutex;
 | 
						|
    while (mutex && mutex->thread) {
 | 
						|
        if (mutex->thread == thread)
 | 
						|
            return TRUE;
 | 
						|
        mutex = mutex->thread->mutex;
 | 
						|
    }
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/* 8033F55C-8033F5D0 339E9C 0074+00 0/0 1/1 0/0 .text            __OSCheckMutexes */
 | 
						|
BOOL __OSCheckMutexes(OSThread* thread) {
 | 
						|
    OSMutex* mutex;
 | 
						|
 | 
						|
    for (mutex = thread->owned_mutexes.head; mutex; mutex = mutex->link.next) {
 | 
						|
        if (mutex->thread != thread)
 | 
						|
            return FALSE;
 | 
						|
        if (!__OSCheckMutex(mutex))
 | 
						|
            return FALSE;
 | 
						|
    }
 | 
						|
    return TRUE;
 | 
						|
}
 |