summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Foxley <austinf@cetoncorp.com>2009-10-17 13:37:52 -0700
committerAustin Foxley <austinf@cetoncorp.com>2009-10-17 13:37:52 -0700
commitcfbc0081078b5a41895a2ad689627bf94eeacb43 (patch)
tree4720fff6ae1a79ffe953ee8689a2bd3f8ce016a0
parentc94314fa618c682646c07ddd914a5abb77346273 (diff)
rework internal uClibc mutexes to support futex locking, and nptl
Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
-rw-r--r--libc/Makefile.in4
-rw-r--r--libc/stdio/_fopen.c4
-rw-r--r--libc/stdio/_scanf.c12
-rw-r--r--libc/stdio/_stdio.c22
-rw-r--r--libc/stdio/_stdio.h8
-rw-r--r--libc/stdio/fflush.c4
-rw-r--r--libc/stdio/vdprintf.c2
-rw-r--r--libc/stdio/vsnprintf.c4
-rw-r--r--libc/sysdeps/linux/common/bits/uClibc_mutex.h68
-rw-r--r--libc/sysdeps/linux/common/bits/uClibc_stdio.h28
10 files changed, 119 insertions, 37 deletions
diff --git a/libc/Makefile.in b/libc/Makefile.in
index 7297e9284..c4cf5d7c7 100644
--- a/libc/Makefile.in
+++ b/libc/Makefile.in
@@ -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
diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c
index 96377ee44..2db27a898 100644
--- a/libc/stdio/_fopen.c
+++ b/libc/stdio/_fopen.c
@@ -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
diff --git a/libc/stdio/_scanf.c b/libc/stdio/_scanf.c
index 914311877..34c1c9abd 100644
--- a/libc/stdio/_scanf.c
+++ b/libc/stdio/_scanf.c
@@ -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;
diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c
index 3c8d667d2..6c11451fc 100644
--- a/libc/stdio/_stdio.c
+++ b/libc/stdio/_stdio.c
@@ -74,8 +74,13 @@
#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
diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h
index aaa3ad656..ec98f9e0e 100644
--- a/libc/stdio/_stdio.h
+++ b/libc/stdio/_stdio.h
@@ -24,18 +24,18 @@
#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__
diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c
index 8b918d6bb..d9104a42f 100644
--- a/libc/stdio/fflush.c
+++ b/libc/stdio/fflush.c
@@ -18,11 +18,11 @@
* 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)
diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c
index e3405e411..457018bcf 100644
--- a/libc/stdio/vdprintf.c
+++ b/libc/stdio/vdprintf.c
@@ -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;
diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c
index 07cff3410..31adc52b6 100644
--- a/libc/stdio/vsnprintf.c
+++ b/libc/stdio/vsnprintf.c
@@ -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;
diff --git a/libc/sysdeps/linux/common/bits/uClibc_mutex.h b/libc/sysdeps/linux/common/bits/uClibc_mutex.h
index 14aeb9c80..c6094c3d2 100644
--- a/libc/sysdeps/linux/common/bits/uClibc_mutex.h
+++ b/libc/sysdeps/linux/common/bits/uClibc_mutex.h
@@ -62,7 +62,55 @@
#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
@@ -83,6 +131,22 @@
#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 */
diff --git a/libc/sysdeps/linux/common/bits/uClibc_stdio.h b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
index 3631ef79f..a8cf4eb56 100644
--- a/libc/sysdeps/linux/common/bits/uClibc_stdio.h
+++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
@@ -134,26 +134,26 @@
__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)
@@ -161,6 +161,14 @@
#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