summaryrefslogtreecommitdiffstats
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/stdio/_fopen.c8
-rw-r--r--libc/stdio/_stdio.c20
-rw-r--r--libc/stdio/_stdio.h13
-rw-r--r--libc/stdio/scanf.c12
-rw-r--r--libc/stdio/vdprintf.c4
-rw-r--r--libc/stdio/vsnprintf.c12
-rw-r--r--libc/stdio/vswprintf.c4
-rw-r--r--libc/stdlib/system.c2
-rw-r--r--libc/sysdeps/linux/common/bits/uClibc_stdio.h38
9 files changed, 112 insertions, 1 deletions
diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c
index f7f5bb626..b1722fef2 100644
--- a/libc/stdio/_fopen.c
+++ b/libc/stdio/_fopen.c
@@ -98,8 +98,12 @@ FILE *_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; */
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (stream->_lock);
+#else
__stdio_init_mutex(&stream->__lock);
#endif
+#endif
}
#ifdef __UCLIBC_MJN3_ONLY__
@@ -190,8 +194,12 @@ FILE *_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;
+#ifdef __UCLIBC_HAS_FUTEXES__
+ /* _IO_lock_init (stream->_lock); */
+#else
/* __stdio_init_mutex(&stream->__lock); */
#endif
+#endif
#ifdef __STDIO_HAS_OPENLIST
__STDIO_THREADLOCK_OPENLIST;
diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c
index 4aae3c418..671f1e14c 100644
--- a/libc/stdio/_stdio.c
+++ b/libc/stdio/_stdio.c
@@ -73,8 +73,13 @@
#endif
#ifdef __UCLIBC_HAS_THREADS__
+#ifdef __UCLIBC_HAS_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
@@ -151,7 +156,12 @@ FILE *__stdout = _stdio_streams + 1; /* For putchar() macro. */
FILE *_stdio_openlist = _stdio_streams;
# ifdef __UCLIBC_HAS_THREADS__
+# ifdef __UCLIBC_HAS_FUTEXES__
+# include <bits/stdio-lock.h>
+_IO_lock_t _stdio_openlist_lock = _IO_lock_initializer;
+# else
pthread_mutex_t _stdio_openlist_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+# endif
int _stdio_openlist_delflag = 0;
# endif
@@ -162,6 +172,7 @@ int _stdio_openlist_delflag = 0;
/* 2 if threading not initialized and 0 otherwise; */
int _stdio_user_locking = 2;
+#ifndef __UCLIBC_HAS_FUTEXES__
void __stdio_init_mutex(pthread_mutex_t *m)
{
static const pthread_mutex_t __stdio_mutex_initializer
@@ -169,6 +180,7 @@ void __stdio_init_mutex(pthread_mutex_t *m)
memcpy(m, &__stdio_mutex_initializer, sizeof(__stdio_mutex_initializer));
}
+#endif
#endif
/**********************************************************************/
@@ -184,7 +196,11 @@ void _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.
*/
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (_stdio_openlist_lock);
+#else
__stdio_init_mutex(&_stdio_openlist_lock);
+#endif
/* Next we need to worry about the streams themselves. If a stream
* is currently locked, then it may be in an invalid state. So we
@@ -205,7 +221,11 @@ void _stdio_term(void)
}
ptr->__user_locking = 1; /* Set locking mode to "by caller". */
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (ptr->_lock);
+#else
__stdio_init_mutex(&ptr->__lock); /* Shouldn't be necessary, but... */
+#endif
}
#endif
diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h
index e3c2c5888..2b956daa3 100644
--- a/libc/stdio/_stdio.h
+++ b/libc/stdio/_stdio.h
@@ -25,6 +25,16 @@
#ifdef __UCLIBC_HAS_THREADS__
#include <pthread.h>
+#ifdef __UCLIBC_HAS_FUTEXES__
+#define __STDIO_THREADLOCK_OPENLIST \
+ _IO_lock_lock(_stdio_openlist_lock)
+
+#define __STDIO_THREADUNLOCK_OPENLIST \
+ _IO_lock_unlock(_stdio_openlist_lock)
+
+#define __STDIO_THREADTRYLOCK_OPENLIST \
+ _IO_lock_trylock(_stdio_openlist_lock)
+#else
#define __STDIO_THREADLOCK_OPENLIST \
__pthread_mutex_lock(&_stdio_openlist_lock)
@@ -33,6 +43,9 @@
#define __STDIO_THREADTRYLOCK_OPENLIST \
__pthread_mutex_trylock(&_stdio_openlist_lock)
+#endif
+
+
#else
diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c
index 0bb6c0f4d..13254a50b 100644
--- a/libc/stdio/scanf.c
+++ b/libc/stdio/scanf.c
@@ -235,8 +235,12 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)
#ifdef __UCLIBC_HAS_THREADS__
f.__user_locking = 1; /* Set user locking. */
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (f._lock);
+#else
__stdio_init_mutex(&f.__lock);
#endif
+#endif
f.__nextopen = NULL;
/* Set these last since __bufgetc initialization depends on
@@ -282,8 +286,12 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)
#ifdef __UCLIBC_HAS_THREADS__
f.f.__user_locking = 1; /* Set user locking. */
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (f.f._lock);
+#else
__stdio_init_mutex(&f.f.__lock);
#endif
+#endif
f.f.__nextopen = NULL;
return vfscanf(&f.f, fmt, ap);
@@ -413,8 +421,12 @@ int vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict format,
#ifdef __UCLIBC_HAS_THREADS__
f.__user_locking = 1; /* Set user locking. */
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (f._lock);
+#else
__stdio_init_mutex(&f.__lock);
#endif
+#endif
f.__nextopen = NULL;
return vfwscanf(&f, format, arg);
diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c
index de8362c20..6449d37ca 100644
--- a/libc/stdio/vdprintf.c
+++ b/libc/stdio/vdprintf.c
@@ -43,8 +43,12 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)
#ifdef __UCLIBC_HAS_THREADS__
f.__user_locking = 1; /* Set user locking. */
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (f._lock);
+#else
__stdio_init_mutex(&f.__lock);
#endif
+#endif
f.__nextopen = NULL;
rv = vfprintf(&f, format, arg);
diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c
index ffe33ada3..2f4f8e0a4 100644
--- a/libc/stdio/vsnprintf.c
+++ b/libc/stdio/vsnprintf.c
@@ -41,8 +41,12 @@ int vsnprintf(char *__restrict buf, size_t size,
#ifdef __UCLIBC_HAS_THREADS__
f.__user_locking = 1; /* Set user locking. */
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (f._lock);
+#else
__stdio_init_mutex(&f.__lock);
#endif
+#endif
f.__nextopen = NULL;
if (size > SIZE_MAX - (size_t) buf) {
@@ -109,8 +113,12 @@ int vsnprintf(char *__restrict buf, size_t size,
#ifdef __UCLIBC_HAS_THREADS__
f.f.__user_locking = 1; /* Set user locking. */
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (f.f._lock);
+#else
__stdio_init_mutex(&f.f.__lock);
#endif
+#endif
f.f.__nextopen = NULL;
rv = vfprintf((FILE *) &f, format, arg);
@@ -193,8 +201,12 @@ int vsnprintf(char *__restrict buf, size_t size,
#ifdef __UCLIBC_HAS_THREADS__
f.__user_locking = 1; /* Set user locking. */
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (f._lock);
+#else
__stdio_init_mutex(&f.__lock);
#endif
+#endif
f.__nextopen = NULL;
rv = vfprintf(&f, format, arg);
diff --git a/libc/stdio/vswprintf.c b/libc/stdio/vswprintf.c
index a5839b7bd..ea99836e2 100644
--- a/libc/stdio/vswprintf.c
+++ b/libc/stdio/vswprintf.c
@@ -38,8 +38,12 @@ int vswprintf(wchar_t *__restrict buf, size_t size,
#ifdef __UCLIBC_HAS_THREADS__
f.__user_locking = 1; /* Set user locking. */
+#ifdef __UCLIBC_HAS_FUTEXES__
+ _IO_lock_init (f._lock);
+#else
__stdio_init_mutex(&f.__lock);
#endif
+#endif
f.__nextopen = NULL;
if (size > ((SIZE_MAX - (size_t) buf)/sizeof(wchar_t))) {
diff --git a/libc/stdlib/system.c b/libc/stdlib/system.c
index b365ef82e..06f11abf2 100644
--- a/libc/stdlib/system.c
+++ b/libc/stdlib/system.c
@@ -10,7 +10,7 @@
#define vfork fork
#endif
-int __libc_system(char *command)
+int __libc_system(__const char *command)
{
int wait_val, pid;
__sighandler_t save_quit, save_int, save_chld;
diff --git a/libc/sysdeps/linux/common/bits/uClibc_stdio.h b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
index 40cd5fe70..e378489a4 100644
--- a/libc/sysdeps/linux/common/bits/uClibc_stdio.h
+++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
@@ -119,6 +119,9 @@
#ifdef __UCLIBC_HAS_THREADS__
/* Need this for pthread_mutex_t. */
#include <bits/pthreadtypes.h>
+#if defined __UCLIBC_HAS_FUTEXES__ && defined _LIBC
+#include <bits/stdio-lock.h>
+#endif
/* user_locking
* 0 : do auto locking/unlocking
@@ -134,6 +137,31 @@
#define __STDIO_AUTO_THREADLOCK_VAR int __infunc_user_locking
+#if defined __UCLIBC_HAS_FUTEXES__ && defined _LIBC
+
+#define __STDIO_SET_USER_LOCKING(__stream) ((__stream)->__user_locking = 1)
+
+#define __STDIO_AUTO_THREADLOCK(__stream) \
+ if ((__infunc_user_locking = (__stream)->__user_locking) == 0) { \
+ _IO_lock_lock((__stream)->_lock); \
+ }
+
+#define __STDIO_AUTO_THREADUNLOCK(__stream) \
+ if (__infunc_user_locking == 0) { \
+ _IO_lock_unlock((__stream)->_lock); \
+ }
+
+#define __STDIO_ALWAYS_THREADLOCK(__stream) \
+ _IO_lock_lock((__stream)->_lock)
+
+#define __STDIO_ALWAYS_THREADTRYLOCK(__stream) \
+ _IO_lock_trylock((__stream)->_lock)
+
+#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \
+ _IO_lock_unlock((__stream)->_lock)
+
+#else
+
#define __STDIO_AUTO_THREADLOCK(__stream) \
if ((__infunc_user_locking = (__stream)->__user_locking) == 0) { \
__pthread_mutex_lock(&(__stream)->__lock); \
@@ -155,6 +183,8 @@
#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \
__pthread_mutex_unlock(&(__stream)->__lock)
+#endif
+
#else /* __UCLIBC_HAS_THREADS__ */
#define __STDIO_AUTO_THREADLOCK_VAR ((void)0)
@@ -283,8 +313,12 @@ struct __STDIO_FILE_STRUCT {
#endif
#ifdef __UCLIBC_HAS_THREADS__
int __user_locking;
+#if defined __UCLIBC_HAS_FUTEXES__ && defined _LIBC
+ _IO_lock_t _lock;
+#else
pthread_mutex_t __lock;
#endif
+#endif
/* Everything after this is unimplemented... and may be trashed. */
#if __STDIO_BUILTIN_BUF_SIZE > 0
unsigned char __builtinbuf[__STDIO_BUILTIN_BUF_SIZE];
@@ -358,7 +392,11 @@ extern void _stdio_term(void);
extern struct __STDIO_FILE_STRUCT *_stdio_openlist;
#ifdef __UCLIBC_HAS_THREADS__
+#if defined __UCLIBC_HAS_FUTEXES__ && defined _LIBC
+extern _IO_lock_t _stdio_openlist_lock;
+#else
extern pthread_mutex_t _stdio_openlist_lock;
+#endif
extern int _stdio_openlist_delflag;
extern int _stdio_user_locking;
extern void __stdio_init_mutex(pthread_mutex_t *m);