Skip to content

Commit f58ee63

Browse files
committed
LibUV glue.
1 parent 720de96 commit f58ee63

File tree

6 files changed

+87
-20
lines changed

6 files changed

+87
-20
lines changed

src/ftdi/abstract-ftd2xx-win32.cc

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/***************************************************************************
1+
/***s************************************************************************
22
* Copyright (C) 2019 PCSX-Redux authors *
33
* *
44
* This program is free software; you can redistribute it and/or modify *
@@ -51,29 +51,45 @@ class DeviceData {
5151
} // namespace FTDI
5252
} // namespace PCSX
5353

54-
static std::vector<PCSX::FTDI::Device> s_devices;
54+
static PCSX::FTDI::Device* s_devices = nullptr;
55+
static unsigned s_numDevs = 0;
5556
static HANDLE s_thread;
5657
static std::atomic_bool s_exitThread;
5758
static bool s_threadRunning = false;
5859
static HANDLE s_kickEvent = nullptr;
5960
static std::shared_mutex s_listLock;
6061
static unsigned s_numOpened = 0;
6162

63+
static PCSX::GUI* s_gui = nullptr;
64+
65+
static void asyncCallbackTrampoline(uv_async_t* handle) {
66+
PCSX::FTDI::Device* device = (PCSX::FTDI::Device*)handle->data;
67+
device->asyncCallback();
68+
}
69+
70+
static void asyncCloseCallback(uv_handle_t* handle) {}
71+
72+
PCSX::FTDI::Device::Device() {
73+
uv_async_init(s_gui->loop(), &m_async, asyncCallbackTrampoline);
74+
m_async.data = this;
75+
}
76+
6277
PCSX::FTDI::Device::~Device() {
6378
assert(m_private->m_state == Private::DeviceData::STATE_CLOSED);
6479
assert(!m_private->m_event);
6580
assert(!m_private->m_handle);
6681
delete m_private;
82+
uv_close(reinterpret_cast<uv_handle_t*>(&m_async), asyncCloseCallback);
6783
}
6884

6985
void PCSX::FTDI::Device::open() {
70-
std::shared_lock<std::shared_mutex> guard(s_listLock);
86+
std::unique_lock<std::shared_mutex> guard(s_listLock);
7187
assert(m_private->m_state == Private::DeviceData::STATE_CLOSED);
7288
m_private->m_state = Private::DeviceData::STATE_OPEN_PENDING;
7389
SetEvent(s_kickEvent);
7490
}
7591
void PCSX::FTDI::Device::close() {
76-
std::shared_lock<std::shared_mutex> guard(s_listLock);
92+
std::unique_lock<std::shared_mutex> guard(s_listLock);
7793
assert(m_private->m_state == Private::DeviceData::STATE_OPENED);
7894
m_private->m_state = Private::DeviceData::STATE_CLOSE_PENDING;
7995
SetEvent(s_kickEvent);
@@ -85,19 +101,22 @@ void PCSX::FTDI::Devices::scan() {
85101
DWORD numDevs = 0;
86102

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

90-
s_devices.clear();
107+
delete[] s_devices;
108+
s_numDevs = 0;
91109
status = FT_CreateDeviceInfoList(&numDevs);
92110

93111
if (status != FT_OK || numDevs == 0) return;
112+
s_numDevs = numDevs;
94113

95114
FT_DEVICE_LIST_INFO_NODE* nodes = new FT_DEVICE_LIST_INFO_NODE[numDevs];
96115

97116
status = FT_GetDeviceInfoList(nodes, &numDevs);
98117

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

117136
void PCSX::FTDI::Devices::iterate(std::function<bool(Device&)> iter) {
118137
std::shared_lock<std::shared_mutex> guard(s_listLock);
119-
for (auto& d : s_devices) {
120-
if (!iter(d)) break;
138+
for (unsigned i = 0; i < s_numDevs; i++) {
139+
if (!iter(s_devices[i])) break;
121140
}
122141
}
123142

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

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

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

212+
void PCSX::FTDI::Devices::setGUI(GUI* gui) { s_gui = gui; }
213+
192214
#endif

src/ftdi/abstract.h

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@
2121

2222
#include <stdint.h>
2323

24+
#include <atomic>
2425
#include <functional>
2526
#include <string>
26-
#include <vector>
27+
28+
#include "gui/gui.h"
29+
#include "support/slice.h"
2730

2831
namespace PCSX {
2932

@@ -35,6 +38,7 @@ class DeviceData;
3538
}
3639
class Device {
3740
public:
41+
Device();
3842
~Device();
3943
bool isLocked() const { return m_locked; }
4044
bool isHighSpeed() const { return m_highSpeed; }
@@ -49,6 +53,9 @@ class Device {
4953
void open();
5054
void close();
5155

56+
// technically private, but difficult to enforce properly
57+
void asyncCallback() {}
58+
5259
private:
5360
bool m_locked = false;
5461
bool m_highSpeed = false;
@@ -58,7 +65,30 @@ class Device {
5865
std::string m_serial = "";
5966
std::string m_description = "";
6067

61-
Private::DeviceData* m_private;
68+
Private::DeviceData* m_private = nullptr;
69+
70+
static const unsigned SLICES_COUNT = 256;
71+
Slice m_slices[SLICES_COUNT];
72+
std::atomic_uint16_t m_slicesIndexes = 0;
73+
74+
uv_async_t m_async;
75+
76+
unsigned usedSlices() {
77+
uint16_t indexes = m_slicesIndexes.load();
78+
unsigned first = indexes & 0xff;
79+
unsigned last = (indexes >> 8) & 0xff;
80+
if (last < first) last += 256;
81+
return last - first;
82+
}
83+
84+
unsigned availableSlices() { return 256 - usedSlices(); }
85+
86+
Slice& allocateSlice() {
87+
while (availableSlices() == 0)
88+
;
89+
uint16_t indexes = m_slicesIndexes.fetch_add(0x100);
90+
return m_slices[(indexes >> 8) & 0xff];
91+
}
6292

6393
friend class Devices;
6494
};
@@ -70,6 +100,7 @@ class Devices {
70100
static bool isThreadRunning();
71101
static void startThread();
72102
static void stopThread();
103+
static void setGUI(GUI*);
73104

74105
// technically private, but difficult to enforce properly
75106
static void threadProc();

src/gui/gui.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ class GUI final {
105105
}
106106
}
107107

108+
uv_loop_t *loop() { return &m_loop; }
109+
108110
private:
109111
GLFWwindow *m_window = nullptr;
110112
int &m_glfwPosX = settings.get<WindowPosX>().value;

src/main/main.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "core/r3000a.h"
3131
#include "core/sstate.h"
3232
#include "flags.h"
33+
#include "ftdi/abstract.h"
3334
#include "gui/gui.h"
3435
#include "spu/interface.h"
3536
#include "support/slice.h"
@@ -197,6 +198,7 @@ int main(int argc, char **argv) {
197198
LoadPlugins();
198199
PCSX::g_emulator.m_gpu->open(s_gui);
199200
PCSX::g_emulator.m_spu->open();
201+
PCSX::FTDI::Devices::setGUI(s_gui);
200202

201203
PCSX::g_emulator.EmuInit();
202204
PCSX::g_emulator.EmuReset();

vsprojects/ftdi/ftdi.vcxproj

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,19 @@
5858
</ImportGroup>
5959
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
6060
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
61+
<Import Project="..\includes.props" />
6162
</ImportGroup>
6263
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
6364
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
65+
<Import Project="..\includes.props" />
6466
</ImportGroup>
6567
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
6668
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
69+
<Import Project="..\includes.props" />
6770
</ImportGroup>
6871
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
6972
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
73+
<Import Project="..\includes.props" />
7074
</ImportGroup>
7175
<PropertyGroup Label="UserMacros" />
7276
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -85,9 +89,10 @@
8589
<ClCompile>
8690
<WarningLevel>Level3</WarningLevel>
8791
<SDLCheck>true</SDLCheck>
88-
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
92+
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
8993
<ConformanceMode>true</ConformanceMode>
90-
<AdditionalIncludeDirectories>..\..\src</AdditionalIncludeDirectories>
94+
<AdditionalIncludeDirectories>..\..\src;..\..\third_party;..\..\third_party\imgui;..\..\third_party\imgui_club;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
95+
<LanguageStandard>stdcpp17</LanguageStandard>
9196
</ClCompile>
9297
<Link>
9398
<SubSystem>Console</SubSystem>
@@ -98,9 +103,10 @@
98103
<ClCompile>
99104
<WarningLevel>Level3</WarningLevel>
100105
<SDLCheck>true</SDLCheck>
101-
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
106+
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
102107
<ConformanceMode>true</ConformanceMode>
103-
<AdditionalIncludeDirectories>..\..\src</AdditionalIncludeDirectories>
108+
<AdditionalIncludeDirectories>..\..\src;..\..\third_party;..\..\third_party\imgui;..\..\third_party\imgui_club;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
109+
<LanguageStandard>stdcpp17</LanguageStandard>
104110
</ClCompile>
105111
<Link>
106112
<SubSystem>Console</SubSystem>
@@ -113,9 +119,10 @@
113119
<FunctionLevelLinking>true</FunctionLevelLinking>
114120
<IntrinsicFunctions>true</IntrinsicFunctions>
115121
<SDLCheck>true</SDLCheck>
116-
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
122+
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
117123
<ConformanceMode>true</ConformanceMode>
118-
<AdditionalIncludeDirectories>..\..\src</AdditionalIncludeDirectories>
124+
<AdditionalIncludeDirectories>..\..\src;..\..\third_party;..\..\third_party\imgui;..\..\third_party\imgui_club;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
125+
<LanguageStandard>stdcpp17</LanguageStandard>
119126
</ClCompile>
120127
<Link>
121128
<SubSystem>Console</SubSystem>
@@ -130,9 +137,10 @@
130137
<FunctionLevelLinking>true</FunctionLevelLinking>
131138
<IntrinsicFunctions>true</IntrinsicFunctions>
132139
<SDLCheck>true</SDLCheck>
133-
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
140+
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
134141
<ConformanceMode>true</ConformanceMode>
135-
<AdditionalIncludeDirectories>..\..\src</AdditionalIncludeDirectories>
142+
<AdditionalIncludeDirectories>..\..\src;..\..\third_party;..\..\third_party\imgui;..\..\third_party\imgui_club;..\..\third_party\libuv\include</AdditionalIncludeDirectories>
143+
<LanguageStandard>stdcpp17</LanguageStandard>
136144
</ClCompile>
137145
<Link>
138146
<SubSystem>Console</SubSystem>

vsprojects/includes.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
<ItemDefinitionGroup>
99
<ClCompile>
1010
<MultiProcessorCompilation>true</MultiProcessorCompilation>
11+
<AdditionalIncludeDirectories>
12+
</AdditionalIncludeDirectories>
1113
</ClCompile>
1214
</ItemDefinitionGroup>
1315
<ItemGroup />

0 commit comments

Comments
 (0)