Browse Source
Merge branch 'threading' of https://github.com/bunnei/citra
Merge branch 'threading' of https://github.com/bunnei/citra
Conflicts: src/core/hle/function_wrappers.h src/core/hle/service/gsp.cpppull/15/merge
41 changed files with 1243 additions and 1199 deletions
-
2src/citra_qt/debugger/disassembler.cpp
-
16src/common/console_listener.cpp
-
39src/common/log.h
-
30src/common/log_manager.cpp
-
6src/common/log_manager.h
-
2src/core/CMakeLists.txt
-
3src/core/arm/arm_interface.h
-
14src/core/arm/interpreter/arm_interpreter.cpp
-
3src/core/arm/interpreter/arm_interpreter.h
-
18src/core/arm/interpreter/armemu.cpp
-
23src/core/core.cpp
-
4src/core/core.vcxproj
-
12src/core/core.vcxproj.filters
-
2src/core/hle/config_mem.cpp
-
2src/core/hle/coprocessor.cpp
-
753src/core/hle/function_wrappers.h
-
20src/core/hle/hle.cpp
-
12src/core/hle/hle.h
-
159src/core/hle/kernel/event.cpp
-
52src/core/hle/kernel/event.h
-
11src/core/hle/kernel/kernel.cpp
-
33src/core/hle/kernel/kernel.h
-
50src/core/hle/kernel/mutex.cpp
-
6src/core/hle/kernel/mutex.h
-
223src/core/hle/kernel/thread.cpp
-
15src/core/hle/kernel/thread.h
-
187src/core/hle/service/apt.cpp
-
74src/core/hle/service/gsp.cpp
-
10src/core/hle/service/hid.cpp
-
32src/core/hle/service/ndm.cpp
-
33src/core/hle/service/ndm.h
-
10src/core/hle/service/service.cpp
-
40src/core/hle/service/service.h
-
27src/core/hle/service/srv.cpp
-
6src/core/hle/service/srv.h
-
487src/core/hle/svc.cpp
-
13src/core/hle/svc.h
-
2src/core/hw/gpu.cpp
-
3src/core/hw/gpu.h
-
5src/core/mem_map_funcs.cpp
-
3src/core/system.cpp
@ -0,0 +1,159 @@ |
|||||
|
// Copyright 2014 Citra Emulator Project
|
||||
|
// Licensed under GPLv2
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include <map>
|
||||
|
#include <algorithm>
|
||||
|
#include <vector>
|
||||
|
|
||||
|
#include "common/common.h"
|
||||
|
|
||||
|
#include "core/hle/kernel/kernel.h"
|
||||
|
#include "core/hle/kernel/event.h"
|
||||
|
#include "core/hle/kernel/thread.h"
|
||||
|
|
||||
|
namespace Kernel { |
||||
|
|
||||
|
class Event : public Object { |
||||
|
public: |
||||
|
const char* GetTypeName() const { return "Event"; } |
||||
|
const char* GetName() const { return name.c_str(); } |
||||
|
|
||||
|
static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Event; } |
||||
|
Kernel::HandleType GetHandleType() const { return Kernel::HandleType::Event; } |
||||
|
|
||||
|
ResetType intitial_reset_type; ///< ResetType specified at Event initialization
|
||||
|
ResetType reset_type; ///< Current ResetType
|
||||
|
|
||||
|
bool locked; ///< Event signal wait
|
||||
|
bool permanent_locked; ///< Hack - to set event permanent state (for easy passthrough)
|
||||
|
std::vector<Handle> waiting_threads; ///< Threads that are waiting for the event
|
||||
|
std::string name; ///< Name of event (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) { |
||||
|
*wait = locked; |
||||
|
if (locked) { |
||||
|
Handle thread = GetCurrentThreadHandle(); |
||||
|
if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { |
||||
|
waiting_threads.push_back(thread); |
||||
|
} |
||||
|
Kernel::WaitCurrentThread(WAITTYPE_EVENT); |
||||
|
} |
||||
|
if (reset_type != RESETTYPE_STICKY && !permanent_locked) { |
||||
|
locked = true; |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
/**
|
||||
|
* Hackish function to set an events permanent lock state, used to pass through synch blocks |
||||
|
* @param handle Handle to event to change |
||||
|
* @param permanent_locked Boolean permanent locked value to set event |
||||
|
* @return Result of operation, 0 on success, otherwise error code |
||||
|
*/ |
||||
|
Result SetPermanentLock(Handle handle, const bool permanent_locked) { |
||||
|
Event* evt = g_object_pool.GetFast<Event>(handle); |
||||
|
_assert_msg_(KERNEL, (evt != nullptr), "called, but event is nullptr!"); |
||||
|
|
||||
|
evt->permanent_locked = permanent_locked; |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Changes whether an event is locked or not |
||||
|
* @param handle Handle to event to change |
||||
|
* @param locked Boolean locked value to set event |
||||
|
* @return Result of operation, 0 on success, otherwise error code |
||||
|
*/ |
||||
|
Result SetEventLocked(const Handle handle, const bool locked) { |
||||
|
Event* evt = g_object_pool.GetFast<Event>(handle); |
||||
|
_assert_msg_(KERNEL, (evt != nullptr), "called, but event is nullptr!"); |
||||
|
|
||||
|
if (!evt->permanent_locked) { |
||||
|
evt->locked = locked; |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Signals an event |
||||
|
* @param handle Handle to event to signal |
||||
|
* @return Result of operation, 0 on success, otherwise error code |
||||
|
*/ |
||||
|
Result SignalEvent(const Handle handle) { |
||||
|
Event* evt = g_object_pool.GetFast<Event>(handle); |
||||
|
_assert_msg_(KERNEL, (evt != nullptr), "called, but event is nullptr!"); |
||||
|
|
||||
|
// Resume threads waiting for event to signal
|
||||
|
bool event_caught = false; |
||||
|
for (size_t i = 0; i < evt->waiting_threads.size(); ++i) { |
||||
|
ResumeThreadFromWait( evt->waiting_threads[i]); |
||||
|
|
||||
|
// If any thread is signalled awake by this event, assume the event was "caught" and reset
|
||||
|
// the event. This will result in the next thread waiting on the event to block. Otherwise,
|
||||
|
// the event will not be reset, and the next thread to call WaitSynchronization on it will
|
||||
|
// not block. Not sure if this is correct behavior, but it seems to work.
|
||||
|
event_caught = true; |
||||
|
} |
||||
|
evt->waiting_threads.clear(); |
||||
|
|
||||
|
if (!evt->permanent_locked) { |
||||
|
evt->locked = event_caught; |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Clears an event |
||||
|
* @param handle Handle to event to clear |
||||
|
* @return Result of operation, 0 on success, otherwise error code |
||||
|
*/ |
||||
|
Result ClearEvent(Handle handle) { |
||||
|
Event* evt = g_object_pool.GetFast<Event>(handle); |
||||
|
_assert_msg_(KERNEL, (evt != nullptr), "called, but event is nullptr!"); |
||||
|
|
||||
|
if (!evt->permanent_locked) { |
||||
|
evt->locked = true; |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Creates an event |
||||
|
* @param handle Reference to handle for the newly created mutex |
||||
|
* @param reset_type ResetType describing how to create event |
||||
|
* @param name Optional name of event |
||||
|
* @return Newly created Event object |
||||
|
*/ |
||||
|
Event* CreateEvent(Handle& handle, const ResetType reset_type, const std::string& name) { |
||||
|
Event* evt = new Event; |
||||
|
|
||||
|
handle = Kernel::g_object_pool.Create(evt); |
||||
|
|
||||
|
evt->locked = true; |
||||
|
evt->permanent_locked = false; |
||||
|
evt->reset_type = evt->intitial_reset_type = reset_type; |
||||
|
evt->name = name; |
||||
|
|
||||
|
return evt; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Creates an event |
||||
|
* @param reset_type ResetType describing how to create event |
||||
|
* @param name Optional name of event |
||||
|
* @return Handle to newly created Event object |
||||
|
*/ |
||||
|
Handle CreateEvent(const ResetType reset_type, const std::string& name) { |
||||
|
Handle handle; |
||||
|
Event* evt = CreateEvent(handle, reset_type, name); |
||||
|
return handle; |
||||
|
} |
||||
|
|
||||
|
} // namespace
|
||||
@ -0,0 +1,52 @@ |
|||||
|
// 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" |
||||
|
#include "core/hle/svc.h" |
||||
|
|
||||
|
namespace Kernel { |
||||
|
|
||||
|
/** |
||||
|
* Changes whether an event is locked or not |
||||
|
* @param handle Handle to event to change |
||||
|
* @param locked Boolean locked value to set event |
||||
|
* @return Result of operation, 0 on success, otherwise error code |
||||
|
*/ |
||||
|
Result SetEventLocked(const Handle handle, const bool locked); |
||||
|
|
||||
|
/** |
||||
|
* Hackish function to set an events permanent lock state, used to pass through synch blocks |
||||
|
* @param handle Handle to event to change |
||||
|
* @param permanent_locked Boolean permanent locked value to set event |
||||
|
* @return Result of operation, 0 on success, otherwise error code |
||||
|
*/ |
||||
|
Result SetPermanentLock(Handle handle, const bool permanent_locked); |
||||
|
|
||||
|
/** |
||||
|
* Signals an event |
||||
|
* @param handle Handle to event to signal |
||||
|
* @return Result of operation, 0 on success, otherwise error code |
||||
|
*/ |
||||
|
Result SignalEvent(const Handle handle); |
||||
|
|
||||
|
/** |
||||
|
* Clears an event |
||||
|
* @param handle Handle to event to clear |
||||
|
* @return Result of operation, 0 on success, otherwise error code |
||||
|
*/ |
||||
|
Result ClearEvent(Handle handle); |
||||
|
|
||||
|
/** |
||||
|
* Creates an event |
||||
|
* @param reset_type ResetType describing how to create event |
||||
|
* @param name Optional name of event |
||||
|
* @return Handle to newly created Event object |
||||
|
*/ |
||||
|
Handle CreateEvent(const ResetType reset_type, const std::string& name="Unknown"); |
||||
|
|
||||
|
} // namespace |
||||
@ -0,0 +1,32 @@ |
|||||
|
// Copyright 2014 Citra Emulator Project
|
||||
|
// Licensed under GPLv2
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include "common/log.h"
|
||||
|
|
||||
|
#include "core/hle/hle.h"
|
||||
|
#include "core/hle/service/ndm.h"
|
||||
|
|
||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
// Namespace NDM_U
|
||||
|
|
||||
|
namespace NDM_U { |
||||
|
|
||||
|
const Interface::FunctionInfo FunctionTable[] = { |
||||
|
{0x00060040, nullptr, "SuspendDaemons"}, |
||||
|
{0x00080040, nullptr, "DisableWifiUsage"}, |
||||
|
{0x00090000, nullptr, "EnableWifiUsage"}, |
||||
|
{0x00140040, nullptr, "OverrideDefaultDaemons"}, |
||||
|
}; |
||||
|
|
||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
// Interface class
|
||||
|
|
||||
|
Interface::Interface() { |
||||
|
Register(FunctionTable, ARRAY_SIZE(FunctionTable)); |
||||
|
} |
||||
|
|
||||
|
Interface::~Interface() { |
||||
|
} |
||||
|
|
||||
|
} // namespace
|
||||
@ -0,0 +1,33 @@ |
|||||
|
// Copyright 2014 Citra Emulator Project |
||||
|
// Licensed under GPLv2 |
||||
|
// Refer to the license.txt file included. |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include "core/hle/service/service.h" |
||||
|
|
||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////// |
||||
|
// Namespace NDM |
||||
|
|
||||
|
// No idea what this is |
||||
|
|
||||
|
namespace NDM_U { |
||||
|
|
||||
|
class Interface : public Service::Interface { |
||||
|
public: |
||||
|
|
||||
|
Interface(); |
||||
|
|
||||
|
~Interface(); |
||||
|
|
||||
|
/** |
||||
|
* Gets the string port name used by CTROS for the service |
||||
|
* @return Port name of service |
||||
|
*/ |
||||
|
const char *GetPortName() const { |
||||
|
return "ndm:u"; |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
} // namespace |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue