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


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.

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.

Thanks,
Florian
#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]