Author: miguel
Date: 2005-07-08 16:28:01 -0400 (Fri, 08 Jul 2005)
New Revision: 47119
Modified:
branches/mono-1-1-7/mono/mono/io-layer/handles.c
branches/mono-1-1-7/mono/mono/io-layer/mutex-private.h
branches/mono-1-1-7/mono/mono/io-layer/mutexes.c
branches/mono-1-1-7/mono/mono/io-layer/thread-private.h
branches/mono-1-1-7/mono/mono/io-layer/threads.c
branches/mono-1-1-7/mono/mono/io-layer/wapi-private.h
Log:
2005-06-21 Dick Porter <[EMAIL PROTECTED]>
* mutex-private.h:
* thread-private.h:
* mutexes.c:
* threads.c: Keep a list of owned mutexes in each thread handle,
so that it is easier to abandon them when the thread exits.
Removes a bottleneck when multiple threads are finishing in
parallel.
Modified: branches/mono-1-1-7/mono/mono/io-layer/handles.c
===================================================================
--- branches/mono-1-1-7/mono/mono/io-layer/handles.c 2005-07-08 20:26:42 UTC
(rev 47118)
+++ branches/mono-1-1-7/mono/mono/io-layer/handles.c 2005-07-08 20:28:01 UTC
(rev 47119)
@@ -729,7 +729,7 @@
}
}
- if (!found) {
+ if (!found && _WAPI_SHARED_HANDLE (type)) {
/* Not found yet, so search the shared memory too */
#ifdef DEBUG
g_message ("%s: Looking at other shared handles...", __func__);
Modified: branches/mono-1-1-7/mono/mono/io-layer/mutex-private.h
===================================================================
--- branches/mono-1-1-7/mono/mono/io-layer/mutex-private.h 2005-07-08
20:26:42 UTC (rev 47118)
+++ branches/mono-1-1-7/mono/mono/io-layer/mutex-private.h 2005-07-08
20:28:01 UTC (rev 47119)
@@ -36,6 +36,6 @@
guint32 recursion;
};
-extern void _wapi_mutex_check_abandoned (pid_t pid, pthread_t tid);
+extern void _wapi_mutex_abandon (gpointer data, pid_t pid, pthread_t tid);
#endif /* _WAPI_MUTEX_PRIVATE_H_ */
Modified: branches/mono-1-1-7/mono/mono/io-layer/mutexes.c
===================================================================
--- branches/mono-1-1-7/mono/mono/io-layer/mutexes.c 2005-07-08 20:26:42 UTC
(rev 47118)
+++ branches/mono-1-1-7/mono/mono/io-layer/mutexes.c 2005-07-08 20:28:01 UTC
(rev 47119)
@@ -102,13 +102,15 @@
struct _WapiHandle_mutex *mutex_handle;
gboolean ok;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
- (gpointer *)&mutex_handle);
- if(ok==FALSE) {
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
+ (gpointer *)&mutex_handle);
+ if (ok == FALSE) {
g_warning ("%s: error looking up mutex handle %p", __func__,
handle);
return(FALSE);
}
+
+ _wapi_thread_own_mutex (pthread_self (), handle);
#ifdef DEBUG
g_message("%s: owning mutex handle %p", __func__, handle);
@@ -186,6 +188,9 @@
__func__, handle);
return(FALSE);
}
+
+ _wapi_thread_own_mutex (pthread_self (), handle);
+
namedmutex_handle = &shared_handle.u.namedmutex;
namedmutex_handle->pid = getpid ();
@@ -245,17 +250,10 @@
}
}
-struct mutex_check_data
+static void mutex_abandon (gpointer handle, pid_t pid, pthread_t tid)
{
- pid_t pid;
- pthread_t tid;
-};
-
-static gboolean mutex_check (gpointer handle, gpointer user_data)
-{
struct _WapiHandle_mutex *mutex_handle;
gboolean ok;
- struct mutex_check_data *data = (struct mutex_check_data *)user_data;
int thr_ret;
ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
@@ -263,7 +261,7 @@
if (ok == FALSE) {
g_warning ("%s: error looking up mutex handle %p", __func__,
handle);
- return(FALSE);
+ return;
}
pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
@@ -271,8 +269,8 @@
thr_ret = _wapi_handle_lock_handle (handle);
g_assert (thr_ret == 0);
- if (mutex_handle->pid == data->pid &&
- mutex_handle->tid == data->tid) {
+ if (mutex_handle->pid == pid &&
+ mutex_handle->tid == tid) {
#ifdef DEBUG
g_message ("%s: Mutex handle %p abandoned!", __func__, handle);
#endif
@@ -287,16 +285,12 @@
thr_ret = _wapi_handle_unlock_handle (handle);
g_assert (thr_ret == 0);
pthread_cleanup_pop (0);
-
- /* Return false to keep searching */
- return(FALSE);
}
-static gboolean namedmutex_check (gpointer handle, gpointer user_data)
+static void namedmutex_abandon (gpointer handle, pid_t pid, pthread_t tid)
{
struct _WapiHandle_namedmutex *mutex_handle;
gboolean ok;
- struct mutex_check_data *data = (struct mutex_check_data *)user_data;
int thr_ret;
ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
@@ -304,14 +298,14 @@
if (ok == FALSE) {
g_warning ("%s: error looking up named mutex handle %p",
__func__, handle);
- return(FALSE);
+ return;
}
thr_ret = _wapi_handle_lock_shared_handles ();
g_assert (thr_ret == 0);
- if (mutex_handle->pid == data->pid &&
- mutex_handle->tid == data->tid) {
+ if (mutex_handle->pid == pid &&
+ mutex_handle->tid == tid) {
#ifdef DEBUG
g_message ("%s: Mutex handle %p abandoned!", __func__, handle);
#endif
@@ -324,22 +318,20 @@
}
_wapi_handle_unlock_shared_handles ();
-
- /* Return false to keep searching */
- return(FALSE);
}
/* When a thread exits, any mutexes it still holds need to be signalled */
-void _wapi_mutex_check_abandoned (pid_t pid, pthread_t tid)
+void _wapi_mutex_abandon (gpointer data, pid_t pid, pthread_t tid)
{
- struct mutex_check_data data;
+ WapiHandleType type = _wapi_handle_type (data);
- data.pid = pid;
- data.tid = tid;
-
- _wapi_search_handle (WAPI_HANDLE_MUTEX, mutex_check, &data, NULL);
- _wapi_search_handle (WAPI_HANDLE_NAMEDMUTEX, namedmutex_check, &data,
- NULL);
+ if (type == WAPI_HANDLE_MUTEX) {
+ mutex_abandon (data, pid, tid);
+ } else if (type == WAPI_HANDLE_NAMEDMUTEX) {
+ namedmutex_abandon (data, pid, tid);
+ } else {
+ g_assert_not_reached ();
+ }
}
static gpointer mutex_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
@@ -531,9 +523,9 @@
int thr_ret;
gboolean ret = FALSE;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
- (gpointer *)&mutex_handle);
- if(ok==FALSE) {
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
+ (gpointer *)&mutex_handle);
+ if (ok == FALSE) {
g_warning ("%s: error looking up mutex handle %p", __func__,
handle);
return(FALSE);
@@ -561,6 +553,8 @@
mutex_handle->recursion--;
if(mutex_handle->recursion==0) {
+ _wapi_thread_disown_mutex (tid, handle);
+
#ifdef DEBUG
g_message("%s: Unlocking mutex handle %p", __func__, handle);
#endif
@@ -615,6 +609,8 @@
mutex_handle->recursion--;
if(mutex_handle->recursion==0) {
+ _wapi_thread_disown_mutex (tid, handle);
+
#ifdef DEBUG
g_message("%s: Unlocking mutex handle %p", __func__, handle);
#endif
Modified: branches/mono-1-1-7/mono/mono/io-layer/thread-private.h
===================================================================
--- branches/mono-1-1-7/mono/mono/io-layer/thread-private.h 2005-07-08
20:26:42 UTC (rev 47118)
+++ branches/mono-1-1-7/mono/mono/io-layer/thread-private.h 2005-07-08
20:28:01 UTC (rev 47119)
@@ -29,11 +29,15 @@
pid_t owner_pid;
TimedThread *thread;
gboolean joined;
+ GPtrArray *owned_mutexes;
};
extern gboolean _wapi_thread_apc_pending (gpointer handle);
extern gboolean _wapi_thread_cur_apc_pending (void);
extern gboolean _wapi_thread_dispatch_apc_queue (gpointer handle);
+extern gpointer _wapi_thread_handle_from_id (guint32 tid);
+extern void _wapi_thread_own_mutex (pthread_t tid, gpointer mutex);
+extern void _wapi_thread_disown_mutex (pthread_t tid, gpointer mutex);
#endif /* _WAPI_THREAD_PRIVATE_H_ */
Modified: branches/mono-1-1-7/mono/mono/io-layer/threads.c
===================================================================
--- branches/mono-1-1-7/mono/mono/io-layer/threads.c 2005-07-08 20:26:42 UTC
(rev 47118)
+++ branches/mono-1-1-7/mono/mono/io-layer/threads.c 2005-07-08 20:28:01 UTC
(rev 47119)
@@ -44,10 +44,11 @@
static mono_mutex_t thread_hash_mutex = MONO_MUTEX_INITIALIZER;
static GHashTable *thread_hash=NULL;
+static void thread_close (gpointer handle, gpointer data);
static gboolean thread_own (gpointer handle);
struct _WapiHandleOps _wapi_thread_ops = {
- NULL, /* close_shared */
+ thread_close, /* close */
NULL, /* signal */
thread_own, /* own */
NULL, /* is_owned */
@@ -69,6 +70,17 @@
#endif
}
+static void thread_close (gpointer handle, gpointer data)
+{
+ struct _WapiHandle_thread *thread_handle = (struct _WapiHandle_thread
*)data;
+
+#ifdef DEBUG
+ g_message ("%s: closing thread handle %p", __func__, handle);
+#endif
+
+ g_ptr_array_free (thread_handle->owned_mutexes, TRUE);
+}
+
static gboolean thread_own (gpointer handle)
{
struct _WapiHandle_thread *thread_handle;
@@ -99,6 +111,7 @@
struct _WapiHandle_thread *thread_handle;
gboolean ok;
int thr_ret;
+ int i;
pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
handle);
@@ -113,7 +126,9 @@
return;
}
- _wapi_mutex_check_abandoned (getpid (), thread_handle->thread->id);
+ for (i = 0; i < thread_handle->owned_mutexes->len; i++) {
+ _wapi_mutex_abandon (g_ptr_array_index
(thread_handle->owned_mutexes, i), getpid (), thread_handle->thread->id);
+ }
#ifdef DEBUG
g_message ("%s: Recording thread handle %p exit status", __func__,
@@ -192,7 +207,8 @@
}
thread_handle.state = THREAD_STATE_START;
- thread_handle.owner_pid = getpid();
+ thread_handle.owner_pid = getpid ();
+ thread_handle.owned_mutexes = g_ptr_array_new ();
handle = _wapi_handle_new (WAPI_HANDLE_THREAD, &thread_handle);
if (handle == _WAPI_HANDLE_INVALID) {
@@ -314,17 +330,10 @@
return(ct_ret);
}
-gpointer OpenThread (guint32 access G_GNUC_UNUSED, gboolean inherit
G_GNUC_UNUSED, guint32 tid)
+gpointer _wapi_thread_handle_from_id (guint32 tid)
{
gpointer ret=NULL;
int thr_ret;
-
- mono_once (&thread_hash_once, thread_hash_init);
- mono_once (&thread_ops_once, thread_ops_init);
-
-#ifdef DEBUG
- g_message ("%s: looking up thread %d", __func__, tid);
-#endif
pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
(void *)&thread_hash_mutex);
@@ -336,7 +345,22 @@
thr_ret = mono_mutex_unlock(&thread_hash_mutex);
g_assert (thr_ret == 0);
pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
+gpointer OpenThread (guint32 access G_GNUC_UNUSED, gboolean inherit
G_GNUC_UNUSED, guint32 tid)
+{
+ gpointer ret=NULL;
+ mono_once (&thread_hash_once, thread_hash_init);
+ mono_once (&thread_ops_once, thread_ops_init);
+
+#ifdef DEBUG
+ g_message ("%s: looking up thread %d", __func__, tid);
+#endif
+
+ ret = _wapi_thread_handle_from_id (tid);
if(ret!=NULL) {
_wapi_handle_ref (ret);
}
@@ -445,7 +469,8 @@
mono_once (&thread_ops_once, thread_ops_init);
thread_handle.state = THREAD_STATE_START;
- thread_handle.owner_pid = getpid();
+ thread_handle.owner_pid = getpid ();
+ thread_handle.owned_mutexes = g_ptr_array_new ();
handle = _wapi_handle_new (WAPI_HANDLE_THREAD, &thread_handle);
if (handle == _WAPI_HANDLE_INVALID) {
@@ -551,24 +576,13 @@
{
gpointer ret=NULL;
guint32 tid;
- int thr_ret;
mono_once(&thread_hash_once, thread_hash_init);
mono_once (&thread_ops_once, thread_ops_init);
tid=GetCurrentThreadId();
- pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
- (void *)&thread_hash_mutex);
- thr_ret = mono_mutex_lock(&thread_hash_mutex);
- g_assert (thr_ret == 0);
-
- ret = g_hash_table_lookup (thread_hash, GUINT_TO_POINTER (tid));
-
- thr_ret = mono_mutex_unlock(&thread_hash_mutex);
- g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
-
+ ret = _wapi_thread_handle_from_id (tid);
if (!ret) {
ret = thread_attach (NULL);
}
@@ -962,8 +976,54 @@
return(1);
}
+void _wapi_thread_own_mutex (pthread_t tid, gpointer mutex)
+{
+ struct _WapiHandle_thread *thread_handle;
+ gboolean ok;
+ gpointer thread;
+ thread = _wapi_thread_handle_from_id (tid);
+ if (thread == NULL) {
+ g_warning ("%s: error looking up thread by ID", __func__);
+ return;
+ }
+ ok = _wapi_lookup_handle (thread, WAPI_HANDLE_THREAD,
+ (gpointer *)&thread_handle);
+ if (ok == FALSE) {
+ g_warning ("%s: error looking up thread handle %p", __func__,
+ thread);
+ return;
+ }
+
+ g_ptr_array_add (thread_handle->owned_mutexes, mutex);
+}
+
+void _wapi_thread_disown_mutex (pthread_t tid, gpointer mutex)
+{
+ struct _WapiHandle_thread *thread_handle;
+ gboolean ok;
+ gpointer thread;
+
+ thread = _wapi_thread_handle_from_id (tid);
+ if (thread == NULL) {
+ g_warning ("%s: error looking up thread by ID", __func__);
+ return;
+ }
+
+ ok = _wapi_lookup_handle (thread, WAPI_HANDLE_THREAD,
+ (gpointer *)&thread_handle);
+ if (ok == FALSE) {
+ g_warning ("%s: error looking up thread handle %p", __func__,
+ thread);
+ return;
+ }
+
+ g_ptr_array_remove (thread_handle->owned_mutexes, mutex);
+}
+
+
+
#ifdef WITH_INCLUDED_LIBGC
static void GC_suspend_handler (int sig)
Modified: branches/mono-1-1-7/mono/mono/io-layer/wapi-private.h
===================================================================
--- branches/mono-1-1-7/mono/mono/io-layer/wapi-private.h 2005-07-08
20:26:42 UTC (rev 47118)
+++ branches/mono-1-1-7/mono/mono/io-layer/wapi-private.h 2005-07-08
20:28:01 UTC (rev 47119)
@@ -24,7 +24,7 @@
/* Increment this whenever an incompatible change is made to the
* shared handle structure.
*/
-#define _WAPI_HANDLE_VERSION 6
+#define _WAPI_HANDLE_VERSION 7
typedef enum {
WAPI_HANDLE_UNUSED=0,
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches