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