From 1478c2de052374c6356db5513749a144c13791b1 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Thu, 7 Dec 2006 23:24:02 +0000 Subject: Major cleanup of internal mutex locking. Be more consistant in how we do things, and avoid potential deadlocks caused when a thread holding a uClibc internal lock get canceled and terminates without releasing the lock. This change also provides a single place, bits/uClibc_mutex.h, for thread libraries to modify to change all instances of internal locking. --- libc/sysdeps/linux/common/bits/uClibc_mutex.h | 87 +++++++++++ libc/sysdeps/linux/common/bits/uClibc_stdio.h | 213 ++++++++++---------------- 2 files changed, 168 insertions(+), 132 deletions(-) create mode 100644 libc/sysdeps/linux/common/bits/uClibc_mutex.h (limited to 'libc/sysdeps/linux/common/bits') diff --git a/libc/sysdeps/linux/common/bits/uClibc_mutex.h b/libc/sysdeps/linux/common/bits/uClibc_mutex.h new file mode 100644 index 000000000..5464c2285 --- /dev/null +++ b/libc/sysdeps/linux/common/bits/uClibc_mutex.h @@ -0,0 +1,87 @@ +/* Copyright (C) 2006 Manuel Novoa III + * + * GNU Library General Public License (LGPL) version 2 or later. + * + * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. + */ + +#ifndef _UCLIBC_MUTEX_H +#define _UCLIBC_MUTEX_H + +#include + +#ifdef __UCLIBC_HAS_THREADS__ + +#include + +#define __UCLIBC_MUTEX_TYPE pthread_mutex_t + +#define __UCLIBC_MUTEX(M) pthread_mutex_t M +#define __UCLIBC_MUTEX_INIT(M,I) pthread_mutex_t M = I +#define __UCLIBC_MUTEX_STATIC(M,I) static pthread_mutex_t M = I +#define __UCLIBC_MUTEX_EXTERN(M) extern pthread_mutex_t M + +#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) \ + __pthread_mutex_lock(&(M)) + +#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) \ + __pthread_mutex_unlock(&(M)) + +#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) \ + __pthread_mutex_trylock(&(M)) + +#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) \ + do { \ + struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \ + if (C) { \ + _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \ + __pthread_mutex_unlock, \ + &(M)); \ + __pthread_mutex_lock(&(M)); \ + } \ + ((void)0) + +#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) \ + if (C) { \ + _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1); \ + } \ + } while (0) + +#define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A) int A + +#define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V) \ + __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,((A=(V)) == 0)) + +#define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A) \ + __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,(A == 0)) + +#define __UCLIBC_MUTEX_LOCK(M) \ + __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1) + +#define __UCLIBC_MUTEX_UNLOCK(M) \ + __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1) + +#else + +#define __UCLIBC_MUTEX(M) void *__UCLIBC_MUTEX_DUMMY_ ## M +#define __UCLIBC_MUTEX_INIT(M,I) extern void *__UCLIBC_MUTEX_DUMMY_ ## M +#define __UCLIBC_MUTEX_STATIC(M) extern void *__UCLIBC_MUTEX_DUMMY_ ## M +#define __UCLIBC_MUTEX_EXTERN(M) extern void *__UCLIBC_MUTEX_DUMMY_ ## M + +#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) ((void)0) +#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) ((void)0) +#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) (0) /* Always succeed? */ + +#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) ((void)0) +#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) ((void)0) + +#define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A) ((void)0) +#define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V) ((void)0) +#define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A) ((void)0) + +#define __UCLIBC_MUTEX_LOCK(M) ((void)0) +#define __UCLIBC_MUTEX_UNLOCK(M) ((void)0) + +#endif + +#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 bd584692e..5865ce564 100644 --- a/libc/sysdeps/linux/common/bits/uClibc_stdio.h +++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h @@ -1,21 +1,8 @@ /* Copyright (C) 2002-2004 Manuel Novoa III * - * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. - * - * This 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. + * GNU Library General Public License (LGPL) version 2 or later. * - * You should have received a copy of the GNU Lesser General Public - * License along with the GNU C Library; if not, write to the Free - * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA. + * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. */ #ifndef _STDIO_H @@ -68,7 +55,7 @@ /**********************************************************************/ /* Make sure defines related to large files are consistent. */ -#if defined _LIBC && (defined IS_IN_libc || defined NOT_IN_libc) +#ifdef _LIBC #ifdef __UCLIBC_HAS_LFS__ #undef __USE_LARGEFILE @@ -129,9 +116,7 @@ #endif /**********************************************************************/ -#ifdef __UCLIBC_HAS_THREADS__ -/* Need this for pthread_mutex_t. */ -#include +#include /* user_locking * 0 : do auto locking/unlocking @@ -145,70 +130,37 @@ * This way, we avoid calling the weak lock/unlock functions. */ -#define __STDIO_AUTO_THREADLOCK_VAR int __infunc_user_locking - -#define __STDIO_AUTO_THREADLOCK(__stream) \ - do { \ - struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \ - if ((__infunc_user_locking = (__stream)->__user_locking) == 0) { \ - _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \ - __pthread_mutex_unlock, \ - &(__stream)->__lock); \ - __pthread_mutex_lock(&(__stream)->__lock); \ - } \ - ((void)0) - -#define __STDIO_AUTO_THREADUNLOCK(__stream) \ - if (__infunc_user_locking == 0) { \ - _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1);\ - } \ - } while (0) +#define __STDIO_AUTO_THREADLOCK_VAR \ + __UCLIBC_MUTEX_AUTO_LOCK_VAR(__infunc_user_locking) -#define __STDIO_SET_USER_LOCKING(__stream) ((__stream)->__user_locking = 1) - -#define __STDIO_ALWAYS_THREADLOCK(__stream) \ - do { \ - struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \ - _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \ - __pthread_mutex_unlock, \ - &(__stream)->__lock); \ - __pthread_mutex_lock(&(__stream)->__lock); \ - ((void)0) - -/* #define __STDIO_ALWAYS_THREADTRYLOCK(__stream) \ */ -/* __pthread_mutex_trylock(&(__stream)->__lock) */ +#define __STDIO_AUTO_THREADLOCK(__stream) \ + __UCLIBC_MUTEX_AUTO_LOCK((__stream)->__lock, __infunc_user_locking, \ + (__stream)->__user_locking) -#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \ - _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1); \ - } while (0) +#define __STDIO_AUTO_THREADUNLOCK(__stream) \ + __UCLIBC_MUTEX_AUTO_UNLOCK((__stream)->__lock, __infunc_user_locking) -#define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream) \ - __pthread_mutex_lock(&(__stream)->__lock) +#define __STDIO_ALWAYS_THREADLOCK(__stream) \ + __UCLIBC_MUTEX_LOCK((__stream)->__lock) -#define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream) \ - __pthread_mutex_trylock(&(__stream)->__lock) +#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \ + __UCLIBC_MUTEX_UNLOCK((__stream)->__lock) -#define __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(__stream) \ - __pthread_mutex_unlock(&(__stream)->__lock) +#define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream) \ + __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE((__stream)->__lock) -#else /* __UCLIBC_HAS_THREADS__ */ +#define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream) \ + __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE((__stream)->__lock) -#define __STDIO_AUTO_THREADLOCK_VAR ((void)0) - -#define __STDIO_AUTO_THREADLOCK(__stream) ((void)0) -#define __STDIO_AUTO_THREADUNLOCK(__stream) ((void)0) +#define __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(__stream) \ + __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE((__stream)->__lock) +#ifdef __UCLIBC_HAS_THREADS__ +#define __STDIO_SET_USER_LOCKING(__stream) ((__stream)->__user_locking = 1) +#else #define __STDIO_SET_USER_LOCKING(__stream) ((void)0) +#endif -#define __STDIO_ALWAYS_THREADLOCK(__stream) ((void)0) -/* #define __STDIO_ALWAYS_THREADTRYLOCK(__stream) (0) /\* Always succeed. *\/ */ -#define __STDIO_ALWAYS_THREADUNLOCK(__stream) ((void)0) - -#define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream) ((void)0) -#define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream) (0) /* Ok? */ -#define __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(__stream) ((void)0) - -#endif /* __UCLIBC_HAS_THREADS__ */ /**********************************************************************/ #define __STDIO_IOFBF 0 /* Fully buffered. */ @@ -239,7 +191,7 @@ typedef struct { /**********************************************************************/ #ifdef __UCLIBC_HAS_LFS__ -typedef __off64_t __offmax_t; /* TODO -- rename this? */ +typedef __off64_t __offmax_t; /* TODO -- rename this? */ #else typedef __off_t __offmax_t; /* TODO -- rename this? */ #endif @@ -249,7 +201,7 @@ typedef __off_t __offmax_t; /* TODO -- rename this? */ typedef __ssize_t __io_read_fn(void *__cookie, char *__buf, size_t __bufsize); typedef __ssize_t __io_write_fn(void *__cookie, - __const char *__buf, size_t __bufsize); + __const char *__buf, size_t __bufsize); /* NOTE: GLIBC difference!!! -- fopencookie seek function * For glibc, the type of pos is always (__off64_t *) but in our case * it is type (__off_t *) when the lib is built without large file support. @@ -264,7 +216,7 @@ typedef struct { __io_close_fn *close; } _IO_cookie_io_functions_t; -#ifdef __USE_GNU +#if defined(_LIBC) || defined(_GNU_SOURCE) typedef __io_read_fn cookie_read_function_t; typedef __io_write_fn cookie_write_function_t; @@ -323,7 +275,7 @@ struct __STDIO_FILE_STRUCT { #endif #ifdef __UCLIBC_HAS_THREADS__ int __user_locking; - pthread_mutex_t __lock; + __UCLIBC_MUTEX(__lock); #endif /* Everything after this is unimplemented... and may be trashed. */ #if __STDIO_BUILTIN_BUF_SIZE > 0 @@ -352,25 +304,24 @@ struct __STDIO_FILE_STRUCT { #define __MASK_READING 0x0003U /* (0x0001 | 0x0002) */ #define __FLAG_READING 0x0001U -#define __FLAG_UNGOT 0x0002U -#define __FLAG_EOF 0x0004U +#define __FLAG_UNGOT 0x0002U +#define __FLAG_EOF 0x0004U #define __FLAG_ERROR 0x0008U -#define __FLAG_WRITEONLY 0x0010U -#define __FLAG_READONLY 0x0020U /* (__FLAG_WRITEONLY << 1) */ +#define __FLAG_WRITEONLY 0x0010U +#define __FLAG_READONLY 0x0020U /* (__FLAG_WRITEONLY << 1) */ #define __FLAG_WRITING 0x0040U -#define __FLAG_NARROW 0x0080U - -#define __FLAG_FBF 0x0000U /* must be 0 */ -#define __FLAG_LBF 0x0100U -#define __FLAG_NBF 0x0200U /* (__FLAG_LBF << 1) */ -#define __MASK_BUFMODE 0x0300U /* (__FLAG_LBF|__FLAG_NBF) */ -#define __FLAG_APPEND 0x0400U /* fixed! == O_APPEND for linux */ -#define __FLAG_WIDE 0x0800U -/* available slot 0x1000U */ +#define __FLAG_NARROW 0x0080U + +#define __FLAG_FBF 0x0000U /* must be 0 */ +#define __FLAG_LBF 0x0100U +#define __FLAG_NBF 0x0200U /* (__FLAG_LBF << 1) */ +#define __MASK_BUFMODE 0x0300U /* (__FLAG_LBF|__FLAG_NBF) */ +#define __FLAG_APPEND 0x0400U /* fixed! == O_APPEND for linux */ +#define __FLAG_WIDE 0x0800U +/* available slot 0x1000U */ #define __FLAG_FREEFILE 0x2000U #define __FLAG_FREEBUF 0x4000U -#define __FLAG_LARGEFILE 0x8000U /* fixed! == 0_LARGEFILE for linux */ -#define __FLAG_FAILED_FREOPEN __FLAG_LARGEFILE +#define __FLAG_LARGEFILE 0x8000U /* fixed! == 0_LARGEFILE for linux */ /* Note: In no-buffer mode, it would be possible to pack the necessary * flags into one byte. Since we wouldn't be buffering and there would @@ -389,7 +340,7 @@ struct __STDIO_FILE_STRUCT { /********************************************************************** * PROTOTYPES OF INTERNAL FUNCTIONS **********************************************************************/ -#if defined _LIBC && (defined IS_IN_libc || defined NOT_IN_libc) +#ifdef _LIBC extern void _stdio_init(void) attribute_hidden; extern void _stdio_term(void) attribute_hidden; @@ -399,16 +350,14 @@ extern void _stdio_term(void) attribute_hidden; extern struct __STDIO_FILE_STRUCT *_stdio_openlist; #ifdef __UCLIBC_HAS_THREADS__ -extern pthread_mutex_t _stdio_openlist_add_lock; +__UCLIBC_MUTEX_EXTERN(_stdio_openlist_add_lock); #ifdef __STDIO_BUFFERS -extern pthread_mutex_t _stdio_openlist_del_lock; +__UCLIBC_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 extern int _stdio_user_locking; -/* #ifdef _LIBC */ -extern void __stdio_init_mutex(pthread_mutex_t *m) attribute_hidden; -/* #endif */ +extern void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m) attribute_hidden; #endif #endif @@ -416,17 +365,17 @@ extern void __stdio_init_mutex(pthread_mutex_t *m) attribute_hidden; #endif /**********************************************************************/ -#define __CLEARERR_UNLOCKED(__stream) \ +#define __CLEARERR_UNLOCKED(__stream) \ ((void)((__stream)->__modeflags &= ~(__FLAG_EOF|__FLAG_ERROR))) #define __FEOF_UNLOCKED(__stream) ((__stream)->__modeflags & __FLAG_EOF) #define __FERROR_UNLOCKED(__stream) ((__stream)->__modeflags & __FLAG_ERROR) #ifdef __UCLIBC_HAS_THREADS__ -# define __CLEARERR(__stream) (clearerr)(__stream) +# define __CLEARERR(__stream) (clearerr)(__stream) # define __FERROR(__stream) (ferror)(__stream) # define __FEOF(__stream) (feof)(__stream) #else -# define __CLEARERR(__stream) __CLEARERR_UNLOCKED(__stream) +# define __CLEARERR(__stream) __CLEARERR_UNLOCKED(__stream) # define __FERROR(__stream) __FERROR_UNLOCKED(__stream) # define __FEOF(__stream) __FEOF_UNLOCKED(__stream) #endif @@ -434,17 +383,17 @@ extern void __stdio_init_mutex(pthread_mutex_t *m) attribute_hidden; extern int __fgetc_unlocked(FILE *__stream); extern int __fputc_unlocked(int __c, FILE *__stream); -/* First define the default definitions. They will be overwritten below as necessary. */ +/* First define the default definitions. They overriden below as necessary. */ #define __FGETC_UNLOCKED(__stream) (__fgetc_unlocked)((__stream)) -#define __FGETC(__stream) (fgetc)((__stream)) -#define __GETC_UNLOCKED_MACRO(__stream) (__fgetc_unlocked)((__stream)) +#define __FGETC(__stream) (fgetc)((__stream)) +#define __GETC_UNLOCKED_MACRO(__stream) (__fgetc_unlocked)((__stream)) #define __GETC_UNLOCKED(__stream) (__fgetc_unlocked)((__stream)) -#define __GETC(__stream) (fgetc)((__stream)) +#define __GETC(__stream) (fgetc)((__stream)) -#define __FPUTC_UNLOCKED(__c, __stream) (__fputc_unlocked)((__c),(__stream)) +#define __FPUTC_UNLOCKED(__c, __stream) (__fputc_unlocked)((__c),(__stream)) #define __FPUTC(__c, __stream) (fputc)((__c),(__stream)) -#define __PUTC_UNLOCKED_MACRO(__c, __stream) (__fputc_unlocked)((__c),(__stream)) -#define __PUTC_UNLOCKED(__c, __stream) (__fputc_unlocked)((__c),(__stream)) +#define __PUTC_UNLOCKED_MACRO(__c, __stream) (__fputc_unlocked)((__c),(__stream)) +#define __PUTC_UNLOCKED(__c, __stream) (__fputc_unlocked)((__c),(__stream)) #define __PUTC(__c, __stream) (fputc)((__c),(__stream)) @@ -453,9 +402,9 @@ extern int __fputc_unlocked(int __c, FILE *__stream); extern FILE *__stdin; /* For getchar() macro. */ # undef __GETC_UNLOCKED_MACRO -# define __GETC_UNLOCKED_MACRO(__stream) \ +# define __GETC_UNLOCKED_MACRO(__stream) \ ( ((__stream)->__bufpos < (__stream)->__bufgetc_u) \ - ? (*(__stream)->__bufpos++) \ + ? (*(__stream)->__bufpos++) \ : __fgetc_unlocked(__stream) ) # if 0 @@ -470,10 +419,10 @@ extern FILE *__stdin; /* For getchar() macro. */ # else /* Using gcc extension for safety and additional inlining. */ # undef __FGETC_UNLOCKED -# define __FGETC_UNLOCKED(__stream) \ +# define __FGETC_UNLOCKED(__stream) \ (__extension__ ({ \ - FILE *__S = (__stream); \ - __GETC_UNLOCKED_MACRO(__S); \ + FILE *__S = (__stream); \ + __GETC_UNLOCKED_MACRO(__S); \ }) ) # undef __GETC_UNLOCKED @@ -481,23 +430,23 @@ extern FILE *__stdin; /* For getchar() macro. */ # ifdef __UCLIBC_HAS_THREADS__ # undef __FGETC -# define __FGETC(__stream) \ +# define __FGETC(__stream) \ (__extension__ ({ \ - FILE *__S = (__stream); \ - ((__S->__user_locking ) \ - ? __GETC_UNLOCKED_MACRO(__S) \ + FILE *__S = (__stream); \ + ((__S->__user_locking ) \ + ? __GETC_UNLOCKED_MACRO(__S) \ : (fgetc)(__S)); \ }) ) # undef __GETC -# define __GETC(__stream) __FGETC((__stream)) +# define __GETC(__stream) __FGETC((__stream)) -# else +# else # undef __FGETC # define __FGETC(__stream) __FGETC_UNLOCKED((__stream)) # undef __GETC -# define __GETC(__stream) __FGETC_UNLOCKED((__stream)) +# define __GETC(__stream) __FGETC_UNLOCKED((__stream)) # endif # endif @@ -512,16 +461,16 @@ extern FILE *__stdin; /* For getchar() macro. */ extern FILE *__stdout; /* For putchar() macro. */ # undef __PUTC_UNLOCKED_MACRO -# define __PUTC_UNLOCKED_MACRO(__c, __stream) \ +# define __PUTC_UNLOCKED_MACRO(__c, __stream) \ ( ((__stream)->__bufpos < (__stream)->__bufputc_u) \ - ? (*(__stream)->__bufpos++) = (__c) \ + ? (*(__stream)->__bufpos++) = (__c) \ : __fputc_unlocked((__c),(__stream)) ) # if 0 /* Classic macro approach. putc{_unlocked} can have side effects.*/ # undef __PUTC_UNLOCKED -# define __PUTC_UNLOCKED(__c, __stream) \ - __PUTC_UNLOCKED_MACRO((__c), (__stream)) +# define __PUTC_UNLOCKED(__c, __stream) \ + __PUTC_UNLOCKED_MACRO((__c), (__stream)) # ifndef __UCLIBC_HAS_THREADS__ # undef __PUTC # define __PUTC(__c, __stream) __PUTC_UNLOCKED_MACRO((__c), (__stream)) @@ -531,10 +480,10 @@ extern FILE *__stdout; /* For putchar() macro. */ /* Using gcc extension for safety and additional inlining. */ # undef __FPUTC_UNLOCKED -# define __FPUTC_UNLOCKED(__c, __stream) \ - (__extension__ ({ \ +# define __FPUTC_UNLOCKED(__c, __stream) \ + (__extension__ ({ \ FILE *__S = (__stream); \ - __PUTC_UNLOCKED_MACRO((__c),__S); \ + __PUTC_UNLOCKED_MACRO((__c),__S); \ }) ) # undef __PUTC_UNLOCKED @@ -542,11 +491,11 @@ extern FILE *__stdout; /* For putchar() macro. */ # ifdef __UCLIBC_HAS_THREADS__ # undef __FPUTC -# define __FPUTC(__c, __stream) \ - (__extension__ ({ \ +# define __FPUTC(__c, __stream) \ + (__extension__ ({ \ FILE *__S = (__stream); \ ((__S->__user_locking) \ - ? __PUTC_UNLOCKED_MACRO((__c),__S) \ + ? __PUTC_UNLOCKED_MACRO((__c),__S) \ : (fputc)((__c),__S)); \ }) ) @@ -556,9 +505,9 @@ extern FILE *__stdout; /* For putchar() macro. */ # else # undef __FPUTC -# define __FPUTC(__c, __stream) __FPUTC_UNLOCKED((__c),(__stream)) +# define __FPUTC(__c, __stream) __FPUTC_UNLOCKED((__c),(__stream)) # undef __PUTC -# define __PUTC(__c, __stream) __FPUTC_UNLOCKED((__c),(__stream)) +# define __PUTC(__c, __stream) __FPUTC_UNLOCKED((__c),(__stream)) # endif # endif -- cgit v1.2.3