Skip to content

Commit feba3ea

Browse files
fix: last signaled value in Windows external semaphore enqueueWait
Related-To: NEO-17636 Signed-off-by: Eric Mortensen <eric.mortensen@intel.com> Source: 7b0cef3
1 parent 2fa7140 commit feba3ea

2 files changed

Lines changed: 140 additions & 17 deletions

File tree

shared/source/os_interface/windows/external_semaphore_windows.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ bool ExternalSemaphoreWindows::enqueueWait(uint64_t *fenceValue) {
180180

181181
uint64_t lastSignaledValue = 0;
182182
if (this->type == ExternalSemaphore::OpaqueWin32) {
183-
lastSignaledValue = *this->pLastSignaledValue + 2;
183+
lastSignaledValue = *this->pLastSignaledValue;
184184
wait.FenceValueArray = &lastSignaledValue;
185185
} else {
186186
wait.FenceValueArray = fenceValue;

shared/test/unit_test/semaphore/windows/test_semaphore_windows.cpp

Lines changed: 139 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
*/
77

88
#include "shared/source/execution_environment/root_device_environment.h"
9-
#include "shared/source/os_interface/external_semaphore.h"
109
#include "shared/source/os_interface/os_interface.h"
10+
#include "shared/source/os_interface/windows/external_semaphore_windows.h"
1111
#include "shared/test/common/mocks/mock_builtins.h"
1212
#include "shared/test/common/mocks/mock_device.h"
1313
#include "shared/test/common/os_interface/windows/wddm_fixture.h"
@@ -19,18 +19,18 @@ namespace NEO {
1919

2020
using WddmExternalSemaphoreTest = WddmFixture;
2121

22-
TEST_F(WddmExternalSemaphoreTest, givenOpaqueFdSemaphoreWhenCreateExternalSemaphoreIsCalledThenNullptrIsReturned) {
23-
auto externalSemaphore = ExternalSemaphore::create(osInterface, ExternalSemaphore::Type::OpaqueFd, nullptr, 0u, nullptr);
24-
EXPECT_EQ(externalSemaphore, nullptr);
25-
}
26-
2722
TEST_F(WddmExternalSemaphoreTest, givenNullOsInterfaceWhenCreateExternalSemaphoreIsCalledThenNullptrIsReturned) {
2823
HANDLE extSemaphoreHandle = 0;
2924

3025
auto externalSemaphore = ExternalSemaphore::create(nullptr, ExternalSemaphore::Type::D3d12Fence, extSemaphoreHandle, 0u, nullptr);
3126
EXPECT_EQ(externalSemaphore, nullptr);
3227
}
3328

29+
TEST_F(WddmExternalSemaphoreTest, givenOpaqueFdSemaphoreWhenCreateExternalSemaphoreIsCalledThenNullptrIsReturned) {
30+
auto externalSemaphore = ExternalSemaphore::create(osInterface, ExternalSemaphore::Type::OpaqueFd, nullptr, 0u, nullptr);
31+
EXPECT_EQ(externalSemaphore, nullptr);
32+
}
33+
3434
TEST_F(WddmExternalSemaphoreTest, givenValidD3d12FenceSemaphoreWhenCreateExternalSemaphoreIsCalledThenSemaphoreIsSuccessfullyReturned) {
3535
HANDLE extSemaphoreHandle = 0;
3636

@@ -53,24 +53,147 @@ TEST_F(WddmExternalSemaphoreTest, givenValidTimelineSemaphoreWin32WhenCreateExte
5353
EXPECT_NE(externalSemaphore, nullptr);
5454
}
5555

56-
class MockFailGdi : public MockGdi {
56+
class MockWindowsExternalSemaphore : public ExternalSemaphoreWindows {
5757
public:
58-
MockFailGdi() : MockGdi() {
59-
openSyncObjectNtHandleFromName = mockD3DKMTOpenSyncObjectNtHandleFromName;
60-
openSyncObjectFromNtHandle2 = mockD3DKMTOpenSyncObjectFromNtHandle2;
58+
using ExternalSemaphoreWindows::enqueueSignal;
59+
using ExternalSemaphoreWindows::enqueueWait;
60+
61+
MockWindowsExternalSemaphore(OSInterface *osInterface, ExternalSemaphore::Type type, uint64_t *signalVal) {
62+
this->osInterface = osInterface;
63+
this->type = type;
64+
this->state = ExternalSemaphore::SemaphoreState::Initial;
65+
this->syncHandle = 1;
66+
this->pCpuAddress = nullptr;
67+
this->pLastSignaledValue = signalVal;
6168
}
6269

63-
static NTSTATUS __stdcall mockD3DKMTOpenSyncObjectNtHandleFromName(IN OUT D3DKMT_OPENSYNCOBJECTNTHANDLEFROMNAME *) {
64-
return STATUS_UNSUCCESSFUL;
70+
uint64_t lastSignaledValue() const {
71+
return pLastSignaledValue ? *pLastSignaledValue : 0u;
6572
}
73+
};
6674

67-
static NTSTATUS __stdcall mockD3DKMTOpenSyncObjectFromNtHandle2(IN OUT D3DKMT_OPENSYNCOBJECTFROMNTHANDLE2 *) {
68-
return STATUS_UNSUCCESSFUL;
75+
class MockSyncGdi : public MockGdi {
76+
public:
77+
MockSyncGdi() : MockGdi() {
78+
openSyncObjectNtHandleFromName = mockOpenSyncObjectNtHandleFromName;
79+
openSyncObjectFromNtHandle2 = mockOpenSyncObjectFromNtHandle2;
80+
waitForSynchronizationObjectFromCpu = mockWaitForSynchronizationObjectFromCpu;
81+
signalSynchronizationObjectFromCpu = mockSignalSynchronizationObjectFromCpu;
82+
}
83+
84+
static NTSTATUS __stdcall mockOpenSyncObjectNtHandleFromName(IN OUT D3DKMT_OPENSYNCOBJECTNTHANDLEFROMNAME *) {
85+
return (failOpenSyncObjectNtHandleName ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS);
86+
}
87+
88+
static NTSTATUS __stdcall mockOpenSyncObjectFromNtHandle2(IN OUT D3DKMT_OPENSYNCOBJECTFROMNTHANDLE2 *) {
89+
return (failOpenSyncObjectFromNtHandle ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS);
6990
}
91+
92+
static NTSTATUS __stdcall mockWaitForSynchronizationObjectFromCpu(IN CONST D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU *) {
93+
return (failWaitForSynchObjectFromCpu ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS);
94+
}
95+
96+
static NTSTATUS __stdcall mockSignalSynchronizationObjectFromCpu(IN CONST D3DKMT_SIGNALSYNCHRONIZATIONOBJECTFROMCPU *) {
97+
return (failSignalSynchObjectFromCpu ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS);
98+
}
99+
100+
static bool failOpenSyncObjectNtHandleName;
101+
static bool failOpenSyncObjectFromNtHandle;
102+
static bool failWaitForSynchObjectFromCpu;
103+
static bool failSignalSynchObjectFromCpu;
70104
};
71105

106+
bool MockSyncGdi::failOpenSyncObjectNtHandleName = true;
107+
bool MockSyncGdi::failOpenSyncObjectFromNtHandle = true;
108+
bool MockSyncGdi::failWaitForSynchObjectFromCpu = false;
109+
bool MockSyncGdi::failSignalSynchObjectFromCpu = false;
110+
111+
TEST_F(WddmExternalSemaphoreTest, givenGdiWaitForSyncObjFailsWhenEnqueueSignalIsCalledWithOpaqueWin32ThenFalseIsReturnedAndSignalValueIsNotUpdated) {
112+
auto mockGdi = new MockSyncGdi();
113+
static_cast<OsEnvironmentWin *>(executionEnvironment->osEnvironment.get())->gdi.reset(mockGdi);
114+
115+
uint64_t signalVal = 0u;
116+
auto extSem = new MockWindowsExternalSemaphore{osInterface, ExternalSemaphore::Type::OpaqueWin32, &signalVal};
117+
EXPECT_NE(extSem, nullptr);
118+
EXPECT_EQ(extSem->getState(), ExternalSemaphore::SemaphoreState::Initial);
119+
EXPECT_EQ(extSem->lastSignaledValue(), 0u);
120+
EXPECT_EQ(signalVal, 0u);
121+
122+
MockSyncGdi::failSignalSynchObjectFromCpu = true;
123+
auto result = extSem->enqueueSignal(&signalVal);
124+
MockSyncGdi::failSignalSynchObjectFromCpu = false;
125+
EXPECT_EQ(result, false);
126+
EXPECT_EQ(extSem->getState(), ExternalSemaphore::SemaphoreState::Initial);
127+
EXPECT_EQ(extSem->lastSignaledValue(), signalVal);
128+
EXPECT_EQ(signalVal, 0ull);
129+
130+
delete extSem;
131+
}
132+
133+
TEST_F(WddmExternalSemaphoreTest, givenGdiWaitForSyncObjFailsWhenEnqueueWaitIsCalledWithOpaqueWin32ThenFalseIsReturned) {
134+
auto mockGdi = new MockSyncGdi();
135+
static_cast<OsEnvironmentWin *>(executionEnvironment->osEnvironment.get())->gdi.reset(mockGdi);
136+
137+
uint64_t signalVal = 0u;
138+
auto extSem = new MockWindowsExternalSemaphore{osInterface, ExternalSemaphore::Type::OpaqueWin32, &signalVal};
139+
EXPECT_NE(extSem, nullptr);
140+
EXPECT_EQ(extSem->getState(), ExternalSemaphore::SemaphoreState::Initial);
141+
EXPECT_EQ(extSem->lastSignaledValue(), 0u);
142+
EXPECT_EQ(signalVal, 0ull);
143+
144+
MockSyncGdi::failWaitForSynchObjectFromCpu = true;
145+
auto result = extSem->enqueueWait(&signalVal);
146+
MockSyncGdi::failWaitForSynchObjectFromCpu = false;
147+
EXPECT_EQ(result, false);
148+
EXPECT_EQ(extSem->getState(), ExternalSemaphore::SemaphoreState::Initial);
149+
EXPECT_EQ(extSem->lastSignaledValue(), signalVal);
150+
EXPECT_EQ(signalVal, 0ull);
151+
152+
delete extSem;
153+
}
154+
155+
TEST_F(WddmExternalSemaphoreTest, givenGdiWaitForSyncObjSucceedsWhenEnqueueSignalIsCalledWithOpaqueWin32ThenTrueIsReturnedAndSignalValueIsUpdated) {
156+
auto mockGdi = new MockSyncGdi();
157+
static_cast<OsEnvironmentWin *>(executionEnvironment->osEnvironment.get())->gdi.reset(mockGdi);
158+
159+
uint64_t signalVal = 0u;
160+
auto extSem = new MockWindowsExternalSemaphore{osInterface, ExternalSemaphore::Type::OpaqueWin32, &signalVal};
161+
EXPECT_NE(extSem, nullptr);
162+
EXPECT_EQ(extSem->getState(), ExternalSemaphore::SemaphoreState::Initial);
163+
EXPECT_EQ(extSem->lastSignaledValue(), 0u);
164+
EXPECT_EQ(signalVal, 0ull);
165+
166+
auto result = extSem->enqueueSignal(&signalVal);
167+
EXPECT_EQ(result, true);
168+
EXPECT_EQ(extSem->getState(), ExternalSemaphore::SemaphoreState::Signaled);
169+
EXPECT_EQ(extSem->lastSignaledValue(), signalVal);
170+
EXPECT_EQ(signalVal, 2ull);
171+
172+
delete extSem;
173+
}
174+
175+
TEST_F(WddmExternalSemaphoreTest, givenGdiWaitForSyncObjSucceedsWhenEnqueueWaitIsCalledWithOpaqueWin32ThenTrueIsReturned) {
176+
auto mockGdi = new MockSyncGdi();
177+
static_cast<OsEnvironmentWin *>(executionEnvironment->osEnvironment.get())->gdi.reset(mockGdi);
178+
179+
uint64_t signalVal = 0u;
180+
auto extSem = new MockWindowsExternalSemaphore{osInterface, ExternalSemaphore::Type::OpaqueWin32, &signalVal};
181+
EXPECT_NE(extSem, nullptr);
182+
EXPECT_EQ(extSem->getState(), ExternalSemaphore::SemaphoreState::Initial);
183+
EXPECT_EQ(extSem->lastSignaledValue(), 0u);
184+
EXPECT_EQ(signalVal, 0ull);
185+
186+
auto result = extSem->enqueueWait(&signalVal);
187+
EXPECT_EQ(result, true);
188+
EXPECT_EQ(extSem->getState(), ExternalSemaphore::SemaphoreState::Signaled);
189+
EXPECT_EQ(extSem->lastSignaledValue(), signalVal);
190+
EXPECT_EQ(signalVal, 0ull);
191+
192+
delete extSem;
193+
}
194+
72195
TEST_F(WddmExternalSemaphoreTest, givenTimelineSemaphoreWin32FailsToOpenSyncObjectFromNameThenNullptrIsReturned) {
73-
auto mockGdi = new MockFailGdi();
196+
auto mockGdi = new MockSyncGdi();
74197
static_cast<OsEnvironmentWin *>(executionEnvironment->osEnvironment.get())->gdi.reset(mockGdi);
75198
HANDLE extSemaphoreHandle = 0;
76199
const char *extSemName = "timeline_semaphore_name";
@@ -80,7 +203,7 @@ TEST_F(WddmExternalSemaphoreTest, givenTimelineSemaphoreWin32FailsToOpenSyncObje
80203
}
81204

82205
TEST_F(WddmExternalSemaphoreTest, givenTimelineSemaphoreWin32FailsToOpenSyncObjectFromNtHandleThenNullptrIsReturned) {
83-
auto mockGdi = new MockFailGdi();
206+
auto mockGdi = new MockSyncGdi();
84207
static_cast<OsEnvironmentWin *>(executionEnvironment->osEnvironment.get())->gdi.reset(mockGdi);
85208
HANDLE extSemaphoreHandle = 0;
86209

0 commit comments

Comments
 (0)