Fast events

Maarten Lankhorst m.b.lankhorst at gmail.com
Sat May 12 08:29:31 CDT 2007


Hi all,

Since I'm trying to improve on winmm's timing scheduling, the best
improvement I can find is getting rid of the wineserver calls, they add
a huge delay to the timer and that is bad for something that should
sleep all the time to get better scheduling. I tried sending in a patch
that used linux sockets but it was rejected.

Similar patches already do exist: winealsa and wineoss use them, some
other sound drivers might use them too. Instead of duplicating that code
everywhere I think it's better to add a generic implementation of it
that can very easily be changed back to a win32 implementation.

What are your thoughts on this?

Maarten

fevent patch attached.
-------------- next part --------------
>From 5e5cb0a326f51dc2edef245fcaab4a071f9e0c42 Mon Sep 17 00:00:00 2001
From: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Sat, 12 May 2007 15:19:45 +0200
Subject: [PATCH] wine headers: introduce fevent interface

---
 include/wine/fevent.h |  145 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 145 insertions(+), 0 deletions(-)

diff --git a/include/wine/fevent.h b/include/wine/fevent.h
new file mode 100644
index 0000000..e80391d
--- /dev/null
+++ b/include/wine/fevent.h
@@ -0,0 +1,145 @@
+/*
+ * Fast event interface
+ * Use this for when default wineserver calls are extremely bad for time critical usages
+ * This is also REALLY *ONLY* useful in case of 1 thread doing a 'WaitForSingleObject'
+ * else weird effects might occur. If someone wants to use this in any other way, results
+ * are undetermined.
+ *
+ * Copyright (C) 2007 Maarten Lankhorst
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINESRC__
+#error This should only be used internally
+#endif
+
+#ifndef __WINE_WINE_FEVENT_H
+#define __WINE_WINE_FEVENT_H
+
+#if (defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H)) && !defined(WINE_FEVENT_USE_EVENT)
+
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+#ifdef HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#endif
+
+#include <errno.h>
+
+WINE_DECLARE_DEBUG_CHANNEL(fevent);
+
+struct TAGfevent {
+    int fd[2];
+    DWORD manreset;
+};
+
+typedef struct TAGfevent *FEVENT;
+
+static void reset_fd(FEVENT fev)
+{
+    char readme;
+    struct pollfd pfd;
+    pfd.fd = fev->fd[0];
+    pfd.events = POLLIN;
+    while (poll(&pfd, 1, 0) > 0)
+        read(fev->fd[0], &readme, sizeof(readme));
+}
+
+static void set_fd(FEVENT fev)
+{
+    char foo = 'A';
+
+    write(fev->fd[1], &foo, sizeof(foo));
+}
+
+static FEVENT create_fd(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName)
+{
+    FEVENT fev = HeapAlloc(GetProcessHeap(), 0, sizeof(*fev));
+
+    if (!fev)
+        goto err;
+
+    if (lpEventAttributes || lpName)
+       FIXME_(fevent)("FEVENTS are meant to be internal and shouldn't have security attributes or a name\n");
+
+    if (pipe(fev->fd) < 0)
+    {
+        fev->fd[0] = fev->fd[1] = -1;
+        goto err;
+    }
+    fev->manreset = bManualReset;
+    if (bInitialState)
+        set_fd(fev);
+    return fev;
+
+    err:
+    if (fev)
+    {
+        close(fev->fd[0]);
+        close(fev->fd[1]);
+        HeapFree(GetProcessHeap(), 0, fev);
+    }
+    return NULL;
+}
+
+static void close_fd(FEVENT fev)
+{
+    close(fev->fd[0]);
+    close(fev->fd[1]);
+    fev->fd[0] = fev->fd[1] = -1;
+    HeapFree(GetProcessHeap(), 0, fev);
+}
+
+static DWORD poll_fd(FEVENT fev, DWORD timeout)
+{
+    int err;
+    struct pollfd pfd;
+    pfd.fd = fev->fd[0];
+    pfd.events = POLLIN;
+
+    while ((err = poll(&pfd, 1, (int)timeout)) == -1)
+        if (errno != EAGAIN && errno != EINTR)
+            break;
+    switch (err)
+    {
+        case 0: return WAIT_TIMEOUT;
+        case -1: return WAIT_FAILED;
+        default:
+            if (!fev->manreset)
+                reset_fd(fev);
+            return WAIT_OBJECT_0;
+    }
+}
+
+#define RESETEVENT  reset_fd
+#define SETEVENT    set_fd
+#define CREATEEVENT create_fd
+#define CLOSEEVENT  close_fd
+#define WAITEVENT   poll_fd
+
+#else
+
+#define FEVENT HANDLE
+#define RESETEVENT ResetEvent
+#define SETEVENT SetEvent
+#define CREATEEVENT CreateEventW
+#define CLOSEEVENT CloseHandle
+#define WAITEVENT WaitForSingleObject
+
+#endif
+
+#endif  /* __WINE_WINE_FEVENT_H */
-- 
1.4.4.2



More information about the wine-devel mailing list