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 6810cd8b97f40b7a8f7bae0a9086eb5096022395..98c7535aa861dc3e8c83b89d07ba11fac15bfc65 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 72c55192727067a84d72d6f85467a0a28839aa5a..0dd7fb5e41ef0ef839f433e6cf11901303d97460 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 ef8f47dcdaf46f5265655f23d7a59fe35684255a..8d6ce813e45ec8ed880e1680d38fb409b4f63000 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 716e5f7366095455791db3616f6f63168298ba27..191b4454a48d3ff4258c2cd6dd5d29738d79620e 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 317b3c901e7dfd066bfcb3a236b89c2a8b8e02cd..839d88af9bba16c15a15dcb6eaa21d32668673dc 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 7bf862a6ae5f57dbd30a530a3902ddb9cda73dd8..3f462c80e8d12f6efbecd144a144d430736ec6eb 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 d78496091d255a9d54d57ca0f075ce1c84e8487f..7c193a579ba4b5e5d780a63c2cce0e526276f8d3 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 9eafdfbaedce42c1bc86165719638e5e335f822e..58504c9f5ee3410ee8ea9222450339a3cac87dbc 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 35370309d6fd2a8cdd8f91fea0c8820d57caedd7..7ab2c64364e01d310d0c868b40837537af5800fd 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 de72818d778a30ae7be178096ed52e50ac3451e5..6e2e48161753e03f0296e97383b7e081b711fb32 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);