Implement installing MISR (a mid-level interrupt service routine)
This is the middle-level interrupt handler that's triggered from the
LISR. It's just a dedicated thread for now.
Change-Id: I1a27facd695d97d33d6d4b6cf2010b772ad29e64
diff --git a/services/server/env/fuchsia/osfunc.cc b/services/server/env/fuchsia/osfunc.cc
index 10cccd5..5fa771c 100644
--- a/services/server/env/fuchsia/osfunc.cc
+++ b/services/server/env/fuchsia/osfunc.cc
@@ -100,6 +100,14 @@
}
};
+struct MisrHandle
+{
+ std::thread thread;
+ // ZX_EVENT_SIGNALED is used to wake up, and ZX_USER_SIGNAL_0 is used to
+ // force the handler to quit.
+ zx::event event;
+};
+
} // namespace msd_img
@@ -451,34 +459,67 @@
return 0;
}
-/*
- OSInstallMISR
-*/
PVRSRV_ERROR
OSInstallMISR(IMG_HANDLE *hMISRData, PFN_MISR pfnMISR, void *hData)
{
- NOT_IMPLEMENTED();
- return PVRSRV_ERROR_NOT_SUPPORTED;
+ auto misr_handle = std::make_unique<msd_img::MisrHandle>();
+ zx_status_t status = zx::event::create(0, &misr_handle->event);
+ if (status != ZX_OK)
+ {
+ return ZxStatusToError(status);
+ }
+ misr_handle->thread = std::thread(
+ [](PFN_MISR pfnMISR, void *hData, msd_img::MisrHandle *misr_handle) {
+ while (true)
+ {
+ zx_signals_t observed;
+ zx_status_t status = misr_handle->event.wait_one(ZX_EVENT_SIGNALED | ZX_USER_SIGNAL_0,
+ zx::time::infinite(), &observed);
+ if (status != ZX_OK)
+ {
+ DLOG("Failed to wait on MISR handle");
+ return;
+ }
+ // Clear before running the callback to ensure a signal during the
+ // callback won't be ignored.
+ status = misr_handle->event.signal(ZX_EVENT_SIGNALED, 0);
+ if (status != ZX_OK)
+ {
+ DLOG("Failed clear MISR handle");
+ return;
+ }
+ if (observed & ZX_USER_SIGNAL_0)
+ break;
+ pfnMISR(hData);
+ }
+ },
+ pfnMISR, hData, misr_handle.get());
+ *hMISRData = misr_handle.release();
+ return PVRSRV_OK;
}
-/*
- OSUninstallMISR
-*/
PVRSRV_ERROR
OSUninstallMISR(IMG_HANDLE hMISRData)
{
- NOT_IMPLEMENTED();
- return PVRSRV_ERROR_NOT_SUPPORTED;
+ auto misr_handle = reinterpret_cast<msd_img::MisrHandle *>(hMISRData);
+ if (misr_handle->event.signal(0, ZX_USER_SIGNAL_0) != ZX_OK)
+ {
+ DLOG("Failed to signal MISR on shutdown");
+ misr_handle->thread.detach();
+ }
+ else
+ {
+ misr_handle->thread.join();
+ }
+ delete misr_handle;
+ return PVRSRV_OK;
}
-/*
- OSScheduleMISR
-*/
PVRSRV_ERROR
OSScheduleMISR(IMG_HANDLE hMISRData)
{
- NOT_IMPLEMENTED();
- return PVRSRV_ERROR_NOT_SUPPORTED;
+ auto misr_handle = reinterpret_cast<msd_img::MisrHandle *>(hMISRData);
+ return ZxStatusToError(misr_handle->event.signal(0, ZX_EVENT_SIGNALED));
}
PVRSRV_ERROR