This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH v2] Single threaded stdio optimization


On 07/07/17 13:38, Florian Weimer wrote:
> This patch breaks the attached test case.  Not all stream objects are
> linked into the global list, so the locking upgrade doesn't happen for
> some of them.
> 

i thought all files need to be flushed on exit
or on fflush(0), if glibc does not do that that's
observably non-conforming.

> The global list management is quite expensive because the list is
> single-linked, so we can't just add all stream objects when not yet
> running multi-threaded.
> 
> I fear that this patch may have to be backed out again, until we can
> address these issues.
> 

i can back it out, or try to create all the
problematic files with the optimization-disabling
flag set (in case that's simple.. will look into
it in a minute).

> Thanks,
> Florian
> 
> 
> memstream-thread.c
> 
> 
> #include <err.h>
> #include <errno.h>
> #include <pthread.h>
> #include <stdio.h>
> 
> enum
>   {
>     thread_count = 2,
>     byte_count = 1000000,
>   };
> 
> struct closure
> {
>   FILE *fp;
>   char b;
> };
> 
> static void *
> thread_func (void *closure)
> {
>   struct closure *args = closure;
> 
>   for (int i = 0; i < byte_count; ++i)
>     fputc (args->b, args->fp);
> 
>   return NULL;
> }
> 
> int
> main (void)
> {
>   char *buffer = NULL;
>   size_t buffer_length = 0;
>   FILE *fp = open_memstream (&buffer, &buffer_length);
>   if (fp == NULL)
>     err (1, "open_memstream");
> 
>   pthread_t threads[thread_count];
>   struct closure args[thread_count];
> 
>   for (int i = 0; i < thread_count; ++i)
>     {
>       args[i].fp = fp;
>       args[i].b = 'A' + i;
>       int ret = pthread_create (threads + i, NULL, thread_func, args + i);
>       if (ret != 0)
>         {
>           errno = ret;
>           err (1, "pthread_create");
>         }
>     }
> 
>   for (int i = 0; i < thread_count; ++i)
>     {
>       int ret = pthread_join (threads[i], NULL);
>       if (ret != 0)
>         {
>           errno = ret;
>           err (1, "pthread_join");
>         }
>     }
> 
>   fclose (fp);
> 
>   if (buffer_length != thread_count * byte_count)
>     errx (1, "unexpected number of written bytes: %zu (should be %d)",
>           buffer_length, thread_count * byte_count);
> 
>   size_t counts[thread_count] = { 0, };
>   for (size_t i = 0; i < buffer_length; ++i)
>     {
>       if (buffer[i] < 'A' || buffer[i] >= 'A' + thread_count)
>         errx (1, "written byte at %zu out of range: %d", i, buffer[i] & 0xFF);
>       ++counts[buffer[i] - 'A'];
>     }
>   for (int i = 0; i < thread_count; ++i)
>     if (counts[i] != byte_count)
>       errx (1, "incorrect write count for thread %d: %zu (should be %d)",
>             i, counts[i], byte_count);
> 
>   return 0;
> }
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]