Fixes IO lock initialization bug (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 14 May 2015 23:35:44 +0000 (19:35 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 15 May 2015 01:35:44 +0000 (21:35 -0400)
Glibc IO locks were not initialized, but we were using IO locks.  This
showed up as page faults with lock_test or prov when trying to invoke
the argp_usage(), which internally calls _IO_flockfile.

The root issue was that some code was using the locks and some code
wasn't initializing, based on the inconsistent setting of _IO_MTSAFE_IO.

For a bit of Akaros history, check out commit e28dbef7c.  That commit
wasn't the correct fix at the time, but you can see how it's muddling in
the area.  It's likely that setting LIBC_REENTRANT was enough back then,
but now that we're on glibc-2.19, that was insufficient.  If you check
glibc's ChangeLog, there were a few things related to _IO_MTSAFE_IO
changed back in 2012, which was probably between our glibc versions.

Rebuild your toolchain (at least glibc) from scratch.

tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Makeconfig [new file with mode: 0644]
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Makefile
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bits/stdio-lock.h [new file with mode: 0644]
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/configure [deleted file]

diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Makeconfig b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Makeconfig
new file mode 100644 (file)
index 0000000..2b564ea
--- /dev/null
@@ -0,0 +1,2 @@
+# Compile libc code to do internal locking.
+libc-reentrant = yes
index ba7a255..c0c5c05 100644 (file)
@@ -2,10 +2,12 @@ CPPFLAGS += -DHAVE_MMAP=1
 CPPFLAGS += -DHAVE_MUNMAP=1
 CPPFLAGS += -D_LIBC_REENTRANT=1
 
-CFLAGS-fork.c = -D_IO_MTSAFE_IO
-CFLAGS-flockfile.c = -D_IO_MTSAFE_IO
-CFLAGS-ftrylockfile.c = -D_IO_MTSAFE_IO
-CFLAGS-funlockfile.c = -D_IO_MTSAFE_IO
+# from nptl/sysdeps/unix/sysv/linux/Makefile
+CFLAGS-fork.c = $(libio-mtsafe)
+# From nptl/Makefile
+CFLAGS-flockfile.c = $(libio-mtsafe)
+CFLAGS-ftrylockfile.c = $(libio-mtsafe)
+CFLAGS-funlockfile.c = $(libio-mtsafe)
 
 # Any sysdep .c file you want needs to be added here, if it's not somewhere
 # else already.  Many posix-ish .c files already are taken care of.  We also
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bits/stdio-lock.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bits/stdio-lock.h
new file mode 100644 (file)
index 0000000..e2678cc
--- /dev/null
@@ -0,0 +1,110 @@
+/* Thread package specific definitions of stream lock type.  NPTL version.
+   Copyright (C) 2000-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_STDIO_LOCK_H
+#define _BITS_STDIO_LOCK_H 1
+
+#include <bits/libc-lock.h>
+#include <lowlevellock.h>
+
+
+/* The locking here is very inexpensive, even for inlining.  */
+#define _IO_lock_inexpensive   1
+
+typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
+
+#define _IO_lock_initializer { LLL_LOCK_INITIALIZER, 0, NULL }
+
+#define _IO_lock_init(_name) \
+  ((_name) = (_IO_lock_t) _IO_lock_initializer , 0)
+
+#define _IO_lock_fini(_name) \
+  ((void) 0)
+
+#define _IO_lock_lock(_name) \
+  do {                                                                       \
+    void *__self = THREAD_SELF;                                                      \
+    if ((_name).owner != __self)                                             \
+      {                                                                              \
+       lll_lock ((_name).lock, LLL_PRIVATE);                                 \
+        (_name).owner = __self;                                                      \
+      }                                                                              \
+    ++(_name).cnt;                                                           \
+  } while (0)
+
+#define _IO_lock_trylock(_name) \
+  ({                                                                         \
+    int __result = 0;                                                        \
+    void *__self = THREAD_SELF;                                                      \
+    if ((_name).owner != __self)                                             \
+      {                                                                              \
+        if (lll_trylock ((_name).lock) == 0)                                 \
+          {                                                                  \
+            (_name).owner = __self;                                          \
+            (_name).cnt = 1;                                                 \
+          }                                                                  \
+        else                                                                 \
+          __result = EBUSY;                                                  \
+      }                                                                              \
+    else                                                                     \
+      ++(_name).cnt;                                                         \
+    __result;                                                                \
+  })
+
+#define _IO_lock_unlock(_name) \
+  do {                                                                       \
+    if (--(_name).cnt == 0)                                                  \
+      {                                                                              \
+        (_name).owner = NULL;                                                \
+       lll_unlock ((_name).lock, LLL_PRIVATE);                               \
+      }                                                                              \
+  } while (0)
+
+
+
+#define _IO_cleanup_region_start(_fct, _fp) \
+  __libc_cleanup_region_start (((_fp)->_flags & _IO_USER_LOCK) == 0, _fct, _fp)
+#define _IO_cleanup_region_start_noarg(_fct) \
+  __libc_cleanup_region_start (1, _fct, NULL)
+#define _IO_cleanup_region_end(_doit) \
+  __libc_cleanup_region_end (_doit)
+
+#if defined _LIBC && !defined NOT_IN_libc
+
+# ifdef __EXCEPTIONS
+#  define _IO_acquire_lock(_fp) \
+  do {                                                                       \
+    _IO_FILE *_IO_acquire_lock_file                                          \
+       __attribute__((cleanup (_IO_acquire_lock_fct)))                       \
+       = (_fp);                                                              \
+    _IO_flockfile (_IO_acquire_lock_file);
+#  define _IO_acquire_lock_clear_flags2(_fp) \
+  do {                                                                       \
+    _IO_FILE *_IO_acquire_lock_file                                          \
+       __attribute__((cleanup (_IO_acquire_lock_clear_flags2_fct)))          \
+       = (_fp);                                                              \
+    _IO_flockfile (_IO_acquire_lock_file);
+# else
+#  define _IO_acquire_lock(_fp) _IO_acquire_lock_needs_exceptions_enabled
+#  define _IO_acquire_lock_clear_flags2(_fp) _IO_acquire_lock (_fp)
+# endif
+# define _IO_release_lock(_fp) ; } while (0)
+
+#endif
+
+#endif /* bits/stdio-lock.h */
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/configure b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/configure
deleted file mode 100644 (file)
index 8f15bf5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-DEFINES="$DEFINES -D_LIBC_REENTRANT"