Implement event objects

Use zx::event

Change-Id: I98ae757b3c50af34ebd0b8a5251baa5b394ba518
diff --git a/BUILD.gn b/BUILD.gn
index 037b7b9..07fe15b 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -208,5 +208,6 @@
   deps = [
     "//garnet/lib/magma/include:msd_abi",
     "//garnet/lib/magma/src/magma_util",
+    "//zircon/public/lib/zx",
   ]
 }
diff --git a/services/server/env/fuchsia/osfunc.cc b/services/server/env/fuchsia/osfunc.cc
index baa12f9..b0dd0b8 100644
--- a/services/server/env/fuchsia/osfunc.cc
+++ b/services/server/env/fuchsia/osfunc.cc
@@ -30,6 +30,7 @@
 
 #include <shared_mutex>
 
+#include <lib/zx/event.h>
 #include <zircon/syscalls.h>
 
 #include "magma_util/macros.h"
@@ -49,6 +50,47 @@
 
 #define NOT_IMPLEMENTED() fprintf(stderr, "msd-img-rgx-mtk: Not implemented in %s:%s:%d\n", __func__, __FILE__, __LINE__);
 
+namespace msd_img
+{
+struct EventObject
+{
+	static constexpr uint32_t kMagic = 'hEVT';
+
+	uint32_t magic = kMagic;
+	zx::event event;
+	static EventObject *FromHandle(IMG_HANDLE img_event_object)
+	{
+		auto event_object = reinterpret_cast<EventObject *>(img_event_object);
+		assert(event_object->magic == kMagic);
+		return event_object;
+	}
+};
+
+} // namespace msd_img
+
+static PVRSRV_ERROR
+ZxStatusToError(zx_status_t status)
+{
+	switch (status)
+	{
+		case ZX_OK: return PVRSRV_OK;
+		case ZX_ERR_INTERNAL: return PVRSRV_ERROR_INTERNAL_ERROR;
+		case ZX_ERR_NOT_SUPPORTED: return PVRSRV_ERROR_NOT_SUPPORTED;
+		case ZX_ERR_NO_RESOURCES: return PVRSRV_ERROR_OUT_OF_MEMORY;
+		case ZX_ERR_NO_MEMORY: return PVRSRV_ERROR_OUT_OF_MEMORY;
+		case ZX_ERR_INVALID_ARGS: return PVRSRV_ERROR_INVALID_PARAMS;
+		case ZX_ERR_BAD_HANDLE: return PVRSRV_ERROR_INVALID_HANDLE_TYPE;
+		case ZX_ERR_OUT_OF_RANGE: return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+		case ZX_ERR_BUFFER_TOO_SMALL: return PVRSRV_ERROR_INVALID_PARAMS;
+		case ZX_ERR_BAD_STATE: return PVRSRV_ERROR_INVALID_DEVICE;
+		case ZX_ERR_TIMED_OUT: return PVRSRV_ERROR_TIMEOUT;
+		case ZX_ERR_UNAVAILABLE: return PVRSRV_ERROR_INVALID_DEVICE;
+		case ZX_ERR_ACCESS_DENIED: return PVRSRV_ERROR_INIT_FAILURE;
+		default: return PVRSRV_ERROR_NOT_SUPPORTED;
+	}
+}
+
+
 void
 OSThreadDumpInfo(IMG_HANDLE hDbgReqestHandle, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, void *pvDumpDebugFile)
 {
@@ -489,38 +531,33 @@
 	return PVRSRV_ERROR_NOT_SUPPORTED;
 }
 
-
 PVRSRV_ERROR
 OSEventObjectCreate(const IMG_CHAR *pszName, IMG_HANDLE *hEventObject)
 {
-	NOT_IMPLEMENTED();
-	return PVRSRV_ERROR_NOT_SUPPORTED;
+	std::unique_ptr<msd_img::EventObject> event_object = std::make_unique<msd_img::EventObject>();
+	zx_status_t status = zx::event::create(0, &event_object->event);
+	if (status != ZX_OK)
+	{
+		return ZxStatusToError(status);
+	}
+	*hEventObject = event_object.release();
+	return PVRSRV_OK;
 }
 
 
 PVRSRV_ERROR
 OSEventObjectDestroy(IMG_HANDLE hEventObject)
 {
-	NOT_IMPLEMENTED();
-	return PVRSRV_ERROR_NOT_SUPPORTED;
+	auto event_object = std::unique_ptr<msd_img::EventObject>(msd_img::EventObject::FromHandle(hEventObject));
+	return PVRSRV_OK;
 }
 
-/*
- * EventObjectWaitTimeout()
- */
-static PVRSRV_ERROR
-EventObjectWaitTimeout(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus, IMG_BOOL bHoldBridgeLock)
-{
-	NOT_IMPLEMENTED();
-	return PVRSRV_ERROR_NOT_SUPPORTED;
-}
-
-
 PVRSRV_ERROR
 OSEventObjectWait(IMG_HANDLE hOSEventKM)
 {
-	NOT_IMPLEMENTED();
-	return PVRSRV_ERROR_NOT_SUPPORTED;
+	auto event_object = msd_img::EventObject::FromHandle(hOSEventKM);
+	zx_status_t status = event_object->event.wait_one(ZX_EVENT_SIGNALED, zx::time::infinite(), nullptr);
+	return ZxStatusToError(status);
 }
 
 PVRSRV_ERROR
@@ -540,29 +577,39 @@
 PVRSRV_ERROR
 OSEventObjectWaitKernel(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus)
 {
-	NOT_IMPLEMENTED();
-	return PVRSRV_ERROR_NOT_SUPPORTED;
+	auto event_object = msd_img::EventObject::FromHandle(hOSEventKM);
+	zx_status_t status =
+		event_object->event.wait_one(ZX_EVENT_SIGNALED, zx::deadline_after(zx::usec(uiTimeoutus)), nullptr);
+	return ZxStatusToError(status);
 }
 
 PVRSRV_ERROR
 OSEventObjectOpen(IMG_HANDLE hEventObject, IMG_HANDLE *phOSEvent)
 {
-	NOT_IMPLEMENTED();
-	return PVRSRV_ERROR_NOT_SUPPORTED;
+	auto event_object = msd_img::EventObject::FromHandle(hEventObject);
+	auto event_object_duplicate = std::make_unique<msd_img::EventObject>();
+	zx_status_t status = event_object->event.duplicate(ZX_RIGHT_SAME_RIGHTS, &event_object_duplicate->event);
+	if (status != ZX_OK)
+	{
+		return ZxStatusToError(status);
+	}
+	*phOSEvent = event_object_duplicate.release();
+	return PVRSRV_OK;
 }
 
 PVRSRV_ERROR
 OSEventObjectClose(IMG_HANDLE hOSEventKM)
 {
-	NOT_IMPLEMENTED();
-	return PVRSRV_ERROR_NOT_SUPPORTED;
+	auto object = std::unique_ptr<msd_img::EventObject>(msd_img::EventObject::FromHandle(hOSEventKM));
+	return PVRSRV_OK;
 }
 
 PVRSRV_ERROR
 OSEventObjectSignal(IMG_HANDLE hEventObject)
 {
-	NOT_IMPLEMENTED();
-	return PVRSRV_ERROR_NOT_SUPPORTED;
+	auto object = msd_img::EventObject::FromHandle(hEventObject);
+	zx_status_t status = object->event.signal(0u, ZX_EVENT_SIGNALED);
+	return ZxStatusToError(status);
 }
 
 PVRSRV_ERROR