mirror of git://git.musl-libc.org/musl
refactor stdio open file list handling, move it out of global libc struct
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.
This commit is contained in:
parent
f22a9edaf8
commit
1b0cdc8700
|
@ -17,8 +17,6 @@ struct __libc {
|
||||||
int secure;
|
int secure;
|
||||||
volatile int threads_minus_1;
|
volatile int threads_minus_1;
|
||||||
size_t *auxv;
|
size_t *auxv;
|
||||||
FILE *ofl_head;
|
|
||||||
volatile int ofl_lock[2];
|
|
||||||
size_t tls_size;
|
size_t tls_size;
|
||||||
size_t page_size;
|
size_t page_size;
|
||||||
struct __locale_struct global_locale;
|
struct __locale_struct global_locale;
|
||||||
|
|
|
@ -76,8 +76,9 @@ int __putc_unlocked(int, FILE *);
|
||||||
FILE *__fdopen(int, const char *);
|
FILE *__fdopen(int, const char *);
|
||||||
int __fmodeflags(const char *);
|
int __fmodeflags(const char *);
|
||||||
|
|
||||||
#define OFLLOCK() LOCK(libc.ofl_lock)
|
FILE *__ofl_add(FILE *f);
|
||||||
#define OFLUNLOCK() UNLOCK(libc.ofl_lock)
|
FILE **__ofl_lock(void);
|
||||||
|
void __ofl_unlock(void);
|
||||||
|
|
||||||
#define feof(f) ((f)->flags & F_EOF)
|
#define feof(f) ((f)->flags & F_EOF)
|
||||||
#define ferror(f) ((f)->flags & F_ERR)
|
#define ferror(f) ((f)->flags & F_ERR)
|
||||||
|
|
|
@ -54,13 +54,7 @@ FILE *__fdopen(int fd, const char *mode)
|
||||||
if (!libc.threaded) f->lock = -1;
|
if (!libc.threaded) f->lock = -1;
|
||||||
|
|
||||||
/* Add new FILE to open file list */
|
/* Add new FILE to open file list */
|
||||||
OFLLOCK();
|
return __ofl_add(f);
|
||||||
f->next = libc.ofl_head;
|
|
||||||
if (libc.ofl_head) libc.ofl_head->prev = f;
|
|
||||||
libc.ofl_head = f;
|
|
||||||
OFLUNLOCK();
|
|
||||||
|
|
||||||
return f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
weak_alias(__fdopen, fdopen);
|
weak_alias(__fdopen, fdopen);
|
||||||
|
|
|
@ -16,8 +16,7 @@ static void close_file(FILE *f)
|
||||||
void __stdio_exit(void)
|
void __stdio_exit(void)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
OFLLOCK();
|
for (f=*__ofl_lock(); f; f=f->next) close_file(f);
|
||||||
for (f=libc.ofl_head; f; f=f->next) close_file(f);
|
|
||||||
close_file(__stdin_used);
|
close_file(__stdin_used);
|
||||||
close_file(__stdout_used);
|
close_file(__stdout_used);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,11 @@ int fclose(FILE *f)
|
||||||
__unlist_locked_file(f);
|
__unlist_locked_file(f);
|
||||||
|
|
||||||
if (!(perm = f->flags & F_PERM)) {
|
if (!(perm = f->flags & F_PERM)) {
|
||||||
OFLLOCK();
|
FILE **head = __ofl_lock();
|
||||||
if (f->prev) f->prev->next = f->next;
|
if (f->prev) f->prev->next = f->next;
|
||||||
if (f->next) f->next->prev = f->prev;
|
if (f->next) f->next->prev = f->prev;
|
||||||
if (libc.ofl_head == f) libc.ofl_head = f->next;
|
if (*head == f) *head = f->next;
|
||||||
OFLUNLOCK();
|
__ofl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
r = fflush(f);
|
r = fflush(f);
|
||||||
|
|
|
@ -35,13 +35,12 @@ int fflush(FILE *f)
|
||||||
|
|
||||||
r = __stdout_used ? fflush(__stdout_used) : 0;
|
r = __stdout_used ? fflush(__stdout_used) : 0;
|
||||||
|
|
||||||
OFLLOCK();
|
for (f=*__ofl_lock(); f; f=f->next) {
|
||||||
for (f=libc.ofl_head; f; f=f->next) {
|
|
||||||
FLOCK(f);
|
FLOCK(f);
|
||||||
if (f->wpos > f->wbase) r |= __fflush_unlocked(f);
|
if (f->wpos > f->wbase) r |= __fflush_unlocked(f);
|
||||||
FUNLOCK(f);
|
FUNLOCK(f);
|
||||||
}
|
}
|
||||||
OFLUNLOCK();
|
__ofl_unlock();
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,11 +110,5 @@ FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode)
|
||||||
|
|
||||||
if (!libc.threaded) f->lock = -1;
|
if (!libc.threaded) f->lock = -1;
|
||||||
|
|
||||||
OFLLOCK();
|
return __ofl_add(f);
|
||||||
f->next = libc.ofl_head;
|
|
||||||
if (libc.ofl_head) libc.ofl_head->prev = f;
|
|
||||||
libc.ofl_head = f;
|
|
||||||
OFLUNLOCK();
|
|
||||||
|
|
||||||
return f;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -79,11 +79,5 @@ FILE *open_memstream(char **bufp, size_t *sizep)
|
||||||
|
|
||||||
if (!libc.threaded) f->lock = -1;
|
if (!libc.threaded) f->lock = -1;
|
||||||
|
|
||||||
OFLLOCK();
|
return __ofl_add(f);
|
||||||
f->next = libc.ofl_head;
|
|
||||||
if (libc.ofl_head) libc.ofl_head->prev = f;
|
|
||||||
libc.ofl_head = f;
|
|
||||||
OFLUNLOCK();
|
|
||||||
|
|
||||||
return f;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,11 +81,5 @@ FILE *open_wmemstream(wchar_t **bufp, size_t *sizep)
|
||||||
|
|
||||||
if (!libc.threaded) f->lock = -1;
|
if (!libc.threaded) f->lock = -1;
|
||||||
|
|
||||||
OFLLOCK();
|
return __ofl_add(f);
|
||||||
f->next = libc.ofl_head;
|
|
||||||
if (libc.ofl_head) libc.ofl_head->prev = f;
|
|
||||||
libc.ofl_head = f;
|
|
||||||
OFLUNLOCK();
|
|
||||||
|
|
||||||
return f;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,8 +191,9 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
|
||||||
if (!libc.can_do_threads) return ENOSYS;
|
if (!libc.can_do_threads) return ENOSYS;
|
||||||
self = __pthread_self();
|
self = __pthread_self();
|
||||||
if (!libc.threaded) {
|
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);
|
init_file_lock(f);
|
||||||
|
__ofl_unlock();
|
||||||
init_file_lock(__stdin_used);
|
init_file_lock(__stdin_used);
|
||||||
init_file_lock(__stdout_used);
|
init_file_lock(__stdout_used);
|
||||||
init_file_lock(__stderr_used);
|
init_file_lock(__stderr_used);
|
||||||
|
|
Loading…
Reference in New Issue