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

Reply via email to