This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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]

[PATCH] pthread_once: Clean up constants.


This is part c) of
https://sourceware.org/bugzilla/show_bug.cgi?id=15215: Replace magic
numbers with name constants.  Also updates the documentation.
Applies on top of the pthread_once unification patch I sent recently.

OK?

2013-10-11  Torvald Riegel  <triegel@redhat.com>

	[BZ #15215]
	* pthreadP.h (__PTHREAD_ONCE_INPROGRESS, __PTHREAD_ONCE_DONE,
	__PTHREAD_ONCE_FORK_GEN_INCR): New.
	* sysdeps/unix/sysv/linux/fork.c (__libc_fork): Use them.
	* sysdeps/unix/sysv/linux/pthread_once.c (__pthread_once): Likewise.
	Update comments.

commit d0e5a3556c793ab44428eade2673274f1e8e4e9e
Author: Torvald Riegel <triegel@redhat.com>
Date:   Fri Oct 11 18:58:04 2013 +0300

    pthread_once: Clean up constants.
    
    [BZ #15215] This just gives a name to the integer constants being used.

diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 789bbf6..59717ef 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -159,6 +159,12 @@ enum
 #define FUTEX_TID_MASK		0x3fffffff
 
 
+/* pthread_once definitions.  See __pthread_once for how these are used.  */
+#define __PTHREAD_ONCE_INPROGRESS	1
+#define __PTHREAD_ONCE_DONE		2
+#define __PTHREAD_ONCE_FORK_GEN_INCR	4
+
+
 /* Internal variables.  */
 
 
diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c
index ff08942..0e1d4e1 100644
--- a/nptl/sysdeps/unix/sysv/linux/fork.c
+++ b/nptl/sysdeps/unix/sysv/linux/fork.c
@@ -140,8 +140,9 @@ __libc_fork (void)
 
       assert (THREAD_GETMEM (self, tid) != ppid);
 
+      /* See __pthread_once.  */
       if (__fork_generation_pointer != NULL)
-	*__fork_generation_pointer += 4;
+	*__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR;
 
       /* Adjust the PID field for the new process.  */
       THREAD_SETMEM (self, pid, THREAD_GETMEM (self, tid));
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/pthread_once.c
index f9b0953..c364ed1 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_once.c
+++ b/nptl/sysdeps/unix/sysv/linux/pthread_once.c
@@ -37,8 +37,11 @@ clear_once_control (void *arg)
 
 
 /* This is similar to a lock implementation, but we distinguish between three
-   states: not yet initialized (0), initialization finished (2), and
-   initialization in progress (__fork_generation | 1).  If in the first state,
+   states: not yet initialized (0), initialization in progress
+   (__fork_generation | __PTHREAD_ONCE_INPROGRESS), and initialization
+   finished (__PTHREAD_ONCE_DONE); __fork_generation does not use the bits
+   that are used for __PTHREAD_ONCE_INPROGRESS and __PTHREAD_ONCE_DONE (which
+   is what __PTHREAD_ONCE_FORK_GEN_INCR is used for).  If in the first state,
    threads will try to run the initialization by moving to the second state;
    the first thread to do so via a CAS on once_control runs init_routine,
    other threads block.
@@ -63,14 +66,14 @@ __pthread_once (once_control, init_routine)
       int oldval, val, newval;
 
       /* We need acquire memory order for this load because if the value
-         signals that initialization has finished, we need to be see any
+         signals that initialization has finished, we need to see any
          data modifications done during initialization.  */
       val = *once_control;
       atomic_read_barrier();
       do
 	{
 	  /* Check if the initialization has already been done.  */
-	  if (__builtin_expect ((val & 2) != 0, 1))
+	  if (__builtin_expect ((val & __PTHREAD_ONCE_DONE) != 0, 1))
 	    return 0;
 
 	  oldval = val;
@@ -79,7 +82,7 @@ __pthread_once (once_control, init_routine)
 	     generation because it's immutable in a particular process, and
 	     forked child processes start with a single thread that modified
 	     the generation.  */
-	  newval = __fork_generation | 1;
+	  newval = __fork_generation | __PTHREAD_ONCE_INPROGRESS;
 	  /* We need acquire memory order here for the same reason as for the
 	     load from once_control above.  */
 	  val = atomic_compare_and_exchange_val_acq (once_control, newval,
@@ -88,11 +91,11 @@ __pthread_once (once_control, init_routine)
       while (__builtin_expect (val != oldval, 0));
 
       /* Check if another thread already runs the initializer.	*/
-      if ((oldval & 1) != 0)
+      if ((oldval & __PTHREAD_ONCE_INPROGRESS) != 0)
 	{
 	  /* Check whether the initializer execution was interrupted by a
-	     fork. (We know that for both values, bit 0 is set and bit 1 is
-	     not.)  */
+	     fork. (We know that for both values, __PTHREAD_ONCE_INPROGRESS
+	     is set and __PTHREAD_ONCE_DONE is not.)  */
 	  if (oldval == newval)
 	    {
 	      /* Same generation, some other thread was faster. Wait.  */
@@ -115,7 +118,7 @@ __pthread_once (once_control, init_routine)
          release memory order here because we need to synchronize with other
          threads that want to use the initialized data.  */
       atomic_write_barrier();
-      *once_control = 2;
+      *once_control = __PTHREAD_ONCE_DONE;
 
       /* Wake up all other threads.  */
       lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);

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