Add magma InflightList.
It won't be provided by Fuchsia SDK.
Change-Id: Ic0c2666051f2c61b809805308db5170a64058ef3
diff --git a/src/intel/vulkan/BUILD.gn b/src/intel/vulkan/BUILD.gn
index 509eb5a..768498a 100644
--- a/src/intel/vulkan/BUILD.gn
+++ b/src/intel/vulkan/BUILD.gn
@@ -83,7 +83,6 @@
":anv_extensions",
":gen",
"$magma_build_root/include:magma_abi",
- "$magma_build_root/src/magma_util:inflight_list",
"$mesa_build_root/src:sha1",
"$mesa_build_root/include:c_compat",
"$mesa_build_root/src/compiler/nir",
diff --git a/src/intel/vulkan/anv_magma_connection.cc b/src/intel/vulkan/anv_magma_connection.cc
index 7cd4d03..3cd526a 100644
--- a/src/intel/vulkan/anv_magma_connection.cc
+++ b/src/intel/vulkan/anv_magma_connection.cc
@@ -24,7 +24,7 @@
#include "anv_magma.h"
#include "common/gen_gem.h"
#include "magma_sysmem.h"
-#include "magma_util/inflight_list.h"
+#include "util/inflight_list.h"
#include "common/intel_log.h"
#include <assert.h>
#include <chrono>
@@ -93,7 +93,7 @@
class Connection : public anv_connection {
public:
- Connection(magma_connection_t magma_connection)
+ Connection(magma_connection_t magma_connection) : inflight_list_(InflightList_Create())
{
anv_connection::connection = magma_connection;
}
@@ -106,11 +106,12 @@
}
#endif // VK_USE_PLATFORM_FUCHSIA
magma_release_connection(magma_connection());
+ InflightList_Destroy(inflight_list_);
}
magma_connection_t magma_connection() { return anv_connection::connection; }
- magma::InflightList* inflight_list() { return &inflight_list_; }
+ InflightList* inflight_list() { return inflight_list_; }
#if VK_USE_PLATFORM_FUCHSIA
magma_status_t GetSysmemConnection(magma_sysmem_connection_t* sysmem_connection_out)
@@ -137,7 +138,7 @@
#if VK_USE_PLATFORM_FUCHSIA
magma_sysmem_connection_t sysmem_connection_{};
#endif // #if VK_USE_PLATFORM_FUCHSIA
- magma::InflightList inflight_list_;
+ InflightList* inflight_list_;
};
anv_connection* AnvMagmaCreateConnection(magma_connection_t connection)
@@ -161,21 +162,21 @@
magma_status_t AnvMagmaConnectionWait(anv_connection* connection, uint64_t buffer_id,
int64_t* timeout_ns)
{
- magma::InflightList* inflight_list = Connection::cast(connection)->inflight_list();
+ InflightList* inflight_list = Connection::cast(connection)->inflight_list();
auto start = std::chrono::high_resolution_clock::now();
- while (inflight_list->is_inflight(buffer_id) &&
+ while (InflightList_is_inflight(inflight_list, buffer_id) &&
std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::high_resolution_clock::now() - start)
.count() < *timeout_ns) {
magma_connection_t magma_connection = Connection::cast(connection)->magma_connection();
- magma::Status status = inflight_list->WaitForCompletion(magma_connection, *timeout_ns);
- if (status.ok()) {
- inflight_list->ServiceCompletions(magma_connection);
+ magma_status_t status = InflightList_WaitForCompletion(inflight_list, magma_connection, *timeout_ns);
+ if (status == MAGMA_STATUS_OK) {
+ InflightList_ServiceCompletions(inflight_list, magma_connection);
} else {
- return status.get();
+ return status;
}
}
return MAGMA_STATUS_OK;
@@ -183,11 +184,11 @@
int AnvMagmaConnectionIsBusy(anv_connection* connection, uint64_t buffer_id)
{
- magma::InflightList* inflight_list = Connection::cast(connection)->inflight_list();
+ InflightList* inflight_list = Connection::cast(connection)->inflight_list();
- inflight_list->ServiceCompletions(Connection::cast(connection)->magma_connection());
+ InflightList_ServiceCompletions(inflight_list, Connection::cast(connection)->magma_connection());
- return inflight_list->is_inflight(buffer_id) ? 1 : 0;
+ return InflightList_is_inflight(inflight_list, buffer_id) ? 1 : 0;
}
int AnvMagmaConnectionExec(anv_connection* connection, uint32_t context_id,
@@ -279,13 +280,13 @@
resources.data(),
semaphore_ids.data());
- magma::InflightList* inflight_list = Connection::cast(connection)->inflight_list();
+ InflightList* inflight_list = Connection::cast(connection)->inflight_list();
for (uint32_t i = 0; i < execbuf->buffer_count; i++) {
- inflight_list->add(resources[i].buffer_id);
+ InflightList_add(inflight_list, resources[i].buffer_id);
}
- inflight_list->ServiceCompletions(Connection::cast(connection)->magma_connection());
+ InflightList_ServiceCompletions(inflight_list, Connection::cast(connection)->magma_connection());
return 0;
}
diff --git a/src/util/BUILD.gn b/src/util/BUILD.gn
index 7cd09cb..89b2987 100644
--- a/src/util/BUILD.gn
+++ b/src/util/BUILD.gn
@@ -41,6 +41,7 @@
"futex.h",
"half_float.h",
"hash_table.h",
+ "inflight_list.h",
"list.h",
"macros.h",
"mesa-sha1.h",
@@ -75,6 +76,7 @@
":gen",
":headers",
"$mesa_build_root/include:c_compat",
+ "$magma_build_root/include:magma_abi",
]
public_configs = [ ":util_public_config" ]
@@ -86,6 +88,7 @@
"fast_idiv_by_const.c",
"half_float.c",
"hash_table.c",
+ "inflight_list.c",
"mesa-sha1.c",
"os_file.c",
"os_time.c",
diff --git a/src/util/inflight_list.c b/src/util/inflight_list.c
new file mode 100644
index 0000000..5cd816d
--- /dev/null
+++ b/src/util/inflight_list.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2019 Google, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "inflight_list.h"
+
+struct InflightList* InflightList_Create()
+{
+ struct InflightList* list = (struct InflightList*)malloc(sizeof(struct InflightList));
+ list->wait_ = magma_wait_notification_channel;
+ list->read_ = magma_read_notification_channel;
+ u_vector_init(&list->buffers_, sizeof(uint64_t), sizeof(uint64_t) * 8 /* initial byte size */);
+ list->size_ = 0;
+ return list;
+}
+
+void InflightList_Destroy(struct InflightList* list)
+{
+ u_vector_finish(&list->buffers_);
+ free(list);
+}
+
+void InflightList_add(struct InflightList* list, uint64_t buffer_id)
+{
+ assert(buffer_id != 0);
+ *(uint64_t*)u_vector_add(&list->buffers_) = buffer_id;
+ list->size_ += 1;
+}
+
+bool InflightList_remove(struct InflightList* list, uint64_t buffer_id)
+{
+ bool foundit = false;
+ void* element;
+
+ // Find the buffer_id, mark it for removal
+ u_vector_foreach(element, &list->buffers_)
+ {
+ if (*(uint64_t*)element == buffer_id) {
+ *(uint64_t*)element = 0;
+ foundit = true;
+ break;
+ }
+ }
+
+ if (!foundit)
+ return false; // Not found
+
+ assert(list->size_ > 0);
+ list->size_ -= 1;
+
+ // Remove all marked nodes at the tail
+ const int length = u_vector_length(&list->buffers_);
+
+ for (int i = 0; i < length; i++) {
+ element = u_vector_tail(&list->buffers_);
+ assert(element);
+ if (*(uint64_t*)element == 0) {
+ u_vector_remove(&list->buffers_);
+ } else {
+ break;
+ }
+ }
+
+ return true;
+}
+
+uint32_t InflightList_size(struct InflightList* list) { return list->size_; }
+
+bool InflightList_is_inflight(struct InflightList* list, uint64_t buffer_id)
+{
+ void* element;
+ u_vector_foreach(element, &list->buffers_)
+ {
+ if (*(uint64_t*)element == buffer_id)
+ return true;
+ }
+ return false;
+}
+
+magma_status_t InflightList_WaitForCompletion(struct InflightList* list,
+ magma_connection_t connection, int64_t timeout_ns)
+{
+ return list->wait_(connection, timeout_ns);
+}
+
+void InflightList_ServiceCompletions(struct InflightList* list, magma_connection_t connection)
+{
+ uint64_t buffer_ids[8];
+ uint64_t bytes_available = 0;
+ while (true) {
+ magma_status_t status =
+ list->read_(connection, buffer_ids, sizeof(buffer_ids), &bytes_available);
+ if (status != MAGMA_STATUS_OK) {
+ return;
+ }
+ if (bytes_available == 0)
+ return;
+ assert(bytes_available % sizeof(uint64_t) == 0);
+ for (uint32_t i = 0; i < bytes_available / sizeof(uint64_t); i++) {
+ assert(InflightList_is_inflight(list, buffer_ids[i]));
+ InflightList_remove(list, buffer_ids[i]);
+ }
+ }
+}
diff --git a/src/util/inflight_list.h b/src/util/inflight_list.h
new file mode 100644
index 0000000..2b5d55b
--- /dev/null
+++ b/src/util/inflight_list.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2019 Google, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef INFLIGHT_LIST_H
+#define INFLIGHT_LIST_H
+
+#include "u_vector.h"
+
+#include <assert.h>
+#include <magma.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+// A convenience utility for maintaining a list of inflight command buffers,
+// by reading completed buffer ids from the magma notification channel.
+// Not threadsafe.
+
+typedef magma_status_t (*wait_notification_channel_t)(magma_connection_t connection,
+ int64_t timeout_ns);
+
+typedef magma_status_t (*read_notification_channel_t)(magma_connection_t connection, void* buffer,
+ uint64_t buffer_size,
+ uint64_t* buffer_size_out);
+
+struct InflightList {
+ wait_notification_channel_t wait_;
+ read_notification_channel_t read_;
+ struct u_vector buffers_;
+ uint32_t size_;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct InflightList* InflightList_Create(void);
+
+void InflightList_Destroy(struct InflightList* list);
+
+static inline void InflightList_inject_for_test(struct InflightList* list,
+ wait_notification_channel_t wait,
+ read_notification_channel_t read)
+{
+ list->wait_ = wait;
+ list->read_ = read;
+}
+
+// Add to the end of the list.
+void InflightList_add(struct InflightList* list, uint64_t buffer_id);
+
+// Remove from anywhere in the list.
+bool InflightList_remove(struct InflightList* list, uint64_t buffer_id);
+
+uint32_t InflightList_size(struct InflightList* list);
+
+// Wait for a completion; returns MAGMA_STATUS_OK if a completion was
+// received before |timeout_ms|.
+magma_status_t InflightList_WaitForCompletion(struct InflightList* list,
+ magma_connection_t connection, int64_t timeout_ns);
+
+bool InflightList_is_inflight(struct InflightList* list, uint64_t buffer_id);
+
+// Read all outstanding completions and update the inflight list.
+void InflightList_ServiceCompletions(struct InflightList* list, magma_connection_t connection);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INFLIGHT_LIST_H
diff --git a/src/util/tests/inflight_list/BUILD.gn b/src/util/tests/inflight_list/BUILD.gn
new file mode 100644
index 0000000..bc0540a
--- /dev/null
+++ b/src/util/tests/inflight_list/BUILD.gn
@@ -0,0 +1,42 @@
+# Copyright 2019 Google, LLC
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+import("../../../../mesa.gni")
+
+mesa_source_set("inflight_list") {
+ testonly = true
+
+ sources = [
+ "test_inflight_list.cpp",
+ ]
+
+ deps = [ "$mesa_build_root/src/util" ]
+
+ if (is_fuchsia) {
+ deps += [
+ "$mesa_build_root/src/os",
+ "//third_party/googletest:gtest",
+ "//zircon/public/lib/fdio",
+ "//zircon/public/lib/zx",
+ "//zircon/system/fidl/fuchsia-io",
+ ]
+ }
+}
diff --git a/src/util/tests/inflight_list/test_inflight_list.cpp b/src/util/tests/inflight_list/test_inflight_list.cpp
new file mode 100644
index 0000000..2d26fb7
--- /dev/null
+++ b/src/util/tests/inflight_list/test_inflight_list.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright © 2019 Google, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <lib/zx/channel.h>
+
+#include "util/inflight_list.h"
+#include "gtest/gtest.h"
+
+struct TestConnection : public magma_connection {
+ TestConnection() { zx::channel::create(0, &channel[0], &channel[1]); }
+
+ zx::channel channel[2];
+};
+
+static magma_status_t wait_notification_channel(magma_connection_t connection, int64_t timeout_ns)
+{
+ zx_signals_t pending;
+ zx_status_t status =
+ static_cast<TestConnection*>(connection)
+ ->channel[0]
+ .wait_one(ZX_CHANNEL_READABLE, zx::deadline_after(zx::nsec(timeout_ns)), &pending);
+ if (status != ZX_OK)
+ return MAGMA_STATUS_INTERNAL_ERROR;
+ assert(pending & ZX_CHANNEL_READABLE);
+ return MAGMA_STATUS_OK;
+}
+
+static magma_status_t read_notification_channel(magma_connection_t connection, void* buffer,
+ uint64_t buffer_size, uint64_t* buffer_size_out)
+{
+ uint32_t buffer_actual_size;
+ zx_status_t status = static_cast<TestConnection*>(connection)
+ ->channel[0]
+ .read(0, buffer, nullptr, buffer_size, 0, &buffer_actual_size, nullptr);
+ if (status == ZX_OK) {
+ *buffer_size_out = buffer_actual_size;
+ return MAGMA_STATUS_OK;
+ }
+ return MAGMA_STATUS_INTERNAL_ERROR;
+}
+
+const uint64_t kBufferIdBase = 0xaabbccdd00000000;
+
+class TestInflightList : public ::testing::Test {
+public:
+ void SetUp() override { list_ = InflightList_Create(); }
+
+ void TearDown() override { InflightList_Destroy(list_); }
+
+protected:
+ InflightList* list_;
+};
+
+TEST_F(TestInflightList, RemoveWhenEmpty)
+{
+ EXPECT_FALSE(InflightList_remove(list_, kBufferIdBase));
+ EXPECT_EQ(0u, InflightList_size(list_));
+}
+
+TEST_F(TestInflightList, RemoveFromTail)
+{
+ InflightList_add(list_, kBufferIdBase + 1);
+ EXPECT_TRUE(InflightList_is_inflight(list_, kBufferIdBase + 1));
+ InflightList_add(list_, kBufferIdBase + 2);
+ EXPECT_TRUE(InflightList_is_inflight(list_, kBufferIdBase + 2));
+ EXPECT_EQ(2u, InflightList_size(list_));
+
+ EXPECT_TRUE(InflightList_remove(list_, kBufferIdBase + 1));
+ EXPECT_FALSE(InflightList_is_inflight(list_, kBufferIdBase + 1));
+ EXPECT_EQ(1u, InflightList_size(list_));
+ EXPECT_TRUE(InflightList_remove(list_, kBufferIdBase + 2));
+ EXPECT_FALSE(InflightList_is_inflight(list_, kBufferIdBase + 2));
+ EXPECT_EQ(0u, InflightList_size(list_));
+ EXPECT_EQ(0u, u_vector_length(&list_->buffers_));
+}
+
+TEST_F(TestInflightList, RemoveFromHead)
+{
+ InflightList_add(list_, kBufferIdBase + 1);
+ EXPECT_TRUE(InflightList_is_inflight(list_, kBufferIdBase + 1));
+ InflightList_add(list_, kBufferIdBase + 2);
+ EXPECT_TRUE(InflightList_is_inflight(list_, kBufferIdBase + 2));
+ EXPECT_EQ(2u, InflightList_size(list_));
+
+ EXPECT_TRUE(InflightList_remove(list_, kBufferIdBase + 2));
+ EXPECT_FALSE(InflightList_is_inflight(list_, kBufferIdBase + 2));
+ EXPECT_EQ(1u, InflightList_size(list_));
+ EXPECT_EQ(2u, u_vector_length(&list_->buffers_)); // Entry was only marked for deletion
+ EXPECT_TRUE(InflightList_remove(list_, kBufferIdBase + 1));
+ EXPECT_FALSE(InflightList_is_inflight(list_, kBufferIdBase + 1));
+ EXPECT_EQ(0u, InflightList_size(list_));
+ EXPECT_EQ(0u, u_vector_length(&list_->buffers_));
+}
+
+TEST_F(TestInflightList, RemoveMiddle)
+{
+ InflightList_add(list_, kBufferIdBase + 1);
+ EXPECT_TRUE(InflightList_is_inflight(list_, kBufferIdBase + 1));
+ InflightList_add(list_, kBufferIdBase + 2);
+ EXPECT_TRUE(InflightList_is_inflight(list_, kBufferIdBase + 2));
+ InflightList_add(list_, kBufferIdBase + 3);
+ EXPECT_TRUE(InflightList_is_inflight(list_, kBufferIdBase + 3));
+ EXPECT_EQ(3u, InflightList_size(list_));
+
+ EXPECT_TRUE(InflightList_remove(list_, kBufferIdBase + 2));
+ EXPECT_FALSE(InflightList_is_inflight(list_, kBufferIdBase + 2));
+ EXPECT_EQ(2u, InflightList_size(list_));
+ EXPECT_EQ(3u, u_vector_length(&list_->buffers_)); // Entry was only marked for deletion
+}
+
+TEST_F(TestInflightList, RemoveDouble)
+{
+ InflightList_add(list_, kBufferIdBase);
+ EXPECT_TRUE(InflightList_is_inflight(list_, kBufferIdBase));
+ InflightList_add(list_, kBufferIdBase);
+ EXPECT_TRUE(InflightList_is_inflight(list_, kBufferIdBase));
+ EXPECT_EQ(2u, InflightList_size(list_));
+
+ EXPECT_TRUE(InflightList_remove(list_, kBufferIdBase));
+ EXPECT_TRUE(InflightList_is_inflight(list_, kBufferIdBase));
+ EXPECT_EQ(1u, InflightList_size(list_));
+
+ EXPECT_TRUE(InflightList_remove(list_, kBufferIdBase));
+ EXPECT_FALSE(InflightList_is_inflight(list_, kBufferIdBase));
+ EXPECT_EQ(0u, InflightList_size(list_));
+}
+
+TEST_F(TestInflightList, WaitAndService)
+{
+ InflightList_inject_for_test(list_, wait_notification_channel, read_notification_channel);
+
+ uint64_t buffer_id = 0xabab1234;
+ EXPECT_FALSE(InflightList_is_inflight(list_, buffer_id));
+ InflightList_add(list_, buffer_id);
+ EXPECT_TRUE(InflightList_is_inflight(list_, buffer_id));
+
+ TestConnection connection;
+ EXPECT_NE(MAGMA_STATUS_OK, InflightList_WaitForCompletion(list_, &connection, 100));
+ connection.channel[1].write(0, &buffer_id, sizeof(buffer_id), nullptr, 0);
+ EXPECT_EQ(MAGMA_STATUS_OK, InflightList_WaitForCompletion(list_, &connection, 100));
+
+ InflightList_ServiceCompletions(list_, &connection);
+ EXPECT_FALSE(InflightList_is_inflight(list_, buffer_id));
+}
diff --git a/tests/BUILD.gn b/tests/BUILD.gn
index 33cb32f..7261314 100644
--- a/tests/BUILD.gn
+++ b/tests/BUILD.gn
@@ -39,6 +39,7 @@
deps = [
"unit_tests",
"$mesa_build_root/src/util/tests/os_dirent",
+ "$mesa_build_root/src/util/tests/inflight_list",
"//third_party/googletest:gtest",
]
}