diff --git a/libc/Android.mk b/libc/Android.mk index 0bb521fdb..056efd245 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -233,7 +233,6 @@ libc_upstream_freebsd_src_files := \ upstream-freebsd/lib/libc/stdio/fwrite.c \ upstream-freebsd/lib/libc/stdio/makebuf.c \ upstream-freebsd/lib/libc/stdio/mktemp.c \ - upstream-freebsd/lib/libc/stdio/putw.c \ upstream-freebsd/lib/libc/stdio/setvbuf.c \ upstream-freebsd/lib/libc/stdio/wsetup.c \ upstream-freebsd/lib/libc/stdlib/abs.c \ @@ -352,6 +351,7 @@ libc_upstream_openbsd_src_files := \ upstream-openbsd/lib/libc/stdio/putc.c \ upstream-openbsd/lib/libc/stdio/putchar.c \ upstream-openbsd/lib/libc/stdio/puts.c \ + upstream-openbsd/lib/libc/stdio/putw.c \ upstream-openbsd/lib/libc/stdio/refill.c \ upstream-openbsd/lib/libc/stdio/remove.c \ upstream-openbsd/lib/libc/stdio/rewind.c \ diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index b790e2bd9..f6b3d6038 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -54,6 +54,8 @@ static pthread_mutex_t gPthreadStackCreationLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t gDebuggerNotificationLock = PTHREAD_MUTEX_INITIALIZER; +extern "C" int __isthreaded; + // This code is used both by each new pthread and the code that initializes the main thread. void __init_tls(pthread_internal_t* thread) { // Zero-initialize all the slots after TLS_SLOT_SELF and TLS_SLOT_THREAD_ID. @@ -169,11 +171,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, void* (*start_routine)(void*), void* arg) { ErrnoRestorer errno_restorer; - // Inform the rest of the C library that at least one thread - // was created. This will enforce certain functions to acquire/release - // locks (e.g. atexit()) to protect shared global structures. - // This works because pthread_create() is not called by the C library - // initialization routine that sets up the main thread's data structures. + // Inform the rest of the C library that at least one thread was created. __isthreaded = 1; pthread_internal_t* thread = reinterpret_cast(calloc(sizeof(*thread), 1)); diff --git a/libc/dns/net/reentrant.h b/libc/dns/net/reentrant.h index 60bff089e..ddfa090c0 100644 --- a/libc/dns/net/reentrant.h +++ b/libc/dns/net/reentrant.h @@ -38,49 +38,49 @@ /* * Requirements: - * + * * 1. The thread safe mechanism should be lightweight so the library can * be used by non-threaded applications without unreasonable overhead. - * + * * 2. There should be no dependency on a thread engine for non-threaded * applications. - * + * * 3. There should be no dependency on any particular thread engine. - * + * * 4. The library should be able to be compiled without support for thread * safety. - * - * + * + * * Rationale: - * + * * One approach for thread safety is to provide discrete versions of the * library: one thread safe, the other not. The disadvantage of this is * that libc is rather large, and two copies of a library which are 99%+ * identical is not an efficent use of resources. - * + * * Another approach is to provide a single thread safe library. However, * it should not add significant run time or code size overhead to non- * threaded applications. - * + * * Since the NetBSD C library is used in other projects, it should be * easy to replace the mutual exclusion primitives with ones provided by * another system. Similarly, it should also be easy to remove all * support for thread safety completely if the target environment does * not support threads. - * - * + * + * * Implementation Details: - * + * * The thread primitives used by the library (mutex_t, mutex_lock, etc.) * are macros which expand to the cooresponding primitives provided by * the thread engine or to nothing. The latter is used so that code is * not unreasonably cluttered with #ifdefs when all thread safe support * is removed. - * + * * The thread macros can be directly mapped to the mutex primitives from * pthreads, however it should be reasonably easy to wrap another mutex * implementation so it presents a similar interface. - * + * * The thread functions operate by dispatching to symbols which are, by * default, weak-aliased to no-op functions in thread-stub/thread-stub.c * (some uses of thread operations are conditional on __isthreaded, but @@ -212,8 +212,6 @@ void __libc_thr_create(thr_t *, const thrattr_t *, void __libc_thr_exit(void *) __attribute__((__noreturn__)); int *__libc_thr_errno(void); int __libc_thr_setcancelstate(int, int *); - -extern int __isthreaded; __END_DECLS #define thr_once(o, f) __libc_thr_once((o), (f)) @@ -223,7 +221,6 @@ __END_DECLS #define thr_create(tp, ta, f, a) __libc_thr_create((tp), (ta), (f), (a)) #define thr_exit(v) __libc_thr_exit((v)) #define thr_errno() __libc_thr_errno() -#define thr_enabled() (__isthreaded) #define thr_setcancelstate(n, o) __libc_thr_setcancelstate((n),(o)) #endif /* __LIBC_THREAD_STUBS */ @@ -263,7 +260,7 @@ __END_DECLS #define thr_self() #define thr_errno() -#define FLOCKFILE(fp) -#define FUNLOCKFILE(fp) +#define FLOCKFILE(fp) +#define FUNLOCKFILE(fp) #endif /* _REENTRANT */ diff --git a/libc/include/stdio.h b/libc/include/stdio.h index c241d9456..6f8f92ef3 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -359,83 +359,6 @@ __END_DECLS #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) #endif /* __BSD_VISIBLE */ -/* - * Functions internal to the implementation. - */ -__BEGIN_DECLS -int __srget(FILE *); -int __swbuf(int, FILE *); -__END_DECLS - -/* - * The __sfoo macros are here so that we can - * define function versions in the C library. - */ -#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) -#if defined(__GNUC__) -static __inline int __sputc(int _c, FILE *_p) { - if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) - return (*_p->_p++ = _c); - else - return (__swbuf(_c, _p)); -} -#else -/* - * This has been tuned to generate reasonable code on the vax using pcc. - */ -#define __sputc(c, p) \ - (--(p)->_w < 0 ? \ - (p)->_w >= (p)->_lbfsize ? \ - (*(p)->_p = (c)), *(p)->_p != '\n' ? \ - (int)*(p)->_p++ : \ - __swbuf('\n', p) : \ - __swbuf((int)(c), p) : \ - (*(p)->_p = (c), (int)*(p)->_p++)) -#endif - -#define __sfeof(p) (((p)->_flags & __SEOF) != 0) -#define __sferror(p) (((p)->_flags & __SERR) != 0) -#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)) - -#if __BSD_VISIBLE -/* - * The macro implementations of putc and putc_unlocked are not - * fully POSIX compliant; they do not set errno on failure - */ -#define putc(x, fp) (!__isthreaded ? __sputc(x, fp) : (putc)(x, fp)) -#endif /* __BSD_VISIBLE */ - -#ifndef lint -#if __POSIX_VISIBLE >= 199506 -#define getc_unlocked(fp) __sgetc(fp) -/* - * The macro implementations of putc and putc_unlocked are not - * fully POSIX compliant; they do not set errno on failure - */ -#if __BSD_VISIBLE -#define putc_unlocked(x, fp) __sputc(x, fp) -#endif /* __BSD_VISIBLE */ -#endif /* __POSIX_VISIBLE >= 199506 */ -#endif /* lint */ - -#define getchar() getc(stdin) -#define putchar(x) putc(x, stdout) -#define getchar_unlocked() getc_unlocked(stdin) -#define putchar_unlocked(c) putc_unlocked(c, stdout) - #ifdef _GNU_SOURCE /* * glibc defines dprintf(int, const char*, ...), which is poorly named diff --git a/libc/private/thread_private.h b/libc/private/thread_private.h index b19ad09b9..f73118131 100644 --- a/libc/private/thread_private.h +++ b/libc/private/thread_private.h @@ -14,11 +14,6 @@ * described functions for operation in a non-threaded environment. */ -/* - * This variable is 0 until a second thread is created. - */ -extern int __isthreaded; - /* * helper macro to make unique names in the thread namespace */ @@ -39,13 +34,7 @@ struct __thread_private_tag_t { void _thread_atexit_lock(void); void _thread_atexit_unlock(void); -#define _ATEXIT_LOCK() do { \ - if (__isthreaded) \ - _thread_atexit_lock(); \ - } while (0) -#define _ATEXIT_UNLOCK() do { \ - if (__isthreaded) \ - _thread_atexit_unlock();\ - } while (0) +#define _ATEXIT_LOCK() _thread_atexit_lock() +#define _ATEXIT_UNLOCK() _thread_atexit_unlock() #endif /* _THREAD_PRIVATE_H_ */ diff --git a/libc/stdio/local.h b/libc/stdio/local.h index a175d6fa0..facaa660f 100644 --- a/libc/stdio/local.h +++ b/libc/stdio/local.h @@ -91,7 +91,25 @@ extern int __sdidinit; (fp)->_lb._base = NULL; \ } -#define FLOCKFILE(fp) do { if (__isthreaded) flockfile(fp); } while (0) -#define FUNLOCKFILE(fp) do { if (__isthreaded) funlockfile(fp); } while (0) +#define FLOCKFILE(fp) flockfile(fp) +#define FUNLOCKFILE(fp) funlockfile(fp) #define FLOATING_POINT + +/* OpenBSD exposes these in , but we only want them exposed to the implementation. */ +__BEGIN_DECLS +int __srget(FILE*); +int __swbuf(int, FILE*); +__END_DECLS +#define __sfeof(p) (((p)->_flags & __SEOF) != 0) +#define __sferror(p) (((p)->_flags & __SERR) != 0) +#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) +#define __sfileno(p) ((p)->_file) +#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) +static __inline int __sputc(int _c, FILE* _p) { + if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) { + return (*_p->_p++ = _c); + } else { + return (__swbuf(_c, _p)); + } +} diff --git a/libc/upstream-freebsd/libc_private.h b/libc/upstream-freebsd/libc_private.h index ecdbb7ef5..c6a6433b1 100644 --- a/libc/upstream-freebsd/libc_private.h +++ b/libc/upstream-freebsd/libc_private.h @@ -17,9 +17,6 @@ #ifndef _BIONIC_FREEBSD_LIBC_PRIVATE_H_included #define _BIONIC_FREEBSD_LIBC_PRIVATE_H_included -#define FLOCKFILE(fp) do { if (__isthreaded) flockfile(fp); } while (0) -#define FUNLOCKFILE(fp) do { if (__isthreaded) funlockfile(fp); } while (0) - #define STDIO_THREAD_LOCK() /* TODO: until we have the FreeBSD findfp.c, this is useless. */ #define STDIO_THREAD_UNLOCK() /* TODO: until we have the FreeBSD findfp.c, this is useless. */ diff --git a/libc/upstream-freebsd/lib/libc/stdio/putw.c b/libc/upstream-openbsd/lib/libc/stdio/putw.c similarity index 85% rename from libc/upstream-freebsd/lib/libc/stdio/putw.c rename to libc/upstream-openbsd/lib/libc/stdio/putw.c index 0360cafc4..47941a476 100644 --- a/libc/upstream-freebsd/lib/libc/stdio/putw.c +++ b/libc/upstream-openbsd/lib/libc/stdio/putw.c @@ -1,3 +1,4 @@ +/* $OpenBSD: putw.c,v 1.10 2009/11/21 09:53:44 guenther Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -30,31 +31,24 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)putw.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD$"); - -#include "namespace.h" #include -#include "un-namespace.h" +#include "local.h" #include "fvwrite.h" -#include "libc_private.h" int putw(int w, FILE *fp) { - int retval; struct __suio uio; struct __siov iov; + int ret; iov.iov_base = &w; iov.iov_len = uio.uio_resid = sizeof(w); uio.uio_iov = &iov; uio.uio_iovcnt = 1; FLOCKFILE(fp); - retval = __sfvwrite(fp, &uio); + _SET_ORIENTATION(fp, -1); + ret = __sfvwrite(fp, &uio); FUNLOCKFILE(fp); - return (retval); + return (ret); }