OSDN Git Service

rework internal uClibc mutexes to support futex locking, and nptl
authorAustin Foxley <austinf@cetoncorp.com>
Sat, 17 Oct 2009 20:37:52 +0000 (13:37 -0700)
committerAustin Foxley <austinf@cetoncorp.com>
Sat, 17 Oct 2009 20:37:52 +0000 (13:37 -0700)
Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
libc/Makefile.in
libc/stdio/_fopen.c
libc/stdio/_scanf.c
libc/stdio/_stdio.c
libc/stdio/_stdio.h
libc/stdio/fflush.c
libc/stdio/vdprintf.c
libc/stdio/vsnprintf.c
libc/sysdeps/linux/common/bits/uClibc_mutex.h
libc/sysdeps/linux/common/bits/uClibc_stdio.h

index 7297e92..c4cf5d7 100644 (file)
@@ -16,7 +16,9 @@ VERSION_SCRIPT := -Wl,--version-script,$(VERSION_SCRIPT)
 endif
 
 LDFLAGS-libc.so := $(LDFLAGS) $(VERSION_SCRIPT) -Wl,-init,$(SYMBOL_PREFIX)__uClibc_init
-
+ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
+CFLAGS += -D__USE_STDIO_FUTEXES__
+endif
 LIBS-libc.so := $(interp) $(ldso) $(top_builddir)lib/$(NONSHARED_LIBNAME)
 
 # we have SHARED_MAJORNAME=libc.so.$(MAJOR_VERSION) defined in Rules.mak
index 96377ee..2db27a8 100644 (file)
@@ -99,7 +99,7 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
 #ifdef __UCLIBC_HAS_THREADS__
                /* We only initialize the mutex in the non-freopen case. */
                /* stream->__user_locking = _stdio_user_locking; */
-               __stdio_init_mutex(&stream->__lock);
+               STDIO_INIT_MUTEX(stream->__lock);
 #endif
        }
 
@@ -197,7 +197,7 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
 #ifdef __UCLIBC_HAS_THREADS__
        /* Even in the freopen case, we reset the user locking flag. */
        stream->__user_locking = _stdio_user_locking;
-       /* __stdio_init_mutex(&stream->__lock); */
+       /* STDIO_INIT_MUTEX(stream->__lock); */
 #endif
 
 #ifdef __STDIO_HAS_OPENLIST
index 9143118..34c1c9a 100644 (file)
@@ -235,7 +235,7 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)
 
 #ifdef __UCLIBC_HAS_THREADS__
        f.__user_locking = 1;           /* Set user locking. */
-       __stdio_init_mutex(&f.__lock);
+       STDIO_INIT_MUTEX(f.__lock);
 #endif
        f.__nextopen = NULL;
 
@@ -283,7 +283,7 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)
 
 #ifdef __UCLIBC_HAS_THREADS__
        f.f.__user_locking = 1;         /* Set user locking. */
-       __stdio_init_mutex(&f.f.__lock);
+       STDIO_INIT_MUTEX(f.f.__lock);
 #endif
        f.f.__nextopen = NULL;
 
@@ -388,8 +388,10 @@ int vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict format,
 {
        FILE f;
 
-       f.__bufstart = f.__bufpos = (unsigned char *) str;
-       f.__bufread = f.__bufend = (unsigned char *) (str + wcslen(str));
+       f.__bufstart =
+       f.__bufpos = (char *) str;
+       f.__bufread =
+       f.__bufend = (char *)(str + wcslen(str));
        __STDIO_STREAM_DISABLE_GETC(&f);
        __STDIO_STREAM_DISABLE_PUTC(&f);
 
@@ -414,7 +416,7 @@ int vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict format,
 
 #ifdef __UCLIBC_HAS_THREADS__
        f.__user_locking = 1;           /* Set user locking. */
-       __stdio_init_mutex(&f.__lock);
+       STDIO_INIT_MUTEX(f.__lock);
 #endif
        f.__nextopen = NULL;
 
index 3c8d667..6c11451 100644 (file)
 #endif
 
 #ifdef __UCLIBC_HAS_THREADS__
+#ifdef __USE_STDIO_FUTEXES__
+#define __STDIO_FILE_INIT_THREADSAFE \
+       2, _LIBC_LOCK_RECURSIVE_INITIALIZER,
+#else
 #define __STDIO_FILE_INIT_THREADSAFE \
        2, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
+#endif
 #else
 #define __STDIO_FILE_INIT_THREADSAFE
 #endif
@@ -152,14 +157,13 @@ FILE *__stdout = _stdio_streams + 1; /* For putchar() macro. */
 FILE *_stdio_openlist = _stdio_streams;
 
 # ifdef __UCLIBC_HAS_THREADS__
-__UCLIBC_MUTEX_INIT(_stdio_openlist_add_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
-#ifdef __STDIO_BUFFERS
-__UCLIBC_MUTEX_INIT(_stdio_openlist_del_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+__UCLIBC_IO_MUTEX_INIT(_stdio_openlist_add_lock);
+#  ifdef __STDIO_BUFFERS
+__UCLIBC_IO_MUTEX_INIT(_stdio_openlist_del_lock);
 volatile int _stdio_openlist_use_count = 0;
 int _stdio_openlist_del_count = 0;
-#endif
+#  endif
 # endif
-
 #endif
 /**********************************************************************/
 #ifdef __UCLIBC_HAS_THREADS__
@@ -167,6 +171,7 @@ int _stdio_openlist_del_count = 0;
 /* 2 if threading not initialized and 0 otherwise; */
 int _stdio_user_locking = 2;
 
+#ifndef __USE_STDIO_FUTEXES__
 void attribute_hidden __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m)
 {
        const __UCLIBC_MUTEX_STATIC(__stdio_mutex_initializer,
@@ -174,6 +179,7 @@ void attribute_hidden __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m)
 
        memcpy(m, &__stdio_mutex_initializer, sizeof(__stdio_mutex_initializer));
 }
+#endif
 
 #endif
 /**********************************************************************/
@@ -189,10 +195,10 @@ void attribute_hidden _stdio_term(void)
         * locked, then I suppose there is a chance that a pointer in the
         * chain might be corrupt due to a partial store.
         */
-       __stdio_init_mutex(&_stdio_openlist_add_lock);
+       STDIO_INIT_MUTEX(_stdio_openlist_add_lock);
 #warning check
 #ifdef __STDIO_BUFFERS
-       __stdio_init_mutex(&_stdio_openlist_del_lock);
+       STDIO_INIT_MUTEX(_stdio_openlist_del_lock);
 #endif
 
        /* Next we need to worry about the streams themselves.  If a stream
@@ -214,7 +220,7 @@ void attribute_hidden _stdio_term(void)
                }
 
                ptr->__user_locking = 1; /* Set locking mode to "by caller". */
-               __stdio_init_mutex(&ptr->__lock); /* Shouldn't be necessary, but... */
+               STDIO_INIT_MUTEX(ptr->__lock); /* Shouldn't be necessary, but... */
        }
 #endif
 
index aaa3ad6..ec98f9e 100644 (file)
 #include <bits/uClibc_mutex.h>
 
 #define __STDIO_THREADLOCK_OPENLIST_ADD                        \
-        __UCLIBC_MUTEX_LOCK(_stdio_openlist_add_lock)
+        __UCLIBC_IO_MUTEX_LOCK(_stdio_openlist_add_lock)
 
 #define __STDIO_THREADUNLOCK_OPENLIST_ADD              \
-        __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_add_lock)
+        __UCLIBC_IO_MUTEX_UNLOCK(_stdio_openlist_add_lock)
 
 #ifdef __STDIO_BUFFERS
 
 #define __STDIO_THREADLOCK_OPENLIST_DEL                        \
-        __UCLIBC_MUTEX_LOCK(_stdio_openlist_del_lock)
+        __UCLIBC_IO_MUTEX_LOCK(_stdio_openlist_del_lock)
 
 #define __STDIO_THREADUNLOCK_OPENLIST_DEL              \
-        __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_del_lock)
+        __UCLIBC_IO_MUTEX_UNLOCK(_stdio_openlist_del_lock)
 
 
 #ifdef __UCLIBC_HAS_THREADS__
index 8b918d6..d9104a4 100644 (file)
  * when all (lbf) writing streams are flushed. */
 
 #define __MY_STDIO_THREADLOCK(__stream)                                        \
-        __UCLIBC_MUTEX_CONDITIONAL_LOCK((__stream)->__lock,            \
+        __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK((__stream)->__lock,         \
        (_stdio_user_locking != 2))
 
 #define __MY_STDIO_THREADUNLOCK(__stream)                              \
-        __UCLIBC_MUTEX_CONDITIONAL_UNLOCK((__stream)->__lock,          \
+        __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK((__stream)->__lock,               \
        (_stdio_user_locking != 2))
 
 #if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
index e3405e4..457018b 100644 (file)
@@ -49,7 +49,7 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)
  * only because of fflush_unlocked. TODO? */
 #if (defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__)) && defined(__UCLIBC_HAS_THREADS__)
        f.__user_locking = 1;           /* Set user locking. */
-       __stdio_init_mutex(&f.__lock);
+       STDIO_INIT_MUTEX(f.__lock);
 #endif
        f.__nextopen = NULL;
 
index 07cff34..31adc52 100644 (file)
@@ -43,7 +43,7 @@ int vsnprintf(char *__restrict buf, size_t size,
 
 #if (defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__)) && defined(__UCLIBC_HAS_THREADS__)
        f.__user_locking = 1;           /* Set user locking. */
-       __stdio_init_mutex(&f.__lock);
+       STDIO_INIT_MUTEX(f.__lock);
 #endif
        f.__nextopen = NULL;
 
@@ -117,7 +117,7 @@ int vsnprintf(char *__restrict buf, size_t size,
 
 #ifdef __UCLIBC_HAS_THREADS__
        f.f.__user_locking = 1;         /* Set user locking. */
-       __stdio_init_mutex(&f.f.__lock);
+       STDIO_INIT_MUTEX(f.f.__lock);
 #endif
        f.f.__nextopen = NULL;
 
index 14aeb9c..c6094c3 100644 (file)
 #define __UCLIBC_MUTEX_UNLOCK(M)                                                                       \
         __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1)
 
-#else
+#ifdef __USE_STDIO_FUTEXES__
+
+#include <bits/stdio-lock.h>
+
+#define __UCLIBC_IO_MUTEX(M)                   _IO_lock_t M
+#define __UCLIBC_IO_MUTEX_LOCK(M)              _IO_lock_lock(M)
+#define __UCLIBC_IO_MUTEX_UNLOCK(M)    _IO_lock_unlock(M)
+#define __UCLIBC_IO_MUTEX_TRYLOCK(M)   _IO_lock_trylock(M)
+#define __UCLIBC_IO_MUTEX_INIT(M)      _IO_lock_t M = _IO_lock_initializer
+#define __UCLIBC_IO_MUTEX_EXTERN(M)            extern _IO_lock_t M
+
+#define __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,C)                \
+       if (C) {                                                                                \
+               _IO_lock_lock(M);                                                       \
+       }
+
+#define __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK(M,C)      \
+       if (C) {                                                                                \
+               _IO_lock_unlock(M);                                                     \
+       }
+
+#define __UCLIBC_IO_MUTEX_AUTO_LOCK(M,A,V)                     \
+               __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,((A=(V))) == 0)
+
+#define __UCLIBC_IO_MUTEX_AUTO_UNLOCK(M,A)                     \
+               __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK(M,((A) == 0))
+
+#define __UCLIBC_IO_MUTEX_LOCK_CANCEL_UNSAFE(M)                _IO_lock_lock(M)
+#define __UCLIBC_IO_MUTEX_UNLOCK_CANCEL_UNSAFE(M)      _IO_lock_unlock(M)
+
+#else /* of __USE_STDIO_FUTEXES__ */
+
+#define __UCLIBC_IO_MUTEX(M)                        __UCLIBC_MUTEX(M)
+#define __UCLIBC_IO_MUTEX_LOCK(M)                   __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1)
+#define __UCLIBC_IO_MUTEX_UNLOCK(M)                 __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1)
+#define __UCLIBC_IO_MUTEX_TRYLOCK(M)                __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M)
+#define __UCLIBC_IO_MUTEX_INIT(M)                   __UCLIBC_MUTEX_INIT(M, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
+#define __UCLIBC_IO_MUTEX_EXTERN(M)                 __UCLIBC_MUTEX_EXTERN(M)
+#define __UCLIBC_IO_MUTEX_AUTO_LOCK(M,A,V)          __UCLIBC_MUTEX_AUTO_LOCK(M,A,V)
+#define __UCLIBC_IO_MUTEX_AUTO_UNLOCK(M,A)          __UCLIBC_MUTEX_AUTO_UNLOCK(M,A)
+#define __UCLIBC_IO_MUTEX_LOCK_CANCEL_UNSAFE(M)     __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M)
+#define __UCLIBC_IO_MUTEX_UNLOCK_CANCEL_UNSAFE(M)   __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M)
+#define __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,C)     __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1)
+#define __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK(M,C)   __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1)
+
+#endif /* of __USE_STDIO_FUTEXES__ */
+
+
+#else /* of __UCLIBC_HAS_THREADS__ */
 
 #define __UCLIBC_MUTEX(M)                              void *__UCLIBC_MUTEX_DUMMY_ ## M
 #define __UCLIBC_MUTEX_INIT(M,I)                       extern void *__UCLIBC_MUTEX_DUMMY_ ## M
 #define __UCLIBC_MUTEX_LOCK(M)                         ((void)0)
 #define __UCLIBC_MUTEX_UNLOCK(M)                       ((void)0)
 
-#endif
+#define __UCLIBC_IO_MUTEX(M)                        __UCLIBC_MUTEX(M)
+#define __UCLIBC_IO_MUTEX_LOCK(M)                   __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1)
+#define __UCLIBC_IO_MUTEX_UNLOCK(M)                 __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1)
+#define __UCLIBC_IO_MUTEX_TRYLOCK(M)                __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M)
+#define __UCLIBC_IO_MUTEX_INIT(M)                   __UCLIBC_MUTEX_INIT(M, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
+#define __UCLIBC_IO_MUTEX_EXTERN(M)                 __UCLIBC_MUTEX_EXTERN(M)
+#define __UCLIBC_IO_MUTEX_AUTO_LOCK(M,A,V)          __UCLIBC_MUTEX_AUTO_LOCK(M,A,V)
+#define __UCLIBC_IO_MUTEX_AUTO_UNLOCK(M,A)          __UCLIBC_MUTEX_AUTO_UNLOCK(M,A)
+#define __UCLIBC_IO_MUTEX_LOCK_CANCEL_UNSAFE(M)     __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M)
+#define __UCLIBC_IO_MUTEX_UNLOCK_CANCEL_UNSAFE(M)   __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M)
+#define __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,C)     __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1)
+#define __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK(M,C)   __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1)
+
+#endif /* of __UCLIBC_HAS_THREADS__ */
+
+#define __UCLIBC_IO_MUTEX_TRYLOCK_CANCEL_UNSAFE(M)     \
+               __UCLIBC_IO_MUTEX_TRYLOCK(M)
 
 #endif /* _UCLIBC_MUTEX_H */
index 3631ef7..a8cf4eb 100644 (file)
         __UCLIBC_MUTEX_AUTO_LOCK_VAR(__infunc_user_locking)
 
 #define __STDIO_AUTO_THREADLOCK(__stream)                                      \
-        __UCLIBC_MUTEX_AUTO_LOCK((__stream)->__lock, __infunc_user_locking,    \
+        __UCLIBC_IO_MUTEX_AUTO_LOCK((__stream)->__lock, __infunc_user_locking, \
        (__stream)->__user_locking)
 
 #define __STDIO_AUTO_THREADUNLOCK(__stream)                                    \
-        __UCLIBC_MUTEX_AUTO_UNLOCK((__stream)->__lock, __infunc_user_locking)
+        __UCLIBC_IO_MUTEX_AUTO_UNLOCK((__stream)->__lock, __infunc_user_locking)
 
 #define __STDIO_ALWAYS_THREADLOCK(__stream)                                    \
-        __UCLIBC_MUTEX_LOCK((__stream)->__lock)
+        __UCLIBC_IO_MUTEX_LOCK((__stream)->__lock)
 
 #define __STDIO_ALWAYS_THREADUNLOCK(__stream)                                  \
-        __UCLIBC_MUTEX_UNLOCK((__stream)->__lock)
+        __UCLIBC_IO_MUTEX_UNLOCK((__stream)->__lock)
 
 #define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream)                      \
-        __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE((__stream)->__lock)
+        __UCLIBC_IO_MUTEX_LOCK_CANCEL_UNSAFE((__stream)->__lock)
 
 #define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream)                   \
-        __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE((__stream)->__lock)
+        __UCLIBC_IO_MUTEX_TRYLOCK_CANCEL_UNSAFE((__stream)->__lock)
 
 #define __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(__stream)                    \
-        __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE((__stream)->__lock)
+        __UCLIBC_IO_MUTEX_UNLOCK_CANCEL_UNSAFE((__stream)->__lock)
 
 #ifdef __UCLIBC_HAS_THREADS__
 #define __STDIO_SET_USER_LOCKING(__stream)     ((__stream)->__user_locking = 1)
 #define __STDIO_SET_USER_LOCKING(__stream)             ((void)0)
 #endif
 
+#ifdef __UCLIBC_HAS_THREADS__
+#ifdef __USE_STDIO_FUTEXES__
+#define STDIO_INIT_MUTEX(M) _IO_lock_init(M)
+#else
+#define STDIO_INIT_MUTEX(M) __stdio_init_mutex(& M)
+#endif
+#endif
+
 /**********************************************************************/
 
 #define __STDIO_IOFBF 0                /* Fully buffered.  */
@@ -275,7 +283,7 @@ struct __STDIO_FILE_STRUCT {
 #endif
 #ifdef __UCLIBC_HAS_THREADS__
        int __user_locking;
-       __UCLIBC_MUTEX(__lock);
+       __UCLIBC_IO_MUTEX(__lock);
 #endif
 /* Everything after this is unimplemented... and may be trashed. */
 #if __STDIO_BUILTIN_BUF_SIZE > 0
@@ -351,9 +359,9 @@ extern void _stdio_term(void) attribute_hidden;
 extern struct __STDIO_FILE_STRUCT *_stdio_openlist;
 
 #ifdef __UCLIBC_HAS_THREADS__
-__UCLIBC_MUTEX_EXTERN(_stdio_openlist_add_lock);
+__UCLIBC_IO_MUTEX_EXTERN(_stdio_openlist_add_lock);
 #ifdef __STDIO_BUFFERS
-__UCLIBC_MUTEX_EXTERN(_stdio_openlist_del_lock);
+__UCLIBC_IO_MUTEX_EXTERN(_stdio_openlist_del_lock);
 extern volatile int _stdio_openlist_use_count; /* _stdio_openlist_del_lock */
 extern int _stdio_openlist_del_count; /* _stdio_openlist_del_lock */
 #endif