[PATCH] (almost) thread-safe libgfortran
Richard Henderson
rth@twiddle.net
Fri Oct 7 20:31:00 GMT 2005
On Thu, Oct 06, 2005 at 07:53:30PM -0400, Jakub Jelinek wrote:
> @@ -145,9 +135,10 @@ st_printf (const char *format, ...)
> const char *q;
> stream *s;
> char itoa_buf[GFC_ITOA_BUF_SIZE];
> + char err_stream[sizeof (unix_stream)];
...
> + s = init_error_stream (err_stream);
Is this variable sufficiently aligned? Why do you want to declare
a char array instead of just
unix_stream err_stream;
s = init_error_stream (&err_stream);
> + if (!locked)
> + __gthread_mutex_unlock (&u->lock);
> +
> + /* If there are any threads waiting in find_unit for this unit,
> + avoid freeing the memory, the last such thread will free it
> + instead. */
> + if (u->waiting == 0)
> + free_mem (u);
> +
> + if (!locked)
> + __gthread_mutex_unlock (&unit_lock);
Unlocking twice on one path?
> + __gthread_mutex_lock (&unit_lock);
> +retry:
> + u = find_file0 (unit_root, &statbuf);
> + if (u != NULL)
> + {
> +#ifdef HAVE_SYNC_FETCH_AND_ADD
> + (void) __sync_fetch_and_add (&u->waiting, 1);
> +#else
> + u->waiting++;
> +#endif
Wouldn't you want to do a try_lock first? It could avoid two
atomic instructions, which would be nice.
> + if (__sync_fetch_and_add (&u->waiting, -1) == 1)
__sync_add_and_fetch (&u->waiting, -1) == 0
And it seems like you really ought to consider encapsulating
these calls in inline functions, so that there's not so much
ifdeffing. Something like
inline int predec_waiting_locked (u)
{
#ifdef HAVE_SYNC_FETCH_AND_ADD
return __sync_add_and_fetch (&u->waiting, -1);
#else
return --u->waiting;
#endif
}
inline void dec_waiting_unlocked (u)
{
#ifdef HAVE_SYNC_FETCH_AND_ADD
__sync_fetch_and_add (&u->waiting, -1);
#else
__gthread_mutex_lock (&unit_lock);
u->waiting--;
__gthread_mutex_unlock (&unit_lock);
#endif
}
etc.
r~
More information about the Fortran
mailing list