mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	Kernel: Added preliminary support for address arbiters.
AddressArbiter: Added documentation comment, fixed whitespace issue. AddressArbiter: Fixed incorrect comment, reordered if-statement to be more clear. SVC: Removed trailing whitespace.
This commit is contained in:
		
							
								
								
									
										87
									
								
								src/core/hle/kernel/address_arbiter.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/core/hle/kernel/address_arbiter.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
// Copyright 2014 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
 | 
			
		||||
#include "core/mem_map.h"
 | 
			
		||||
 | 
			
		||||
#include "core/hle/hle.h"
 | 
			
		||||
#include "core/hle/kernel/address_arbiter.h"
 | 
			
		||||
#include "core/hle/kernel/thread.h"
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Kernel namespace
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
class AddressArbiter : public Object {
 | 
			
		||||
public:
 | 
			
		||||
    const char* GetTypeName() const { return "Arbiter"; }
 | 
			
		||||
    const char* GetName() const { return name.c_str(); }
 | 
			
		||||
 | 
			
		||||
    static Kernel::HandleType GetStaticHandleType() { return HandleType::AddressArbiter; }
 | 
			
		||||
    Kernel::HandleType GetHandleType() const { return HandleType::AddressArbiter; }
 | 
			
		||||
 | 
			
		||||
    std::string name;   ///< Name of address arbiter object (optional)
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Wait for kernel object to synchronize
 | 
			
		||||
     * @param wait Boolean wait set if current thread should wait as a result of sync operation
 | 
			
		||||
     * @return Result of operation, 0 on success, otherwise error code
 | 
			
		||||
     */
 | 
			
		||||
    Result WaitSynchronization(bool* wait) {
 | 
			
		||||
        // TODO(bunnei): ImplementMe
 | 
			
		||||
        ERROR_LOG(OSHLE, "(UNIMPLEMENTED)");
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
/// Arbitrate an address
 | 
			
		||||
Result ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) {
 | 
			
		||||
    switch (type) {
 | 
			
		||||
 | 
			
		||||
    // Signal thread(s) waiting for arbitrate address...
 | 
			
		||||
    case ArbitrationType::Signal:
 | 
			
		||||
        // Negative value means resume all threads
 | 
			
		||||
        if (value < 0) {
 | 
			
		||||
            ArbitrateAllThreads(handle, address);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Resume first N threads
 | 
			
		||||
            for(int i = 0; i < value; i++)
 | 
			
		||||
                ArbitrateHighestPriorityThread(handle, address);
 | 
			
		||||
        }
 | 
			
		||||
        HLE::Reschedule(__func__);
 | 
			
		||||
 | 
			
		||||
    // Wait current thread (acquire the arbiter)...
 | 
			
		||||
    case ArbitrationType::WaitIfLessThan:
 | 
			
		||||
        if ((s32)Memory::Read32(address) <= value) {
 | 
			
		||||
            Kernel::WaitCurrentThread(WAITTYPE_ARB, handle);
 | 
			
		||||
            HLE::Reschedule(__func__);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        ERROR_LOG(KERNEL, "unknown type=%d", type);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create an address arbiter
 | 
			
		||||
AddressArbiter* CreateAddressArbiter(Handle& handle, const std::string& name) {
 | 
			
		||||
    AddressArbiter* address_arbiter = new AddressArbiter;
 | 
			
		||||
    handle = Kernel::g_object_pool.Create(address_arbiter);
 | 
			
		||||
    address_arbiter->name = name;
 | 
			
		||||
    return address_arbiter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create an address arbiter
 | 
			
		||||
Handle CreateAddressArbiter(const std::string& name) {
 | 
			
		||||
    Handle handle;
 | 
			
		||||
    CreateAddressArbiter(handle, name);
 | 
			
		||||
    return handle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
							
								
								
									
										36
									
								
								src/core/hle/kernel/address_arbiter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/core/hle/kernel/address_arbiter.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
// Copyright 2014 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
 | 
			
		||||
// Address arbiters are an underlying kernel synchronization object that can be created/used via
 | 
			
		||||
// supervisor calls (SVCs). They function as sort of a global lock. Typically, games/other CTR
 | 
			
		||||
// applications use them as an underlying mechanism to implement thread-safe barriers, events, and
 | 
			
		||||
// semphores. 
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Kernel namespace
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
/// Address arbitration types
 | 
			
		||||
enum class ArbitrationType : u32 {
 | 
			
		||||
    Signal,
 | 
			
		||||
    WaitIfLessThan,
 | 
			
		||||
    DecrementAndWaitIfLessThan,
 | 
			
		||||
    WaitIfLessThanWithTimeout,
 | 
			
		||||
    DecrementAndWaitIfLessThanWithTimeout,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Arbitrate an address
 | 
			
		||||
Result ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value);
 | 
			
		||||
 | 
			
		||||
/// Create an address arbiter
 | 
			
		||||
Handle CreateAddressArbiter(const std::string& name = "Unknown");
 | 
			
		||||
 | 
			
		||||
} // namespace FileSys
 | 
			
		||||
@@ -26,7 +26,7 @@ enum class HandleType : u32 {
 | 
			
		||||
    Redirection     = 6,
 | 
			
		||||
    Thread          = 7,
 | 
			
		||||
    Process         = 8,
 | 
			
		||||
    Arbiter         = 9,
 | 
			
		||||
    AddressArbiter  = 9,
 | 
			
		||||
    File            = 10,
 | 
			
		||||
    Semaphore       = 11,
 | 
			
		||||
    Archive         = 12,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user