RFC: getc() and putc() as macros

Tim Robbins tjr at freebsd.org
Sat Mar 13 03:27:17 PST 2004


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
  */


More information about the freebsd-threads mailing list