Skip to content

Commit

Permalink
LibUV glue.
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasnoble committed Jan 19, 2020
1 parent 720de96 commit f58ee63
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 20 deletions.
42 changes: 32 additions & 10 deletions src/ftdi/abstract-ftd2xx-win32.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/***************************************************************************
/***s************************************************************************
* Copyright (C) 2019 PCSX-Redux authors *
* *
* This program is free software; you can redistribute it and/or modify *
Expand Down Expand Up @@ -51,29 +51,45 @@ class DeviceData {
} // namespace FTDI
} // namespace PCSX

static std::vector<PCSX::FTDI::Device> s_devices;
static PCSX::FTDI::Device* s_devices = nullptr;
static unsigned s_numDevs = 0;
static HANDLE s_thread;
static std::atomic_bool s_exitThread;
static bool s_threadRunning = false;
static HANDLE s_kickEvent = nullptr;
static std::shared_mutex s_listLock;
static unsigned s_numOpened = 0;

static PCSX::GUI* s_gui = nullptr;

static void asyncCallbackTrampoline(uv_async_t* handle) {
PCSX::FTDI::Device* device = (PCSX::FTDI::Device*)handle->data;
device->asyncCallback();
}

static void asyncCloseCallback(uv_handle_t* handle) {}

PCSX::FTDI::Device::Device() {
uv_async_init(s_gui->loop(), &m_async, asyncCallbackTrampoline);
m_async.data = this;
}

PCSX::FTDI::Device::~Device() {
assert(m_private->m_state == Private::DeviceData::STATE_CLOSED);
assert(!m_private->m_event);
assert(!m_private->m_handle);
delete m_private;
uv_close(reinterpret_cast<uv_handle_t*>(&m_async), asyncCloseCallback);
}

void PCSX::FTDI::Device::open() {
std::shared_lock<std::shared_mutex> guard(s_listLock);
std::unique_lock<std::shared_mutex> guard(s_listLock);
assert(m_private->m_state == Private::DeviceData::STATE_CLOSED);
m_private->m_state = Private::DeviceData::STATE_OPEN_PENDING;
SetEvent(s_kickEvent);
}
void PCSX::FTDI::Device::close() {
std::shared_lock<std::shared_mutex> guard(s_listLock);
std::unique_lock<std::shared_mutex> guard(s_listLock);
assert(m_private->m_state == Private::DeviceData::STATE_OPENED);
m_private->m_state = Private::DeviceData::STATE_CLOSE_PENDING;
SetEvent(s_kickEvent);
Expand All @@ -85,19 +101,22 @@ void PCSX::FTDI::Devices::scan() {
DWORD numDevs = 0;

std::unique_lock<std::shared_mutex> guard(s_listLock);
if (s_numOpened != 0) return;
// we can't modify the list if there's any device that's still opened
if (s_numDevs != 0) return;

s_devices.clear();
delete[] s_devices;
s_numDevs = 0;
status = FT_CreateDeviceInfoList(&numDevs);

if (status != FT_OK || numDevs == 0) return;
s_numDevs = numDevs;

FT_DEVICE_LIST_INFO_NODE* nodes = new FT_DEVICE_LIST_INFO_NODE[numDevs];

status = FT_GetDeviceInfoList(nodes, &numDevs);

if (status == FT_OK && numDevs != 0) {
s_devices.resize(numDevs);
s_devices = new Device[numDevs];
for (DWORD i = 0; i < numDevs; i++) {
const FT_DEVICE_LIST_INFO_NODE* n = nodes + i;
s_devices[i].m_locked = n->Flags & FT_FLAGS_OPENED;
Expand All @@ -116,8 +135,8 @@ void PCSX::FTDI::Devices::scan() {

void PCSX::FTDI::Devices::iterate(std::function<bool(Device&)> iter) {
std::shared_lock<std::shared_mutex> guard(s_listLock);
for (auto& d : s_devices) {
if (!iter(d)) break;
for (unsigned i = 0; i < s_numDevs; i++) {
if (!iter(s_devices[i])) break;
}
}

Expand All @@ -129,7 +148,8 @@ void PCSX::FTDI::Devices::threadProc() {
{
std::shared_lock<std::shared_mutex> guard(s_listLock);

for (auto& device : s_devices) {
for (unsigned i = 0; i < s_numDevs; i++) {
auto& device = s_devices[i];
switch (device.m_private->m_state) {
case Private::DeviceData::STATE_OPEN_PENDING:
s_numOpened++;
Expand Down Expand Up @@ -189,4 +209,6 @@ void PCSX::FTDI::Devices::stopThread() {

bool PCSX::FTDI::Devices::isThreadRunning() { return s_threadRunning; }

void PCSX::FTDI::Devices::setGUI(GUI* gui) { s_gui = gui; }

#endif
35 changes: 33 additions & 2 deletions src/ftdi/abstract.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@

#include <stdint.h>

#include <atomic>
#include <functional>
#include <string>
#include <vector>

#include "gui/gui.h"
#include "support/slice.h"

namespace PCSX {

Expand All @@ -35,6 +38,7 @@ class DeviceData;
}
class Device {
public:
Device();
~Device();
bool isLocked() const { return m_locked; }
bool isHighSpeed() const { return m_highSpeed; }
Expand All @@ -49,6 +53,9 @@ class Device {
void open();
void close();

// technically private, but difficult to enforce properly
void asyncCallback() {}

private:
bool m_locked = false;
bool m_highSpeed = false;
Expand All @@ -58,7 +65,30 @@ class Device {
std::string m_serial = "";
std::string m_description = "";

Private::DeviceData* m_private;
Private::DeviceData* m_private = nullptr;

static const unsigned SLICES_COUNT = 256;
Slice m_slices[SLICES_COUNT];
std::atomic_uint16_t m_slicesIndexes = 0;

uv_async_t m_async;

unsigned usedSlices() {
uint16_t indexes = m_slicesIndexes.load();
unsigned first = indexes & 0xff;
unsigned last = (indexes >> 8) & 0xff;
if (last < first) last += 256;
return last - first;
}

unsigned availableSlices() { return 256 - usedSlices(); }

Slice& allocateSlice() {
while (availableSlices() == 0)
;
uint16_t indexes = m_slicesIndexes.fetch_add(0x100);
return m_slices[(indexes >> 8) & 0xff];
}

friend class Devices;
};
Expand All @@ -70,6 +100,7 @@ class Devices {
static bool isThreadRunning();
static void startThread();
static void stopThread();
static void setGUI(GUI*);

// technically private, but difficult to enforce properly
static void threadProc();
Expand Down
2 changes: 2 additions & 0 deletions src/gui/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ class GUI final {
}
}

uv_loop_t *loop() { return &m_loop; }

private:
GLFWwindow *m_window = nullptr;
int &m_glfwPosX = settings.get<WindowPosX>().value;
Expand Down
2 changes: 2 additions & 0 deletions src/main/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "core/r3000a.h"
#include "core/sstate.h"
#include "flags.h"
#include "ftdi/abstract.h"
#include "gui/gui.h"
#include "spu/interface.h"
#include "support/slice.h"
Expand Down Expand Up @@ -197,6 +198,7 @@ int main(int argc, char **argv) {
LoadPlugins();
PCSX::g_emulator.m_gpu->open(s_gui);
PCSX::g_emulator.m_spu->open();
PCSX::FTDI::Devices::setGUI(s_gui);

PCSX::g_emulator.EmuInit();
PCSX::g_emulator.EmuReset();
Expand Down
24 changes: 16 additions & 8 deletions vsprojects/ftdi/ftdi.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,19 @@
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\includes.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\includes.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\includes.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\includes.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
Expand All @@ -85,9 +89,10 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\src</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\src;..\..\third_party;..\..\third_party\imgui;..\..\third_party\imgui_club;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -98,9 +103,10 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\src</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\src;..\..\third_party;..\..\third_party\imgui;..\..\third_party\imgui_club;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -113,9 +119,10 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\src</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\src;..\..\third_party;..\..\third_party\imgui;..\..\third_party\imgui_club;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -130,9 +137,10 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\..\src</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\src;..\..\third_party;..\..\third_party\imgui;..\..\third_party\imgui_club;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand Down
2 changes: 2 additions & 0 deletions vsprojects/includes.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
<ItemDefinitionGroup>
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
Expand Down

0 comments on commit f58ee63

Please sign in to comment.