adding iris benchmark
[c11concurrency-benchmarks.git] / iris / src / notifier.cpp
diff --git a/iris/src/notifier.cpp b/iris/src/notifier.cpp
new file mode 100644 (file)
index 0000000..5d93185
--- /dev/null
@@ -0,0 +1,79 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <poll.h>
+
+#include <string>
+#include <system_error>
+
+#include <notifier.h>
+
+using namespace iris;
+
+notifier::notifier() {
+    if (::pipe(m_pipe)) {
+        std::string error_str = "failed to call pipe(), reason:";
+        error_str += strerror(errno);
+        throw std::system_error(std::error_code(errno, std::system_category()), error_str);
+    }   
+    if (fcntl(m_pipe[1], F_SETFL, O_NONBLOCK)) {
+        std::string error_str = "failed to set piep's write side to nonblock mode, reason:";
+        error_str += strerror(errno);
+        throw std::system_error(std::error_code(errno, std::system_category()), error_str);
+    }
+}
+
+notifier::~notifier() {
+    close(m_pipe[0]);
+    close(m_pipe[1]);
+}
+
+void notifier::notify(const ntf_t & ntf) {
+    size_t written = 0;
+    while (written < sizeof(ntf_t)) {
+        int n = write(m_pipe[1], (char *)&ntf, sizeof(ntf_t) - written);
+        if (n <= 0) {
+            if (errno == EINTR)
+                continue;
+            break;
+        }
+        written += n;
+    }
+}
+
+bool notifier::wait(long timeout, std::vector<ntf_t> & ntfs) {
+    struct pollfd pfd;
+    pfd.fd = m_pipe[0];
+    pfd.events = POLLIN;
+
+    if(poll(&pfd, 1, timeout) == 1) {
+        int flags = fcntl(m_pipe[0], F_GETFL, 0);
+        flags |= O_NONBLOCK;
+        fcntl(m_pipe[0], F_SETFL, flags);
+        while (true) {
+            ntf_t ntf;
+            size_t readn = 0;
+            while (readn < sizeof(ntf_t)) {
+                int n = read(m_pipe[0], &ntf, sizeof(ntf_t) - readn);
+                if (n <= 0) {
+                    if (errno == EINTR)
+                        continue;
+                    break;
+                }
+                readn += n;
+            }
+            if (readn >= sizeof(ntf_t)) {
+                ntfs.push_back(ntf);
+            } else {
+                break;
+            }
+        }
+        flags &= ~O_NONBLOCK;
+        fcntl(m_pipe[0], F_SETFL, flags);
+
+        return true;
+    }
+
+    return false;
+}
\ No newline at end of file