mirror of
https://github.com/fluencelabs/musl
synced 2025-05-06 20:42:14 +00:00
previously, stdio used spinlocks, which would be unacceptable if we ever add support for thread priorities, and which yielded pathologically bad performance if an application attempted to use flockfile on a key file as a major/primary locking mechanism. i had held off on making this change for fear that it would hurt performance in the non-threaded case, but actually support for recursive locking had already inflicted that cost. by having the internal locking functions store a flag indicating whether they need to perform unlocking, rather than using the actual recursive lock counter, i was able to combine the conditionals at unlock time, eliminating any additional cost, and also avoid a nasty corner case where a huge number of calls to ftrylockfile could cause deadlock later at the point of internal locking. this commit also fixes some issues with usage of pthread_self conflicting with __attribute__((const)) which resulted in crashes with some compiler versions/optimizations, mainly in flockfile prior to pthread_create.
57 lines
1004 B
C
57 lines
1004 B
C
#include "stdio_impl.h"
|
|
|
|
static int __fflush_unlocked(FILE *f)
|
|
{
|
|
/* If writing, flush output */
|
|
if (f->wpos > f->wbase) {
|
|
f->write(f, 0, 0);
|
|
if (!f->wpos) return EOF;
|
|
}
|
|
|
|
/* If reading, sync position, per POSIX */
|
|
if (f->rpos < f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);
|
|
|
|
/* Clear read and write modes */
|
|
f->wpos = f->wbase = f->wend = 0;
|
|
f->rpos = f->rend = 0;
|
|
|
|
/* Hook for special behavior on flush */
|
|
if (f->flush) f->flush(f);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* stdout.c will override this if linked */
|
|
static FILE *const dummy = 0;
|
|
weak_alias(dummy, __stdout_used);
|
|
|
|
int fflush(FILE *f)
|
|
{
|
|
int r;
|
|
FILE *next;
|
|
|
|
if (f) {
|
|
FLOCK(f);
|
|
r = __fflush_unlocked(f);
|
|
FUNLOCK(f);
|
|
return r;
|
|
}
|
|
|
|
r = __stdout_used ? fflush(__stdout_used) : 0;
|
|
|
|
OFLLOCK();
|
|
for (f=libc.ofl_head; f; f=next) {
|
|
FLOCK(f);
|
|
//OFLUNLOCK();
|
|
if (f->wpos > f->wbase) r |= __fflush_unlocked(f);
|
|
//OFLLOCK();
|
|
next = f->next;
|
|
FUNLOCK(f);
|
|
}
|
|
OFLUNLOCK();
|
|
|
|
return r;
|
|
}
|
|
|
|
weak_alias(__fflush_unlocked, fflush_unlocked);
|