Add memory barriers to pthread_once.

The implementation was using a double-checked locking approach that
could break on SMP.

In addition to the barriers I also switched to a volatile pointer.  I
don't think this will matter unless gcc can conclude that _normal_lock
can't affect *once_control, but I figured it was better to be safe.
(It seems to have no impact whatsoever on the generated code.)

Bug 3022795.

Change-Id: Ib91da25d57ff5bee4288526e39d457153ef6aacd
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index dd8d758..a195018 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -1886,12 +1886,16 @@
 int  pthread_once( pthread_once_t*  once_control,  void (*init_routine)(void) )
 {
     static pthread_mutex_t   once_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+    volatile pthread_once_t* ocptr = once_control;
 
-    if (*once_control == PTHREAD_ONCE_INIT) {
+    pthread_once_t tmp = *ocptr;
+    ANDROID_MEMBAR_FULL();
+    if (tmp == PTHREAD_ONCE_INIT) {
         pthread_mutex_lock( &once_lock );
-        if (*once_control == PTHREAD_ONCE_INIT) {
+        if (*ocptr == PTHREAD_ONCE_INIT) {
             (*init_routine)();
-            *once_control = ~PTHREAD_ONCE_INIT;
+            ANDROID_MEMBAR_FULL();
+            *ocptr = ~PTHREAD_ONCE_INIT;
         }
         pthread_mutex_unlock( &once_lock );
     }