This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [gomp] new critical section functions in libgomp


On Thu, Sep 22, 2005 at 02:23:10AM -0400, Jakub Jelinek wrote:
> Can't you optimize this for the cases where
> sizeof (gomp_mutex_t) <= sizeof (gomp_mutex_t *) \
> && __alignof (gomp_mutex_t) <= __alignof (gomp_mutex_t *) \
> && defined (GOMP_MUTEX_INIT_0)

Like so.  Also fixes the testsuite problem Diego reported.


r~


        * critical.c (GOMP_critical_name_start): Change argument to void**.
        Reuse the pointer space if the mutex fits.
        (GOMP_critical_name_end): Likewise.
        (initialize_critical): Don't define if GOMP_MUTEX_INIT_0.
        * libgomp_g.h (GOMP_critical_name_start): Update decl.
        (GOMP_critical_name_end): Likewise.
        * config/linux/mutex.h (GOMP_MUTEX_INIT_0): New.
        * config/posix/mutex.h (GOMP_MUTEX_INIT_0): New.

Index: critical.c
===================================================================
RCS file: /cvs/gcc/gcc/libgomp/Attic/critical.c,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 critical.c
--- critical.c	21 Sep 2005 23:11:45 -0000	1.1.2.2
+++ critical.c	22 Sep 2005 17:19:35 -0000
@@ -49,45 +49,70 @@ static gomp_mutex_t create_lock_lock;
 #endif
 
 void
-GOMP_critical_name_start (gomp_mutex_t **pplock)
+GOMP_critical_name_start (void **pptr)
 {
-  gomp_mutex_t *plock = *pplock;
+  gomp_mutex_t *plock;
 
-  if (plock == NULL)
+  /* If a mutex fits within the space for a pointer, and is zero initialized,
+     then use the pointer space directly.  */
+  if (GOMP_MUTEX_INIT_0
+      && sizeof (gomp_mutex_t) <= sizeof (void *)
+      && __alignof (gomp_mutex_t) <= sizeof (void *))
+    plock = (gomp_mutex_t *)pptr;
+
+  /* Otherwise we have to be prepared to malloc storage.  */
+  else
     {
-#ifdef HAVE_SYNC_BUILTINS
-      gomp_mutex_t *nlock = gomp_malloc (sizeof (gomp_mutex_t));
-      gomp_mutex_init (nlock);
+      plock = *pptr;
 
-      plock = __sync_val_compare_and_swap (pplock, plock, nlock);
-      if (plock != nlock)
-	{
-	  gomp_mutex_destroy (nlock);
-	  free (nlock);
-	}
-#else
-      gomp_mutex_lock (&create_lock_lock);
-      plock = *pplock;
       if (plock == NULL)
 	{
-	  plock = gomp_malloc (sizeof (gomp_mutex_t));
-	  gomp_mutex_init (plock);
-	  __sync_synchronize ();
-	  *pplock = plock;
-	}
-      gomp_mutex_unlock (&create_lock_lock);
+#ifdef HAVE_SYNC_BUILTINS
+	  gomp_mutex_t *nlock = gomp_malloc (sizeof (gomp_mutex_t));
+	  gomp_mutex_init (nlock);
+
+	  plock = __sync_val_compare_and_swap (pptr, plock, nlock);
+	  if (plock != nlock)
+	    {
+	      gomp_mutex_destroy (nlock);
+	      free (nlock);
+	    }
+#else
+	  gomp_mutex_lock (&create_lock_lock);
+	  plock = *pptr;
+	  if (plock == NULL)
+	    {
+	      plock = gomp_malloc (sizeof (gomp_mutex_t));
+	      gomp_mutex_init (plock);
+	      __sync_synchronize ();
+	      *pptr = plock;
+	    }
+	  gomp_mutex_unlock (&create_lock_lock);
 #endif
+	}
     }
 
   gomp_mutex_lock (plock);
 }
 
 void
-GOMP_critical_name_end (gomp_mutex_t **pplock)
+GOMP_critical_name_end (void **pptr)
 {
-  gomp_mutex_unlock (*pplock);
+  gomp_mutex_t *plock;
+
+  /* If a mutex fits within the space for a pointer, and is zero initialized,
+     then use the pointer space directly.  */
+  if (GOMP_MUTEX_INIT_0
+      && sizeof (gomp_mutex_t) <= sizeof (void *)
+      && __alignof (gomp_mutex_t) <= sizeof (void *))
+    plock = (gomp_mutex_t *)pptr;
+  else
+    plock = *pptr;
+
+  gomp_mutex_unlock (plock);
 }
 
+#if !GOMP_MUTEX_INIT_0
 static void __attribute__((constructor))
 initialize_critical (void)
 {
@@ -96,3 +121,4 @@ initialize_critical (void)
   gomp_mutex_init (&create_lock_lock);
 #endif
 }
+#endif
Index: libgomp_g.h
===================================================================
RCS file: /cvs/gcc/gcc/libgomp/Attic/libgomp_g.h,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 libgomp_g.h
--- libgomp_g.h	21 Sep 2005 23:11:45 -0000	1.1.2.2
+++ libgomp_g.h	22 Sep 2005 17:19:35 -0000
@@ -39,10 +39,10 @@ extern void GOMP_barrier (void);
 
 /* critical.c */
 
-extern void GOMP_critical_name_start (gomp_mutex_t **);
-extern void GOMP_critical_name_end (gomp_mutex_t **);
 extern void GOMP_critical_start (void);
 extern void GOMP_critical_end (void);
+extern void GOMP_critical_name_start (void **);
+extern void GOMP_critical_name_end (void **);
 
 /* loop.c */
 
Index: config/linux/mutex.h
===================================================================
RCS file: /cvs/gcc/gcc/libgomp/config/linux/Attic/mutex.h,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 mutex.h
--- config/linux/mutex.h	13 Jun 2005 22:13:10 -0000	1.1.2.1
+++ config/linux/mutex.h	22 Sep 2005 17:19:35 -0000
@@ -34,6 +34,8 @@
 
 typedef int gomp_mutex_t;
 
+#define GOMP_MUTEX_INIT_0 1
+
 static inline void gomp_mutex_init (gomp_mutex_t *mutex)
 {
   *mutex = 0;
Index: config/posix/mutex.h
===================================================================
RCS file: /cvs/gcc/gcc/libgomp/config/posix/Attic/mutex.h,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 mutex.h
--- config/posix/mutex.h	13 Jun 2005 22:13:12 -0000	1.1.2.1
+++ config/posix/mutex.h	22 Sep 2005 17:19:35 -0000
@@ -35,6 +35,8 @@
 
 typedef pthread_mutex_t gomp_mutex_t;
 
+#define GOMP_MUTEX_INIT_0 0
+
 static inline void gomp_mutex_init (gomp_mutex_t *mutex)
 {
   pthread_mutex_init (mutex, NULL);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]