Date: Sat, 13 Mar 2004 22:27:19 +1100 From: Tim Robbins <tjr@freebsd.org> To: threads@freebsd.org Subject: RFC: getc() and putc() as macros Message-ID: <20040313112719.GA18628@cat.robbins.dropbear.id.au>
next in thread | raw e-mail | index | archive | help
The patch below re-adds macro versions of getc(), getchar(), putc(), putchar(), feof(), ferror(), fileno() and clearerr(), using the value of __isthreaded to decide between the fast inline single-threaded code and the more general function equivalent (as suggested by Alfred). Is this approach safe? The justification for wanting to do this is that the the performance benefits for single-threaded applications that make heavy use of these functions is pretty amazing (only 5% slower than RELENG_4). There is going to be a minor performance hit for threaded applications, but the time taken to test __isthreaded is likely to be miniscule compared to the function call and locking overhead. ==== //depot/user/tjr/freebsd-tjr/src/include/stdio.h#3 (text+ko) ==== @@ -416,6 +416,22 @@ #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) #define __sfileno(p) ((p)->_file) +extern int __isthreaded; + +#define feof(p) (!__isthreaded ? __sfeof(p) : feof(p)) +#define ferror(p) (!__isthreaded ? __sferror(p) : ferror(p)) +#define clearerr(p) (!__isthreaded ? __sclearerr(p) : clearerr(p)) + +#if __POSIX_VISIBLE +#define fileno(p) (!__isthreaded ? __sfileno(p) : fileno(p)) +#endif + +#define getc(fp) (!__isthreaded ? __sgetc(fp) : getc(fp)) +#define putc(x, fp) (!__isthreaded ? __sputc(x, fp) : putc(x, fp)) + +#define getchar() getc(stdin) +#define putchar(x) putc(x, stdout) + #if __BSD_VISIBLE /* * See ISO/IEC 9945-1 ANSI/IEEE Std 1003.1 Second Edition 1996-07-12 ==== //depot/user/tjr/freebsd-tjr/src/lib/libc/stdio/feof.c#2 (text+ko) ==== @@ -45,12 +45,8 @@ #include "un-namespace.h" #include "libc_private.h" -/* - * feof has traditionally been a macro in <stdio.h>. That is no - * longer true because it needs to be thread-safe. - * - * #undef feof - */ +#undef feof + int feof(FILE *fp) { ==== //depot/user/tjr/freebsd-tjr/src/lib/libc/stdio/ferror.c#2 (text+ko) ==== @@ -45,12 +45,8 @@ #include "un-namespace.h" #include "libc_private.h" -/* - * ferror has traditionally been a macro in <stdio.h>. That is no - * longer true because it needs to be thread-safe. - * - * #undef ferror - */ +#undef ferror + int ferror(FILE *fp) { ==== //depot/user/tjr/freebsd-tjr/src/lib/libc/stdio/fileno.c#2 (text+ko) ==== @@ -45,12 +45,8 @@ #include "un-namespace.h" #include "libc_private.h" -/* - * fileno has traditionally been a macro in <stdio.h>. That is - * no longer true because it needs to be thread-safe. - * - * #undef fileno - */ +#undef fileno + int fileno(FILE *fp) { ==== //depot/user/tjr/freebsd-tjr/src/lib/libc/stdio/getc.c#2 (text+ko) ==== @@ -46,6 +46,8 @@ #include "libc_private.h" #include "local.h" +#undef getc + int getc(FILE *fp) { ==== //depot/user/tjr/freebsd-tjr/src/lib/libc/stdio/getchar.c#4 (text+ko) ==== @@ -40,9 +40,6 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD: src/lib/libc/stdio/getchar.c,v 1.11 2004/03/10 10:24:15 tjr Exp $"); -/* - * A subroutine version of the macro getchar. - */ #include "namespace.h" #include <stdio.h> #include "un-namespace.h" @@ -51,6 +48,9 @@ #undef getchar +/* + * A subroutine version of the macro getchar. + */ int getchar() { ==== //depot/user/tjr/freebsd-tjr/src/lib/libc/stdio/putc.c#2 (text+ko) ==== @@ -46,14 +46,8 @@ #include "local.h" #include "libc_private.h" -/* - * putc has traditionally been a macro in <stdio.h>. That is no - * longer true because POSIX requires it to be thread-safe. POSIX - * does define putc_unlocked() which is defined as a macro and is - * probably what you want to use instead. - * - * #undef putc - */ +#undef putc + int putc(c, fp) int c; ==== //depot/user/tjr/freebsd-tjr/src/lib/libc/stdio/putchar.c#2 (text+ko) ==== @@ -46,14 +46,8 @@ #include "local.h" #include "libc_private.h" -/* - * putchar has traditionally been a macro in <stdio.h>. That is no - * longer true because POSIX requires it to be thread-safe. POSIX - * does define putchar_unlocked() which is defined as a macro and is - * probably what you want to use instead. - * - * #undef putchar - */ +#undef putchar + /* * A subroutine version of the macro putchar */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040313112719.GA18628>