>From 2535ce3ac9fdd46ec44b0fa5f1e4f6dcaaaebd99 Mon Sep 17 00:00:00 2001
From: Bruno Haible
Date: Thu, 20 Jun 2019 04:08:16 +0200
Subject: [PATCH 09/26] windows-mutex: New module.
* lib/windows-mutex.h: New file, extracted from lib/glthread/lock.h.
* lib/windows-mutex.c: New file, extracted from lib/glthread/lock.c.
* lib/windows-spinlock.h: New file, extracted from lib/glthread/lock.h.
* lib/glthread/lock.h: Include windows-spinlock.h, windows-mutex.h.
(gl_spinlock_t): Remove type.
(gl_lock_t): Define using glwthread_mutex_t.
(gl_lock_initializer): Define using GLWTHREAD_MUTEX_INIT.
(glthread_lock_init): Define using glwthread_mutex_init.
(glthread_lock_lock): Define using glwthread_mutex_lock.
(glthread_lock_unlock): Define using glwthread_mutex_unlock.
(glthread_lock_destroy): Define using glwthread_mutex_destroy.
(glthread_lock_init_func, glthread_lock_lock_func,
glthread_lock_unlock_func, glthread_lock_destroy_func): Remove
declarations.
Use glwthread_spinlock_t instead of gl_spinlock_t.
(gl_rwlock_initializer, gl_recursive_lock_initializer): Define using
GLWTHREAD_SPINLOCK_INIT.
* lib/glthread/lock.c (glthread_lock_init_func, glthread_lock_lock_func,
glthread_lock_unlock_func, glthread_lock_destroy_func): Remove
functions.
* lib/glthread/cond.h: Use glwthread_spinlock_t instead of
gl_spinlock_t.
* modules/windows-mutex: New file.
* modules/lock (Depends-on): Add windows-mutex.
---
ChangeLog | 28 +++++++++++++++
lib/glthread/cond.h | 2 +-
lib/glthread/lock.c | 50 --------------------------
lib/glthread/lock.h | 33 +++++++-----------
lib/windows-mutex.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++
lib/windows-mutex.h | 51 +++++++++++++++++++++++++++
lib/windows-spinlock.h | 35 +++++++++++++++++++
modules/lock | 1 +
modules/windows-mutex | 28 +++++++++++++++
9 files changed, 251 insertions(+), 72 deletions(-)
create mode 100644 lib/windows-mutex.c
create mode 100644 lib/windows-mutex.h
create mode 100644 lib/windows-spinlock.h
create mode 100644 modules/windows-mutex
diff --git a/ChangeLog b/ChangeLog
index 06474ea..a168b23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,33 @@
2019-06-20 Bruno Haible
+ windows-mutex: New module.
+ * lib/windows-mutex.h: New file, extracted from lib/glthread/lock.h.
+ * lib/windows-mutex.c: New file, extracted from lib/glthread/lock.c.
+ * lib/windows-spinlock.h: New file, extracted from lib/glthread/lock.h.
+ * lib/glthread/lock.h: Include windows-spinlock.h, windows-mutex.h.
+ (gl_spinlock_t): Remove type.
+ (gl_lock_t): Define using glwthread_mutex_t.
+ (gl_lock_initializer): Define using GLWTHREAD_MUTEX_INIT.
+ (glthread_lock_init): Define using glwthread_mutex_init.
+ (glthread_lock_lock): Define using glwthread_mutex_lock.
+ (glthread_lock_unlock): Define using glwthread_mutex_unlock.
+ (glthread_lock_destroy): Define using glwthread_mutex_destroy.
+ (glthread_lock_init_func, glthread_lock_lock_func,
+ glthread_lock_unlock_func, glthread_lock_destroy_func): Remove
+ declarations.
+ Use glwthread_spinlock_t instead of gl_spinlock_t.
+ (gl_rwlock_initializer, gl_recursive_lock_initializer): Define using
+ GLWTHREAD_SPINLOCK_INIT.
+ * lib/glthread/lock.c (glthread_lock_init_func, glthread_lock_lock_func,
+ glthread_lock_unlock_func, glthread_lock_destroy_func): Remove
+ functions.
+ * lib/glthread/cond.h: Use glwthread_spinlock_t instead of
+ gl_spinlock_t.
+ * modules/windows-mutex: New file.
+ * modules/lock (Depends-on): Add windows-mutex.
+
+2019-06-20 Bruno Haible
+
windows-once: New module.
* lib/windows-once.h: New file, extracted from lib/glthread/lock.h.
* lib/windows-once.c: New file, extracted from lib/glthread/lock.c.
diff --git a/lib/glthread/cond.h b/lib/glthread/cond.h
index 6540f1d..f252c32 100644
--- a/lib/glthread/cond.h
+++ b/lib/glthread/cond.h
@@ -311,7 +311,7 @@ typedef struct
gl_linked_waitqueue_t;
typedef struct
{
- gl_spinlock_t guard; /* protects the initialization */
+ glwthread_spinlock_t guard; /* protects the initialization */
CRITICAL_SECTION lock; /* protects the remaining fields */
gl_linked_waitqueue_t waiters; /* waiting threads */
}
diff --git a/lib/glthread/lock.c b/lib/glthread/lock.c
index 587d1e7..e17f524 100644
--- a/lib/glthread/lock.c
+++ b/lib/glthread/lock.c
@@ -793,56 +793,6 @@ glthread_once_singlethreaded (gl_once_t *once_control)
#if USE_WINDOWS_THREADS
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-void
-glthread_lock_init_func (gl_lock_t *lock)
-{
- InitializeCriticalSection (&lock->lock);
- lock->guard.done = 1;
-}
-
-int
-glthread_lock_lock_func (gl_lock_t *lock)
-{
- if (!lock->guard.done)
- {
- if (InterlockedIncrement (&lock->guard.started) == 0)
- /* This thread is the first one to need this lock. Initialize it. */
- glthread_lock_init (lock);
- else
- {
- /* Don't let lock->guard.started grow and wrap around. */
- InterlockedDecrement (&lock->guard.started);
- /* Yield the CPU while waiting for another thread to finish
- initializing this lock. */
- while (!lock->guard.done)
- Sleep (0);
- }
- }
- EnterCriticalSection (&lock->lock);
- return 0;
-}
-
-int
-glthread_lock_unlock_func (gl_lock_t *lock)
-{
- if (!lock->guard.done)
- return EINVAL;
- LeaveCriticalSection (&lock->lock);
- return 0;
-}
-
-int
-glthread_lock_destroy_func (gl_lock_t *lock)
-{
- if (!lock->guard.done)
- return EINVAL;
- DeleteCriticalSection (&lock->lock);
- lock->guard.done = 0;
- return 0;
-}
-
/* ------------------------- gl_rwlock_t datatype ------------------------- */
/* In this file, the waitqueues are implemented as circular arrays. */
diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h
index 93e2e48..e2a49dc 100644
--- a/lib/glthread/lock.h
+++ b/lib/glthread/lock.h
@@ -690,6 +690,8 @@ extern int glthread_once_singlethreaded (gl_once_t *once_control);
# define WIN32_LEAN_AND_MEAN /* avoid including junk */
# include
+# include "windows-spinlock.h"
+# include "windows-mutex.h"
# include "windows-once.h"
# ifdef __cplusplus
@@ -707,34 +709,23 @@ extern "C" {
/* There is no way to statically initialize a CRITICAL_SECTION. It needs
to be done lazily, once only. For this we need spinlocks. */
-typedef struct { volatile int done; volatile long started; } gl_spinlock_t;
-
/* -------------------------- gl_lock_t datatype -------------------------- */
-typedef struct
- {
- gl_spinlock_t guard; /* protects the initialization */
- CRITICAL_SECTION lock;
- }
- gl_lock_t;
+typedef glwthread_mutex_t gl_lock_t;
# define gl_lock_define(STORAGECLASS, NAME) \
STORAGECLASS gl_lock_t NAME;
# define gl_lock_define_initialized(STORAGECLASS, NAME) \
STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
# define gl_lock_initializer \
- { { 0, -1 } }
+ GLWTHREAD_MUTEX_INIT
# define glthread_lock_init(LOCK) \
- (glthread_lock_init_func (LOCK), 0)
+ (glwthread_mutex_init (LOCK), 0)
# define glthread_lock_lock(LOCK) \
- glthread_lock_lock_func (LOCK)
+ glwthread_mutex_lock (LOCK)
# define glthread_lock_unlock(LOCK) \
- glthread_lock_unlock_func (LOCK)
+ glwthread_mutex_unlock (LOCK)
# define glthread_lock_destroy(LOCK) \
- glthread_lock_destroy_func (LOCK)
-extern void glthread_lock_init_func (gl_lock_t *lock);
-extern int glthread_lock_lock_func (gl_lock_t *lock);
-extern int glthread_lock_unlock_func (gl_lock_t *lock);
-extern int glthread_lock_destroy_func (gl_lock_t *lock);
+ glwthread_mutex_destroy (LOCK)
/* ------------------------- gl_rwlock_t datatype ------------------------- */
@@ -752,7 +743,7 @@ typedef struct
gl_carray_waitqueue_t;
typedef struct
{
- gl_spinlock_t guard; /* protects the initialization */
+ glwthread_spinlock_t guard; /* protects the initialization */
CRITICAL_SECTION lock; /* protects the remaining fields */
gl_carray_waitqueue_t waiting_readers; /* waiting readers */
gl_carray_waitqueue_t waiting_writers; /* waiting writers */
@@ -764,7 +755,7 @@ typedef struct
# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
# define gl_rwlock_initializer \
- { { 0, -1 } }
+ { GLWTHREAD_SPINLOCK_INIT }
# define glthread_rwlock_init(LOCK) \
(glthread_rwlock_init_func (LOCK), 0)
# define glthread_rwlock_rdlock(LOCK) \
@@ -789,7 +780,7 @@ extern int glthread_rwlock_destroy_func (gl_rwlock_t *lock);
typedef struct
{
- gl_spinlock_t guard; /* protects the initialization */
+ glwthread_spinlock_t guard; /* protects the initialization */
DWORD owner;
unsigned long depth;
CRITICAL_SECTION lock;
@@ -800,7 +791,7 @@ typedef struct
# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
# define gl_recursive_lock_initializer \
- { { 0, -1 }, 0, 0 }
+ { GLWTHREAD_SPINLOCK_INIT, 0, 0 }
# define glthread_recursive_lock_init(LOCK) \
(glthread_recursive_lock_init_func (LOCK), 0)
# define glthread_recursive_lock_lock(LOCK) \
diff --git a/lib/windows-mutex.c b/lib/windows-mutex.c
new file mode 100644
index 0000000..e2c94b8
--- /dev/null
+++ b/lib/windows-mutex.c
@@ -0,0 +1,95 @@
+/* Plain mutexes (native Windows implementation).
+ Copyright (C) 2005-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see . */
+
+/* Written by Bruno Haible , 2005.
+ Based on GCC's gthr-win32.h. */
+
+#include
+
+/* Specification. */
+#include "windows-mutex.h"
+
+#include
+
+void
+glwthread_mutex_init (glwthread_mutex_t *mutex)
+{
+ InitializeCriticalSection (&mutex->lock);
+ mutex->guard.done = 1;
+}
+
+int
+glwthread_mutex_lock (glwthread_mutex_t *mutex)
+{
+ if (!mutex->guard.done)
+ {
+ if (InterlockedIncrement (&mutex->guard.started) == 0)
+ /* This thread is the first one to need this mutex. Initialize it. */
+ glwthread_mutex_init (mutex);
+ else
+ {
+ /* Don't let mutex->guard.started grow and wrap around. */
+ InterlockedDecrement (&mutex->guard.started);
+ /* Yield the CPU while waiting for another thread to finish
+ initializing this mutex. */
+ while (!mutex->guard.done)
+ Sleep (0);
+ }
+ }
+ EnterCriticalSection (&mutex->lock);
+ return 0;
+}
+
+int
+glwthread_mutex_trylock (glwthread_mutex_t *mutex)
+{
+ if (!mutex->guard.done)
+ {
+ if (InterlockedIncrement (&mutex->guard.started) == 0)
+ /* This thread is the first one to need this mutex. Initialize it. */
+ glwthread_mutex_init (mutex);
+ else
+ {
+ /* Don't let mutex->guard.started grow and wrap around. */
+ InterlockedDecrement (&mutex->guard.started);
+ /* Let another thread finish initializing this mutex, and let it also
+ lock this mutex. */
+ return EBUSY;
+ }
+ }
+ if (!TryEnterCriticalSection (&mutex->lock))
+ return EBUSY;
+ return 0;
+}
+
+int
+glwthread_mutex_unlock (glwthread_mutex_t *mutex)
+{
+ if (!mutex->guard.done)
+ return EINVAL;
+ LeaveCriticalSection (&mutex->lock);
+ return 0;
+}
+
+int
+glwthread_mutex_destroy (glwthread_mutex_t *mutex)
+{
+ if (!mutex->guard.done)
+ return EINVAL;
+ DeleteCriticalSection (&mutex->lock);
+ mutex->guard.done = 0;
+ return 0;
+}
diff --git a/lib/windows-mutex.h b/lib/windows-mutex.h
new file mode 100644
index 0000000..edc738e
--- /dev/null
+++ b/lib/windows-mutex.h
@@ -0,0 +1,51 @@
+/* Plain mutexes (native Windows implementation).
+ Copyright (C) 2005-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see . */
+
+/* Written by Bruno Haible , 2005.
+ Based on GCC's gthr-win32.h. */
+
+#ifndef _WINDOWS_MUTEX_H
+#define _WINDOWS_MUTEX_H
+
+#define WIN32_LEAN_AND_MEAN /* avoid including junk */
+#include
+
+#include "windows-spinlock.h"
+
+typedef struct
+ {
+ glwthread_spinlock_t guard; /* protects the initialization */
+ CRITICAL_SECTION lock;
+ }
+ glwthread_mutex_t;
+
+#define GLWTHREAD_MUTEX_INIT { GLWTHREAD_SPINLOCK_INIT }
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void glwthread_mutex_init (glwthread_mutex_t *mutex);
+extern int glwthread_mutex_lock (glwthread_mutex_t *mutex);
+extern int glwthread_mutex_trylock (glwthread_mutex_t *mutex);
+extern int glwthread_mutex_unlock (glwthread_mutex_t *mutex);
+extern int glwthread_mutex_destroy (glwthread_mutex_t *mutex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WINDOWS_MUTEX_H */
diff --git a/lib/windows-spinlock.h b/lib/windows-spinlock.h
new file mode 100644
index 0000000..26a4b65
--- /dev/null
+++ b/lib/windows-spinlock.h
@@ -0,0 +1,35 @@
+/* Spinlocks (native Windows implementation).
+ Copyright (C) 2005-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see . */
+
+/* Written by Bruno Haible , 2005.
+ Based on GCC's gthr-win32.h. */
+
+#ifndef _WINDOWS_SPINLOCK_H
+#define _WINDOWS_SPINLOCK_H
+
+#define WIN32_LEAN_AND_MEAN /* avoid including junk */
+#include
+
+typedef struct
+ {
+ volatile int done;
+ volatile LONG started;
+ }
+ glwthread_spinlock_t;
+
+#define GLWTHREAD_SPINLOCK_INIT { 0, -1 }
+
+#endif /* _WINDOWS_SPINLOCK_H */
diff --git a/modules/lock b/modules/lock
index fca8341..351e902 100644
--- a/modules/lock
+++ b/modules/lock
@@ -10,6 +10,7 @@ m4/pthread_rwlock_rdlock.m4
Depends-on:
extensions
threadlib
+windows-mutex [test $gl_threads_api = windows]
windows-once [test $gl_threads_api = windows]
configure.ac:
diff --git a/modules/windows-mutex b/modules/windows-mutex
new file mode 100644
index 0000000..18aabcc
--- /dev/null
+++ b/modules/windows-mutex
@@ -0,0 +1,28 @@
+Description:
+Plain mutexes (native Windows implementation).
+
+Files:
+lib/windows-mutex.h
+lib/windows-mutex.c
+lib/windows-spinlock.h
+
+Depends-on:
+
+configure.ac:
+AC_REQUIRE([AC_CANONICAL_HOST])
+case "$host_os" in
+ mingw*)
+ AC_LIBOBJ([windows-mutex])
+ ;;
+esac
+
+Makefile.am:
+
+Include:
+"windows-mutex.h"
+
+License:
+LGPLv2+
+
+Maintainer:
+all
--
2.7.4