diff options
Diffstat (limited to 'src/stdio')
| -rw-r--r-- | src/stdio/__fdopen.c | 8 | ||||
| -rw-r--r-- | src/stdio/__lockfile.c | 26 | ||||
| -rw-r--r-- | src/stdio/fclose.c | 2 | ||||
| -rw-r--r-- | src/stdio/fflush.c | 10 | ||||
| -rw-r--r-- | src/stdio/fgetc.c | 5 | ||||
| -rw-r--r-- | src/stdio/fgetwc.c | 1 | ||||
| -rw-r--r-- | src/stdio/flockfile.c | 6 | ||||
| -rw-r--r-- | src/stdio/fputc.c | 5 | ||||
| -rw-r--r-- | src/stdio/ftell.c | 6 | ||||
| -rw-r--r-- | src/stdio/ftrylockfile.c | 3 | ||||
| -rw-r--r-- | src/stdio/funlockfile.c | 2 | ||||
| -rw-r--r-- | src/stdio/stderr.c | 2 | ||||
| -rw-r--r-- | src/stdio/stdin.c | 2 | ||||
| -rw-r--r-- | src/stdio/stdout.c | 5 | 
14 files changed, 44 insertions, 39 deletions
| diff --git a/src/stdio/__fdopen.c b/src/stdio/__fdopen.c index b13318e5..07f966a5 100644 --- a/src/stdio/__fdopen.c +++ b/src/stdio/__fdopen.c @@ -39,11 +39,13 @@ FILE *__fdopen(int fd, const char *mode)  	f->seek = __stdio_seek;  	f->close = __stdio_close; +	if (!libc.threaded) f->lock = -1; +  	/* Add new FILE to open file list */  	OFLLOCK(); -	f->next = ofl_head; -	if (ofl_head) ofl_head->prev = f; -	ofl_head = f; +	f->next = libc.ofl_head; +	if (libc.ofl_head) libc.ofl_head->prev = f; +	libc.ofl_head = f;  	OFLUNLOCK();  	return f; diff --git a/src/stdio/__lockfile.c b/src/stdio/__lockfile.c index 66a4d26d..6ebf6202 100644 --- a/src/stdio/__lockfile.c +++ b/src/stdio/__lockfile.c @@ -1,20 +1,18 @@  #include "stdio_impl.h"  #include "pthread_impl.h" -void __lockfile(FILE *f) +int __lockfile(FILE *f)  { -	int spins=10000; -	int tid; +	int owner, tid = __pthread_self()->tid; +	if (f->lock == tid) +		return 0; +	while ((owner = a_cas(&f->lock, 0, tid))) +		__wait(&f->lock, &f->waiters, owner, 1); +	return f->lockcount = 1; +} -	if (f->lock < 0) return; -	tid = __pthread_self()->tid; -	if (f->lock == tid) { -		while (f->lockcount == INT_MAX); -		f->lockcount++; -		return; -	} -	while (a_cas(&f->lock, 0, tid)) -		if (spins) spins--, a_spin(); -		else __syscall(SYS_sched_yield); -	f->lockcount = 1; +void __unlockfile(FILE *f) +{ +	a_store(&f->lock, 0); +	if (f->waiters) __wake(&f->lock, 1, 1);  } diff --git a/src/stdio/fclose.c b/src/stdio/fclose.c index ee772fbb..373a2c76 100644 --- a/src/stdio/fclose.c +++ b/src/stdio/fclose.c @@ -9,7 +9,7 @@ int fclose(FILE *f)  		OFLLOCK();  		if (f->prev) f->prev->next = f->next;  		if (f->next) f->next->prev = f->prev; -		if (ofl_head == f) ofl_head = f->next; +		if (libc.ofl_head == f) libc.ofl_head = f->next;  		OFLUNLOCK();  	} diff --git a/src/stdio/fflush.c b/src/stdio/fflush.c index cdbd39bc..4c1647b7 100644 --- a/src/stdio/fflush.c +++ b/src/stdio/fflush.c @@ -22,8 +22,8 @@ static int __fflush_unlocked(FILE *f)  }  /* stdout.c will override this if linked */ -static FILE *const __dummy = 0; -weak_alias(__dummy, __stdout_to_flush); +static FILE *const dummy = 0; +weak_alias(dummy, __stdout_used);  int fflush(FILE *f)  { @@ -37,13 +37,13 @@ int fflush(FILE *f)  		return r;  	} -	r = __stdout_to_flush ? fflush(__stdout_to_flush) : 0; +	r = __stdout_used ? fflush(__stdout_used) : 0;  	OFLLOCK(); -	for (f=ofl_head; f; f=next) { +	for (f=libc.ofl_head; f; f=next) {  		FLOCK(f);  		//OFLUNLOCK(); -		r |= __fflush_unlocked(f); +		if (f->wpos > f->wbase) r |= __fflush_unlocked(f);  		//OFLLOCK();  		next = f->next;  		FUNLOCK(f); diff --git a/src/stdio/fgetc.c b/src/stdio/fgetc.c index da638684..4d8aca37 100644 --- a/src/stdio/fgetc.c +++ b/src/stdio/fgetc.c @@ -3,9 +3,10 @@  int fgetc(FILE *f)  {  	int c; -	FLOCK(f); +	if (f->lock < 0 || !__lockfile(f)) +		return getc_unlocked(f);  	c = getc_unlocked(f); -	FUNLOCK(f); +	__unlockfile(f);  	return c;  } diff --git a/src/stdio/fgetwc.c b/src/stdio/fgetwc.c index 5e420594..6f9f9ec2 100644 --- a/src/stdio/fgetwc.c +++ b/src/stdio/fgetwc.c @@ -34,7 +34,6 @@ wint_t __fgetwc_unlocked(FILE *f)  		if (l == -1) return WEOF;  	} -	FUNLOCK(f);  	return wc;  } diff --git a/src/stdio/flockfile.c b/src/stdio/flockfile.c index 0d4c92c2..a196c1ef 100644 --- a/src/stdio/flockfile.c +++ b/src/stdio/flockfile.c @@ -3,6 +3,8 @@  void flockfile(FILE *f)  { -	if (!libc.threaded) pthread_self(); -	__lockfile(f); +	while (ftrylockfile(f)) { +		int owner = f->lock; +		if (owner) __wait(&f->lock, &f->waiters, owner, 1); +	}  } diff --git a/src/stdio/fputc.c b/src/stdio/fputc.c index 98d0a20a..6a144a54 100644 --- a/src/stdio/fputc.c +++ b/src/stdio/fputc.c @@ -2,9 +2,10 @@  int fputc(int c, FILE *f)  { -	FLOCK(f); +	if (f->lock < 0 || !__lockfile(f)) +		return putc_unlocked(c, f);  	c = putc_unlocked(c, f); -	FUNLOCK(f); +	__unlockfile(f);  	return c;  } diff --git a/src/stdio/ftell.c b/src/stdio/ftell.c index aa1f5381..3904a1d8 100644 --- a/src/stdio/ftell.c +++ b/src/stdio/ftell.c @@ -3,10 +3,8 @@  off_t __ftello_unlocked(FILE *f)  {  	off_t pos = f->seek(f, 0, SEEK_CUR); -	if (pos < 0) { -		FUNLOCK(f); -		return pos; -	} +	if (pos < 0) return pos; +  	/* Adjust for data in buffer. */  	return pos - (f->rend - f->rpos) + (f->wpos - f->wbase);  } diff --git a/src/stdio/ftrylockfile.c b/src/stdio/ftrylockfile.c index 0b0e44aa..725c4c3e 100644 --- a/src/stdio/ftrylockfile.c +++ b/src/stdio/ftrylockfile.c @@ -5,11 +5,12 @@ int ftrylockfile(FILE *f)  {  	int tid = pthread_self()->tid;  	if (f->lock == tid) { -		if (f->lockcount == INT_MAX) +		if (f->lockcount == LONG_MAX)  			return -1;  		f->lockcount++;  		return 0;  	} +	if (f->lock < 0) f->lock = 0;  	if (f->lock || a_cas(&f->lock, 0, tid))  		return -1;  	f->lockcount = 1; diff --git a/src/stdio/funlockfile.c b/src/stdio/funlockfile.c index d69f68ee..f8a2a071 100644 --- a/src/stdio/funlockfile.c +++ b/src/stdio/funlockfile.c @@ -3,5 +3,5 @@  void funlockfile(FILE *f)  { -	FUNLOCK(f); +	if (!--f->lockcount) __unlockfile(f);  } diff --git a/src/stdio/stderr.c b/src/stdio/stderr.c index 9a70700c..3fd8f81d 100644 --- a/src/stdio/stderr.c +++ b/src/stdio/stderr.c @@ -10,5 +10,7 @@ static FILE f = {  	.write = __stdio_write,  	.seek = __stdio_seek,  	.close = __stdio_close, +	.lock = -1,  };  FILE *const stderr = &f; +FILE *const __stderr_used = &f; diff --git a/src/stdio/stdin.c b/src/stdio/stdin.c index 51c99232..476dc708 100644 --- a/src/stdio/stdin.c +++ b/src/stdio/stdin.c @@ -9,5 +9,7 @@ static FILE f = {  	.read = __stdio_read,  	.seek = __stdio_seek,  	.close = __stdio_close, +	.lock = -1,  };  FILE *const stdin = &f; +FILE *const __stdin_used = &f; diff --git a/src/stdio/stdout.c b/src/stdio/stdout.c index 552d729e..3855dd0b 100644 --- a/src/stdio/stdout.c +++ b/src/stdio/stdout.c @@ -10,8 +10,7 @@ static FILE f = {  	.write = __stdout_write,  	.seek = __stdio_seek,  	.close = __stdio_close, +	.lock = -1,  };  FILE *const stdout = &f; - -/* overrides symbol in fflush.c, used for flushing NULL */ -FILE *const __stdout_to_flush = &f; +FILE *const __stdout_used = &f; | 
