refactor stdio open file list handling, move it out of global libc struct
authorRich Felker <dalias@aerifal.cx>
Tue, 16 Jun 2015 07:11:19 +0000 (07:11 +0000)
committerRich Felker <dalias@aerifal.cx>
Tue, 16 Jun 2015 07:11:19 +0000 (07:11 +0000)
functions which open in-memory FILE stream variants all shared a tail
with __fdopen, adding the FILE structure to stdio's open file list.
replacing this common tail with a function call reduces code size and
duplication of logic. the list is also partially encapsulated now.

function signatures were chosen to facilitate tail call optimization
and reduce the need for additional accessor functions.

with these changes, static linked programs that do not use stdio no
longer have an open file list at all.

12 files changed:
src/internal/libc.h
src/internal/stdio_impl.h
src/stdio/__fdopen.c
src/stdio/__stdio_exit.c
src/stdio/fclose.c
src/stdio/fflush.c
src/stdio/fmemopen.c
src/stdio/ofl.c [new file with mode: 0644]
src/stdio/ofl_add.c [new file with mode: 0644]
src/stdio/open_memstream.c
src/stdio/open_wmemstream.c
src/thread/pthread_create.c

index 6810cd8..98c7535 100644 (file)
@@ -17,8 +17,6 @@ struct __libc {
        int secure;
        volatile int threads_minus_1;
        size_t *auxv;
-       FILE *ofl_head;
-       volatile int ofl_lock[2];
        size_t tls_size;
        size_t page_size;
        struct __locale_struct global_locale;
index 72c5519..0dd7fb5 100644 (file)
@@ -76,8 +76,9 @@ int __putc_unlocked(int, FILE *);
 FILE *__fdopen(int, const char *);
 int __fmodeflags(const char *);
 
-#define OFLLOCK() LOCK(libc.ofl_lock)
-#define OFLUNLOCK() UNLOCK(libc.ofl_lock)
+FILE *__ofl_add(FILE *f);
+FILE **__ofl_lock(void);
+void __ofl_unlock(void);
 
 #define feof(f) ((f)->flags & F_EOF)
 #define ferror(f) ((f)->flags & F_ERR)
index ef8f47d..8d6ce81 100644 (file)
@@ -54,13 +54,7 @@ FILE *__fdopen(int fd, const char *mode)
        if (!libc.threaded) f->lock = -1;
 
        /* Add new FILE to open file list */
-       OFLLOCK();
-       f->next = libc.ofl_head;
-       if (libc.ofl_head) libc.ofl_head->prev = f;
-       libc.ofl_head = f;
-       OFLUNLOCK();
-
-       return f;
+       return __ofl_add(f);
 }
 
 weak_alias(__fdopen, fdopen);
index 716e5f7..191b445 100644 (file)
@@ -16,8 +16,7 @@ static void close_file(FILE *f)
 void __stdio_exit(void)
 {
        FILE *f;
-       OFLLOCK();
-       for (f=libc.ofl_head; f; f=f->next) close_file(f);
+       for (f=*__ofl_lock(); f; f=f->next) close_file(f);
        close_file(__stdin_used);
        close_file(__stdout_used);
 }
index 317b3c9..839d88a 100644 (file)
@@ -14,11 +14,11 @@ int fclose(FILE *f)
        __unlist_locked_file(f);
 
        if (!(perm = f->flags & F_PERM)) {
-               OFLLOCK();
+               FILE **head = __ofl_lock();
                if (f->prev) f->prev->next = f->next;
                if (f->next) f->next->prev = f->prev;
-               if (libc.ofl_head == f) libc.ofl_head = f->next;
-               OFLUNLOCK();
+               if (*head == f) *head = f->next;
+               __ofl_unlock();
        }
 
        r = fflush(f);
index 7bf862a..3f462c8 100644 (file)
@@ -35,13 +35,12 @@ int fflush(FILE *f)
 
        r = __stdout_used ? fflush(__stdout_used) : 0;
 
-       OFLLOCK();
-       for (f=libc.ofl_head; f; f=f->next) {
+       for (f=*__ofl_lock(); f; f=f->next) {
                FLOCK(f);
                if (f->wpos > f->wbase) r |= __fflush_unlocked(f);
                FUNLOCK(f);
        }
-       OFLUNLOCK();
+       __ofl_unlock();
        
        return r;
 }
index d784960..7c193a5 100644 (file)
@@ -110,11 +110,5 @@ FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode)
 
        if (!libc.threaded) f->lock = -1;
 
-       OFLLOCK();
-       f->next = libc.ofl_head;
-       if (libc.ofl_head) libc.ofl_head->prev = f;
-       libc.ofl_head = f;
-       OFLUNLOCK();
-
-       return f;
+       return __ofl_add(f);
 }
diff --git a/src/stdio/ofl.c b/src/stdio/ofl.c
new file mode 100644 (file)
index 0000000..b143999
--- /dev/null
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+#include "libc.h"
+
+static FILE *ofl_head;
+static volatile int ofl_lock[2];
+
+FILE **__ofl_lock()
+{
+       LOCK(ofl_lock);
+       return &ofl_head;
+}
+
+void __ofl_unlock()
+{
+       UNLOCK(ofl_lock);
+}
diff --git a/src/stdio/ofl_add.c b/src/stdio/ofl_add.c
new file mode 100644 (file)
index 0000000..d7de9f1
--- /dev/null
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+
+FILE *__ofl_add(FILE *f)
+{
+       FILE **head = __ofl_lock();
+       f->next = *head;
+       if (*head) (*head)->prev = f;
+       *head = f;
+       __ofl_unlock();
+       return f;
+}
index 9eafdfb..58504c9 100644 (file)
@@ -79,11 +79,5 @@ FILE *open_memstream(char **bufp, size_t *sizep)
 
        if (!libc.threaded) f->lock = -1;
 
-       OFLLOCK();
-       f->next = libc.ofl_head;
-       if (libc.ofl_head) libc.ofl_head->prev = f;
-       libc.ofl_head = f;
-       OFLUNLOCK();
-
-       return f;
+       return __ofl_add(f);
 }
index 3537030..7ab2c64 100644 (file)
@@ -81,11 +81,5 @@ FILE *open_wmemstream(wchar_t **bufp, size_t *sizep)
 
        if (!libc.threaded) f->lock = -1;
 
-       OFLLOCK();
-       f->next = libc.ofl_head;
-       if (libc.ofl_head) libc.ofl_head->prev = f;
-       libc.ofl_head = f;
-       OFLUNLOCK();
-
-       return f;
+       return __ofl_add(f);
 }
index de72818..6e2e481 100644 (file)
@@ -191,8 +191,9 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
        if (!libc.can_do_threads) return ENOSYS;
        self = __pthread_self();
        if (!libc.threaded) {
-               for (FILE *f=libc.ofl_head; f; f=f->next)
+               for (FILE *f=*__ofl_lock(); f; f=f->next)
                        init_file_lock(f);
+               __ofl_unlock();
                init_file_lock(__stdin_used);
                init_file_lock(__stdout_used);
                init_file_lock(__stderr_used);