Пример #1
0
Файл: 2-1.c Проект: 8l/rose
int main()
{
	int rc;
	pthread_barrierattr_t ba;
	pthread_barrier_t barriers [BARRIER_NUM];
	int cnt;
	
	/* Initialize the barrier attribute object */
	rc = pthread_barrierattr_init(&ba);
	if(rc != 0)
	{
		printf("Test FAILED: Error while initialize attribute object\n");
		return PTS_FAIL;
	}

	/* Initialize BARRIER_NUM barrier objects, with count==1 */
	for(cnt = 0; cnt < BARRIER_NUM; cnt++)
	{
		if(pthread_barrier_init(&barriers[cnt], &ba, 1) != 0)
		{
			printf("Error at %dth initialization\n", cnt);
			return PTS_UNRESOLVED;	
		}
	}

	/* Destroy barrier attribute object */
	rc = pthread_barrierattr_destroy(&ba);
	if(rc != 0)
	{
		printf("Error at pthread_barrierattr_destroy() "
			"return code: %d, %s", rc, strerror(rc));
		return PTS_UNRESOLVED;
	}

	/* Check that pthread_barrier_wait can still be performed, even after the attributes
	 * object has been destroyed */
	for(cnt = 0; cnt < BARRIER_NUM; cnt++)
	{
		rc = pthread_barrier_wait(&barriers[cnt]);
		if(rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD)
		{
			printf("Test Fail: Error at %dth wait, %s\n", cnt, strerror(rc));
			return PTS_FAIL;	
		}
	}

	/* Cleanup */
	for(cnt = 0; cnt < BARRIER_NUM; cnt++)
	{
		rc = pthread_barrier_destroy(&barriers[cnt]);
		if(rc != 0)
		{
			printf("Error at %dth destruction, %s\n", cnt, strerror(rc));
			return PTS_UNRESOLVED;	
		}
	}

	printf("Test PASSED\n");
	return PTS_PASS;
}
Пример #2
0
int pthread_test_barrier3()
{
  pthread_t t;
  pthread_barrierattr_t ba;

  assert(pthread_barrierattr_init(&ba) == 0);
  assert(pthread_barrierattr_setpshared(&ba, PTHREAD_PROCESS_PRIVATE) == 0);
  assert(pthread_barrier_init(&barrier, &ba, 1) == 0);

  assert(pthread_create(&t, NULL, func, NULL) == 0);

  assert(pthread_join(t, (void **) &result) == 0);

  assert(result == PTHREAD_BARRIER_SERIAL_THREAD);

  assert(pthread_barrier_destroy(&barrier) == 0);
  assert(pthread_barrierattr_destroy(&ba) == 0);

  return 0;
}
Пример #3
0
int main()
{
	int rc;
	pthread_barrierattr_t ba;
	int pshared;

	/* Initialize the barrier attribute object */
	rc = pthread_barrierattr_init(&ba);
	if (rc != 0)
	{
		printf("Test FAILED: Error while initialize attribute object\n");
		return PTS_FAIL;
	}

	/* Get the pshared value of the initialized barrierattr object */
	if (pthread_barrierattr_getpshared(&ba, &pshared) != 0)
	{
		printf("Error at pthread_barrierattr_getpshared()\n");
		return PTS_UNRESOLVED;
	}

	/* The default should be PTHREAD_PROCESS_PRIVATE */
	if (pshared != PTHREAD_PROCESS_PRIVATE)
	{
		printf("Test FAILED: The process shared attribute was not set to "
			"default value\n");
		return PTS_FAIL;
	}

	/* Cleanup */
	rc = pthread_barrierattr_destroy(&ba);
	if (rc != 0)
	{
		printf("Error at pthread_barrierattr_destroy() "
			"return code: %d, %s", rc, strerror(rc));
		return PTS_UNRESOLVED;
	}

	printf("Test PASSED\n");
	return PTS_PASS;
}
Пример #4
0
int
do_test (void)
{
  char tmpfname[] = "/tmp/tst-mqueue3-barrier.XXXXXX";
  int fd = mkstemp (tmpfname);
  if (fd == -1)
    {
      printf ("cannot open temporary file: %m\n");
      return 1;
    }

  /* Make sure it is always removed.  */
  unlink (tmpfname);

  /* Create one page of data.  */
  size_t ps = sysconf (_SC_PAGESIZE);
  char data[ps];
  memset (data, '\0', ps);

  /* Write the data to the file.  */
  if (write (fd, data, ps) != (ssize_t) ps)
    {
      puts ("short write");
      return 1;
    }

  void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (mem == MAP_FAILED)
    {
      printf ("mmap failed: %m\n");
      return 1;
    }

  pthread_barrier_t *b;
  b = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t))
                             & ~(__alignof (pthread_barrier_t) - 1));

  pthread_barrierattr_t a;
  if (pthread_barrierattr_init (&a) != 0)
    {
      puts ("barrierattr_init failed");
      return 1;
    }

  if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("barrierattr_setpshared failed, could not test");
      return 0;
    }

  if (pthread_barrier_init (b, &a, 2) != 0)
    {
      puts ("barrier_init failed");
      return 1;
    }

  if (pthread_barrierattr_destroy (&a) != 0)
    {
      puts ("barrierattr_destroy failed");
      return 1;
    }

  /* Name for the message queue.  */
  char mqname[sizeof ("/tst-mqueue3-") + 3 * sizeof (pid_t)];
  snprintf (mqname, sizeof (mqname) - 1, "/tst-mqueue3-%ld",
	    (long int) getpid ());

  /* Create the message queue.  */
  struct mq_attr attr = { .mq_maxmsg = MAXMSG, .mq_msgsize = MSGSIZE };
  m = mq_open (mqname, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
  if (m == -1)
    {
      if (errno == ENOSYS)
	{
	  puts ("not implemented");
	  return 0;
	}

      puts ("mq_open failed");
      return 1;
    }

  /* Unlink the message queue right away.  */
  if (mq_unlink (mqname) != 0)
    {
      puts ("mq_unlink failed");
      return 1;
    }

  pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      return 1;
    }
  if (pid == 0)
    {
      /* Request notification via thread.  */
      struct sigevent ev;
      ev.sigev_notify = SIGEV_THREAD;
      ev.sigev_notify_function = fct;
      ev.sigev_value.sival_ptr = NULL;
      ev.sigev_notify_attributes = NULL;

      /* Tell the kernel.  */
      if (mq_notify (m,&ev) != 0)
	{
	  puts ("mq_notify failed");
	  exit (1);
	}

      /* Tell the parent we are ready.  */
      (void) pthread_barrier_wait (b);

      /* Make sure the process goes away eventually.  */
      alarm (10);

      /* Do nothing forever.  */
      while (1)
	pause ();
    }

  /* Wait for the child process to register to notification method.  */
  (void) pthread_barrier_wait (b);

  /* Send the message.  */
  if (mq_send (m, message, sizeof (message), 1) != 0)
    {
      kill (pid, SIGKILL);
      puts ("mq_send failed");
      return 1;
    }

  int r;
  if (TEMP_FAILURE_RETRY (waitpid (pid, &r, 0)) != pid)
    {
      kill (pid, SIGKILL);
      puts ("waitpid failed");
      return 1;
    }

  return WIFEXITED (r) && WEXITSTATUS (r) == UNIQUE ? 0 : 1;
}
Пример #5
0
static int
do_test (void)
{
  int result = 0;

  char tmpfname[] = "/tmp/tst-mqueue5-barrier.XXXXXX";
  int fd = mkstemp (tmpfname);
  if (fd == -1)
    {
      printf ("cannot open temporary file: %m\n");
      return 1;
    }

  /* Make sure it is always removed.  */
  unlink (tmpfname);

  /* Create one page of data.  */
  size_t ps = sysconf (_SC_PAGESIZE);
  char data[ps];
  memset (data, '\0', ps);

  /* Write the data to the file.  */
  if (write (fd, data, ps) != (ssize_t) ps)
    {
      puts ("short write");
      return 1;
    }

  void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (mem == MAP_FAILED)
    {
      printf ("mmap failed: %m\n");
      return 1;
    }

  pthread_barrier_t *b2;
  b2 = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t))
			      & ~(__alignof (pthread_barrier_t) - 1));

  pthread_barrier_t *b3;
  b3 = b2 + 1;

  pthread_barrierattr_t a;
  if (pthread_barrierattr_init (&a) != 0)
    {
      puts ("barrierattr_init failed");
      return 1;
    }

  if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("barrierattr_setpshared failed, could not test");
      return 0;
    }

  if (pthread_barrier_init (b2, &a, 2) != 0)
    {
      puts ("barrier_init failed");
      return 1;
    }

  if (pthread_barrier_init (b3, &a, 3) != 0)
    {
      puts ("barrier_init failed");
      return 1;
    }

  if (pthread_barrierattr_destroy (&a) != 0)
    {
      puts ("barrierattr_destroy failed");
      return 1;
    }

  char name[sizeof "/tst-mqueue5-" + sizeof (pid_t) * 3];
  snprintf (name, sizeof (name), "/tst-mqueue5-%u", getpid ());

  struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = 1 };
  mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);

  if (q == (mqd_t) -1)
    {
      printf ("mq_open failed with: %m\n");
      return result;
    }
  else
    add_temp_mq (name);

  struct sigevent ev;
  memset (&ev, 0xaa, sizeof (ev));
  ev.sigev_notify = SIGEV_NONE;
  if (mq_notify (q, &ev) != 0)
    {
      printf ("mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  if (mq_notify (q, &ev) == 0)
    {
      puts ("second mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBUSY)
    {
      printf ("second mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  result |= mqsend (q);

  if (mq_notify (q, &ev) != 0)
    {
      printf ("third mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  result |= mqrecv (q);

  if (mq_notify (q, NULL) != 0)
    {
      printf ("mq_notify (q, NULL) failed with: %m\n");
      result = 1;
    }

  if (mq_notify (q, NULL) != 0)
    {
      /* Implementation-defined behaviour, so don't fail,
	 just inform.  */
      printf ("second mq_notify (q, NULL) failed with: %m\n");
    }

  struct sigaction sa = { .sa_sigaction = rtmin_handler,
			  .sa_flags = SA_SIGINFO };
  sigemptyset (&sa.sa_mask);
  sigaction (SIGRTMIN, &sa, NULL);

  memset (&ev, 0x55, sizeof (ev));
  ev.sigev_notify = SIGEV_SIGNAL;
  ev.sigev_signo = SIGRTMIN;
  ev.sigev_value.sival_int = 26;
  if (mq_notify (q, &ev) != 0)
    {
      printf ("mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
      result = 1;
    }

  ev.sigev_value.sival_ptr = &ev;
  if (mq_notify (q, &ev) == 0)
    {
      puts ("second mq_notify (q, { SIGEV_SIGNAL }) unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBUSY)
    {
      printf ("second mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
      result = 1;
    }

  if (rtmin_cnt != 0)
    {
      puts ("SIGRTMIN signal caught too early");
      result = 1;
    }

  result |= mqsend (q);

  if (rtmin_cnt != 1)
    {
      puts ("SIGRTMIN signal did not arrive");
      result = 1;
    }
  else if (rtmin_pid != getpid ()
	   || rtmin_uid != getuid ()
	   || rtmin_code != SI_MESGQ
	   || rtmin_sigval.sival_int != 26)
    {
      printf ("unexpected siginfo_t fields: pid %u (%u), uid %u (%u), code %d (%d), si_int %d (26)\n",
	      rtmin_pid, getpid (), rtmin_uid, getuid (),
	      rtmin_code, SI_MESGQ, rtmin_sigval.sival_int);
      result = 1;
    }

  ev.sigev_value.sival_int = 75;
  if (mq_notify (q, &ev) != 0)
    {
      printf ("third mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
      result = 1;
    }

  result |= mqrecv (q);

  if (mq_notify (q, NULL) != 0)
    {
      printf ("mq_notify (q, NULL) failed with: %m\n");
      result = 1;
    }

  memset (&ev, 0x33, sizeof (ev));
  ev.sigev_notify = SIGEV_NONE;
  if (mq_notify (q, &ev) != 0)
    {
      printf ("fourth mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  pid_t pid = fork ();
  if (pid == -1)
    {
      printf ("fork () failed: %m\n");
      mq_unlink (name);
      return 1;
    }

  if (pid == 0)
    do_child (name, b2, b3, q);

  /* Child unsuccessfully attempts to mq_notify.  */

  (void) pthread_barrier_wait (b2);

  result |= mqsend (q);

  (void) pthread_barrier_wait (b2);

  /* Child successfully calls mq_notify SIGEV_SIGNAL now.  */

  result |= mqrecv (q);

  (void) pthread_barrier_wait (b2);

  memset (&ev, 0xbb, sizeof (ev));
  ev.sigev_notify = SIGEV_SIGNAL;
  ev.sigev_signo = SIGRTMIN;
  ev.sigev_value.sival_int = 15;
  if (mq_notify (q, &ev) == 0)
    {
      puts ("fourth mq_notify (q, { SIGEV_SIGNAL }) unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBUSY)
    {
      printf ("fourth mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
      result = 1;
    }

  result |= mqsend (q);

  if (mq_notify (q, &ev) != 0)
    {
      printf ("fifth mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
      result = 1;
    }

  if (rtmin_cnt != 1)
    {
      puts ("SIGRTMIN signal caught too early");
      result = 1;
    }

  result |= mqrecv (q);

  (void) pthread_barrier_wait (b2);

  /* Child verifies caught SIGRTMIN signal.  */
  /* Child calls mq_send (q) which triggers SIGRTMIN signal here.  */

  (void) pthread_barrier_wait (b2);

  /* Child mq_open's another mqd_t for the same queue (q2).  */

  if (rtmin_cnt != 2)
    {
      puts ("SIGRTMIN signal did not arrive");
      result = 1;
    }
  else if (rtmin_pid != pid
	   || rtmin_uid != getuid ()
	   || rtmin_code != SI_MESGQ
	   || rtmin_sigval.sival_int != 15)
    {
      printf ("unexpected siginfo_t fields: pid %u (%u), uid %u (%u), code %d (%d), si_int %d (15)\n",
	      rtmin_pid, pid, rtmin_uid, getuid (),
	      rtmin_code, SI_MESGQ, rtmin_sigval.sival_int);
      result = 1;
    }

  result |= mqrecv (q);

  (void) pthread_barrier_wait (b2);

  /* Child successfully calls mq_notify { SIGEV_SIGNAL } on q2.  */

  (void) pthread_barrier_wait (b2);

  memset (&ev, 0xbb, sizeof (ev));
  ev.sigev_notify = SIGEV_NONE;
  if (mq_notify (q, &ev) == 0)
    {
      puts ("fifth mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBUSY)
    {
      printf ("fifth mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  (void) pthread_barrier_wait (b2);

  /* Child calls mq_close on q2, which makes the queue available again for
     notification.  */

  mqd_t q3 = mq_open (name, O_RDWR);
  if (q3 == (mqd_t) -1)
    {
      printf ("mq_open q3 in parent failed with: %m\n");
      result = 1;
    }

  (void) pthread_barrier_wait (b2);

  memset (&ev, 0x12, sizeof (ev));
  ev.sigev_notify = SIGEV_NONE;
  if (mq_notify (q3, &ev) != 0)
    {
      printf ("mq_notify (q3, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  (void) pthread_barrier_wait (b2);

  /* Child unsuccessfully attempts to mq_notify { SIGEV_SIGNAL } on q.  */

  (void) pthread_barrier_wait (b2);

  if (mq_close (q3) != 0)
    {
      printf ("mq_close failed: %m\n");
      result = 1;
    }

  (void) pthread_barrier_wait (b2);

  /* Child successfully calls mq_notify { SIGEV_NONE } on q.  */
  /* Child successfully calls mq_notify NULL on q.  */

  (void) pthread_barrier_wait (b2);

  /* Child creates new thread.  */
  /* Thread blocks on mqrecv (q).  */
  /* Child sleeps for 1sec so that thread has time to reach that point.  */
  /* Child successfully calls mq_notify { SIGEV_SIGNAL } on q.  */

  (void) pthread_barrier_wait (b2);

  result |= mqsend (q);

  (void) pthread_barrier_wait (b3);

  /* Child verifies SIGRTMIN has not been sent.  */

  (void) pthread_barrier_wait (b3);

  result |= mqsend (q);

  (void) pthread_barrier_wait (b3);

  /* Thread verifies SIGRTMIN has been caught.  */
  /* Thread calls mq_notify (q, { SIGEV_NONE }) to verify notification is now
     available for registration.  */
  /* Thread calls mq_notify (q, NULL).  */

  (void) pthread_barrier_wait (b3);

  /* Child calls mq_notify (q, { SIGEV_SIGNAL }).  */

  (void) pthread_barrier_wait (b3);

  /* Thread calls mq_notify (q, NULL). */

  (void) pthread_barrier_wait (b3);

  result |= mqsend (q);
  result |= mqrecv (q);

  (void) pthread_barrier_wait (b3);

  /* Child verifies SIGRTMIN has not been sent.  */
  /* Child calls mq_notify (q, { SIGEV_SIGNAL }).  */

  (void) pthread_barrier_wait (b3);

  /* Thread opens a new O_RDONLY mqd_t (q4).  */
  /* Thread calls mq_notify (q4, NULL). */
  /* Thread calls mq_close (q4).  */

  (void) pthread_barrier_wait (b3);

  result |= mqsend (q);
  result |= mqrecv (q);

  (void) pthread_barrier_wait (b3);

  /* Child verifies SIGRTMIN has not been sent.  */
  /* Child calls mq_notify (q, { SIGEV_SIGNAL }).  */

  (void) pthread_barrier_wait (b3);

  /* Thread opens a new O_WRONLY mqd_t (q5).  */
  /* Thread calls mq_notify (q5, NULL). */
  /* Thread calls mq_close (q5).  */

  (void) pthread_barrier_wait (b3);

  result |= mqsend (q);
  result |= mqrecv (q);

  (void) pthread_barrier_wait (b3);

  /* Child verifies SIGRTMIN has not been sent.  */

  int status;
  if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
    {
      puts ("waitpid failed");
      kill (pid, SIGKILL);
      result = 1;
    }
  else if (!WIFEXITED (status) || WEXITSTATUS (status))
    {
      printf ("child failed with status %d\n", status);
      result = 1;
    }

  if (mq_unlink (name) != 0)
    {
      printf ("mq_unlink failed: %m\n");
      result = 1;
    }

  if (mq_close (q) != 0)
    {
      printf ("mq_close failed: %m\n");
      result = 1;
    }

  if (mq_notify (q, NULL) == 0)
    {
      puts ("mq_notify on closed mqd_t unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBADF)
    {
      printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n");
      result = 1;
    }

  memset (&ev, 0x55, sizeof (ev));
  ev.sigev_notify = SIGEV_NONE;
  if (mq_notify (q, &ev) == 0)
    {
      puts ("mq_notify on closed mqd_t unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBADF)
    {
      printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n");
      result = 1;
    }

  return result;
}
Пример #6
0
  //!Destructor
 ~barrierattr_wrapper()  {  pthread_barrierattr_destroy(&m_attr);  }
Пример #7
0
static void *
tf (void *arg)
{
  if (pthread_mutex_lock (&lock))
    {
      puts ("1st locking of lock failed");
	  exit (1);
    }

  struct flock fl =
    {
      .l_type = F_WRLCK,
      .l_start = 0,
      .l_whence = SEEK_SET,
      .l_len = 10
    };
  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("fourth fcntl failed");
      exit (1);
    }

  pthread_mutex_unlock (&lock);

  pthread_mutex_lock (&lock2);

  return NULL;
}


static int
do_test (void)
{
  fd = create_temp_file("tst-flock2-", NULL);
  if (fd == -1)
    {
      puts ("create_temp_file failed");
      return 1;
    }

  int i;
  for (i = 0; i < 20; ++i)
    write (fd, "foobar xyzzy", 12);

  pthread_barrier_t *b;
#ifdef __EMX__
  APIRET arc;
  arc = DosAllocSharedMem ((PPVOID) &b, NULL, sizeof (pthread_barrier_t),
                           PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_GETTABLE);
  if (arc)
    {
      puts ("DosAllocSharedMem failed");
      return 1;
    }
  b->hmtx = NULLHANDLE;
  arc = DosCreateMutexSem (NULL, &b->hmtx, DC_SEM_SHARED, FALSE);
  if (arc)
    {
      puts ("DosCreateMutexSem failed");
      return 1;
    }
  b->hev = NULLHANDLE;
  arc = DosCreateEventSem (NULL, &b->hev, DC_SEM_SHARED | DCE_AUTORESET, FALSE);
  if (arc)
    {
      puts ("DosCreateEventSem failed");
      return 1;
    }
  b->cnt = 0;
  b->cnt_max = 2;
#else
  b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE,
	    MAP_SHARED, fd, 0);
  if (b == MAP_FAILED)
    {
      puts ("mmap failed");
      return 1;
    }

  pthread_barrierattr_t ba;
  if (pthread_barrierattr_init (&ba) != 0)
    {
      puts ("barrierattr_init failed");
      return 1;
    }

  if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("barrierattr_setpshared failed");
      return 1;
    }

  if (pthread_barrier_init (b, &ba, 2) != 0)
    {
      puts ("barrier_init failed");
      return 1;
    }

  if (pthread_barrierattr_destroy (&ba) != 0)
    {
      puts ("barrierattr_destroy failed");
      return 1;
    }
#endif

  struct flock fl =
    {
      .l_type = F_WRLCK,
      .l_start = 0,
      .l_whence = SEEK_SET,
      .l_len = 10
    };
  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("first fcntl failed");
      return 1;
    }

  pid_t pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      return 1;
    }

  if (pid == 0)
    {
#ifdef __EMX__
      arc = DosGetSharedMem (b, PAG_READ | PAG_WRITE);
      if (arc)
        {
          puts ("DosGetSharedMem failed");
          return 1;
        }
      arc = DosOpenMutexSem (NULL, &b->hmtx);
      if (arc)
        {
          puts ("DosOpenMutexSem failed");
          return 1;
        }
      arc = DosOpenEventSem (NULL, &b->hev);
      if (arc)
        {
          puts ("DosOpenEventSem failed");
          return 1;
        }
#endif
      /* Make sure the child does not stay around indefinitely.  */
      alarm (10);

      /* Try to get the lock.  */
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("child:  second flock succeeded");
	  return 1;
	}
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_UNLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
	{
	  puts ("third fcntl failed");
	  return 1;
	}
    }

  pthread_barrier_wait (b);

  pthread_t th;
  if (pid == 0)
    {
      if (pthread_mutex_lock (&lock2) != 0)
	{
	  puts ("1st locking of lock2 failed");
	  return 1;
	}

      if (pthread_create (&th, NULL, tf, NULL) != 0)
	{
	  puts ("pthread_create failed");
	  return 1;
	}

      /* Let the new thread run.  */
      sleep (1);

      if (pthread_mutex_lock (&lock) != 0)
	{
	  puts ("2nd locking of lock failed");
	  return 1;
	}

      puts ("child locked file");
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_WRLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("fifth fcntl succeeded");
	  return 1;
	}

      puts ("file locked by child");
    }

  pthread_barrier_wait (b);

  if (pid == 0)
    {
      if (pthread_mutex_unlock (&lock2) != 0)
	{
	  puts ("unlock of lock2 failed");
	  return 1;
	}

      if (pthread_join (th, NULL) != 0)
	{
	  puts ("join failed");
	  return 1;
	}

      puts ("child's thread terminated");
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_WRLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("fifth fcntl succeeded");
	  return 1;
	}

      puts ("file still locked");
    }

  pthread_barrier_wait (b);

  if (pid == 0)
    {
      _exit (0);
    }

  int status;
  if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
    {
      puts ("waitpid failed");
      return 1;
    }
  puts ("child terminated");

  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("sixth fcntl failed");
      return 1;
    }

  return status;
}
Пример #8
0
void barrier_test(void)
{
  pthread_t barrier_thread[CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS];
  pthread_addr_t result;
  pthread_attr_t attr;
  pthread_barrierattr_t barrierattr;
  int status;
  int i;

  printf("barrier_test: Initializing barrier\n");

  status = pthread_barrierattr_init(&barrierattr);
  if (status != OK)
    {
      printf("barrier_test: pthread_barrierattr_init failed, status=%d\n",
             status);
    }

  status = pthread_barrier_init(&barrier, &barrierattr,
                                CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS);
  if (status != OK)
    {
      printf("barrier_test: pthread_barrierattr_init failed, status=%d\n",
             status);
    }

  /* Create the barrier */

  (void)pthread_barrierattr_init(&barrierattr);

  /* Start CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS thread instances */

  status = pthread_attr_init(&attr);
  if (status != OK)
    {
      printf("barrier_test: pthread_attr_init failed, status=%d\n",
              status);
    }

  for (i = 0; i < CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS; i++)
    {
      status = pthread_create(&barrier_thread[i], &attr, barrier_func,
                              (pthread_addr_t)((uintptr_t)i));
      if (status != 0)
        {
          printf("barrier_test: Error in thread %d create, status=%d\n",
                 i, status);
          printf("barrier_test: Test aborted with waiting threads\n");
          goto abort_test;
        }
      else
        {
          printf("barrier_test: Thread %d created\n", i);
        }
    }
  FFLUSH();

  /* Wait for all thread instances to complete */

  for (i = 0; i < CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS; i++)
    {
      status = pthread_join(barrier_thread[i], &result);
      if (status != 0)
        {
          printf("barrier_test: Error in thread %d join, status=%d\n",
                 i, status);
        }
      else
        {
          printf("barrier_test: Thread %d completed with result=%p\n",
                 i, result);
        }
    }

  /* Destroy the barrier */

abort_test:
  status = pthread_barrier_destroy(&barrier);
  if (status != OK)
    {
      printf("barrier_test: pthread_barrier_destroy failed, status=%d\n",
             status);
    }

  status = pthread_barrierattr_destroy(&barrierattr);
  if (status != OK)
    {
      printf("barrier_test: pthread_barrierattr_destroy failed, status=%d\n",
             status);
    }
  FFLUSH();
}
Пример #9
0
static int
do_test (void)
{
    size_t ps = sysconf (_SC_PAGESIZE);
    char tmpfname[] = "/tmp/tst-barrier2.XXXXXX";
    char data[ps];
    void *mem;
    int fd;
    pthread_barrier_t *b;
    pthread_barrierattr_t a;
    pid_t pid;
    int serials = 0;
    int cnt;
    int status;
    int p;

    fd = mkstemp (tmpfname);
    if (fd == -1)
    {
        printf ("cannot open temporary file: %m\n");
        return 1;
    }

    /* Make sure it is always removed.  */
    unlink (tmpfname);

    /* Create one page of data.  */
    memset (data, '\0', ps);

    /* Write the data to the file.  */
    if (write (fd, data, ps) != (ssize_t) ps)
    {
        puts ("short write");
        return 1;
    }

    mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (mem == MAP_FAILED)
    {
        printf ("mmap failed: %m\n");
        return 1;
    }

    b = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t))
                               & ~(__alignof (pthread_barrier_t) - 1));

    if (pthread_barrierattr_init (&a) != 0)
    {
        puts ("barrierattr_init failed");
        return 1;
    }

    if (pthread_barrierattr_getpshared (&a, &p) != 0)
    {
        puts ("1st barrierattr_getpshared failed");
        return 1;
    }

    if (p != PTHREAD_PROCESS_PRIVATE)
    {
        puts ("default pshared value wrong");
        return 1;
    }

    if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
    {
        puts ("barrierattr_setpshared failed");
        return 1;
    }

    if (pthread_barrierattr_getpshared (&a, &p) != 0)
    {
        puts ("2nd barrierattr_getpshared failed");
        return 1;
    }

    if (p != PTHREAD_PROCESS_SHARED)
    {
        puts ("pshared value after setpshared call wrong");
        return 1;
    }

    if (pthread_barrier_init (b, &a, 2) != 0)
    {
        puts ("barrier_init failed");
        return 1;
    }

    if (pthread_barrierattr_destroy (&a) != 0)
    {
        puts ("barrierattr_destroy failed");
        return 1;
    }

    puts ("going to fork now");
    pid = fork ();
    if (pid == -1)
    {
        puts ("fork failed");
        return 1;
    }

    /* Just to be sure we don't hang forever.  */
    alarm (4);

#define N 30
    for (cnt = 0; cnt < N; ++cnt)
    {
        int e;

        e = pthread_barrier_wait (b);
        if (e == PTHREAD_BARRIER_SERIAL_THREAD)
            ++serials;
        else if (e != 0)
        {
            printf ("%s: barrier_wait returned value %d != 0 and PTHREAD_BARRIER_SERIAL_THREAD\n",
                    pid == 0 ? "child" : "parent", e);
            return 1;
        }
    }

    alarm (0);

    printf ("%s: was %d times the serial thread\n",
            pid == 0 ? "child" : "parent", serials);

    if (pid == 0)
        /* The child.  Pass the number of times we had the serializing
           thread back to the parent.  */
        exit (serials);

    if (waitpid (pid, &status, 0) != pid)
    {
        puts ("waitpid failed");
        return 1;
    }

    if (!WIFEXITED (status))
    {
        puts ("child exited abnormally");
        return 1;
    }

    if (WEXITSTATUS (status) + serials != N)
    {
        printf ("total number of serials is %d, expected %d\n",
                WEXITSTATUS (status) + serials, N);
        return 1;
    }

    return 0;
}
Пример #10
0
static int
do_test (void)
{
  char tmp[] = "/tmp/tst-signal1-XXXXXX";

  int fd = mkstemp (tmp);
  if (fd == -1)
    {
      puts ("mkstemp failed");
      exit (1);
    }

  unlink (tmp);

  int i;
  for (i = 0; i < 20; ++i)
    write (fd, "foobar xyzzy", 12);

  b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE,
	    MAP_SHARED, fd, 0);
  if (b == MAP_FAILED)
    {
      puts ("mmap failed");
      exit (1);
    }

  pthread_barrierattr_t ba;
  if (pthread_barrierattr_init (&ba) != 0)
    {
      puts ("barrierattr_init failed");
      exit (1);
    }

  if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("barrierattr_setpshared failed");
      exit (1);
    }

  if (pthread_barrier_init (b, &ba, 2) != 0)
    {
      puts ("barrier_init failed");
      exit (1);
    }

  if (pthread_barrierattr_destroy (&ba) != 0)
    {
      puts ("barrierattr_destroy failed");
      exit (1);
    }

  pid_t pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      exit (1);
    }

  if (pid == 0)
    receiver ();

  pthread_barrier_wait (b);

  /* Wait a bit more.  */
  struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
  nanosleep (&ts, NULL);

  /* Send the signal.  */
  puts ("sending the signal now");
  kill (pid, SIGINT);

  /* Wait for the process to terminate.  */
  int status;
  if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
    {
      puts ("wrong child reported terminated");
      exit (1);
    }

  if (!WIFSIGNALED (status))
    {
      puts ("child wasn't signalled");
      exit (1);
    }

  if (WTERMSIG (status) != SIGINT)
    {
      puts ("child not terminated with SIGINT");
      exit (1);
    }

  return 0;
}
Пример #11
0
static int
do_test (void)
{
  size_t ps = sysconf (_SC_PAGESIZE);
  char tmpfname[] = "/tmp/tst-mutex4.XXXXXX";
  char data[ps];
  void *mem;
  int fd;
  pthread_mutex_t *m;
  pthread_mutexattr_t a;
  pid_t pid;
  char *p;
  int err;
  int s;
  pthread_barrier_t *b;
  pthread_barrierattr_t ba;

  fd = mkstemp (tmpfname);
  if (fd == -1)
    {
      printf ("cannot open temporary file: %m\n");
      return 1;
    }

  /* Make sure it is always removed.  */
  unlink (tmpfname);

  /* Create one page of data.  */
  memset (data, '\0', ps);

  /* Write the data to the file.  */
  if (write (fd, data, ps) != (ssize_t) ps)
    {
      puts ("short write");
      return 1;
    }

  mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (mem == MAP_FAILED)
    {
      printf ("mmap failed: %m\n");
      return 1;
    }

  m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t) - 1)
			   & ~(__alignof (pthread_mutex_t) - 1));
  b = (pthread_barrier_t *) (((uintptr_t) (m + 1)
			      + __alignof (pthread_barrier_t) - 1)
			     & ~(__alignof (pthread_barrier_t) - 1));
  p = (char *) (b + 1);

  if (pthread_mutexattr_init (&a) != 0)
    {
      puts ("mutexattr_init failed");
      return 1;
    }

  if (pthread_mutexattr_getpshared (&a, &s) != 0)
    {
      puts ("1st mutexattr_getpshared failed");
      return 1;
    }

  if (s != PTHREAD_PROCESS_PRIVATE)
    {
      puts ("default pshared value wrong");
      return 1;
    }

  if (pthread_mutexattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("mutexattr_setpshared failed");
      return 1;
    }

  if (pthread_mutexattr_getpshared (&a, &s) != 0)
    {
      puts ("2nd mutexattr_getpshared failed");
      return 1;
    }

  if (s != PTHREAD_PROCESS_SHARED)
    {
      puts ("pshared value after setpshared call wrong");
      return 1;
    }

#ifdef ENABLE_PI
  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
    {
      puts ("pthread_mutexattr_setprotocol failed");
      return 1;
    }
#endif

  if ((err = pthread_mutex_init (m, &a)) != 0)
    {
#ifdef ENABLE_PI
      if (err == ENOTSUP)
	{
	  puts ("PI mutexes unsupported");
	  return 0;
	}
#endif
      puts ("mutex_init failed");
      return 1;
    }

  if (pthread_mutex_lock (m) != 0)
    {
      puts ("mutex_lock failed");
      return 1;
    }

  if (pthread_mutexattr_destroy (&a) != 0)
    {
      puts ("mutexattr_destroy failed");
      return 1;
    }

  if (pthread_barrierattr_init (&ba) != 0)
    {
      puts ("barrierattr_init failed");
      return 1;
    }

  if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("barrierattr_setpshared failed");
      return 1;
    }

  if (pthread_barrier_init (b, &ba, 2) != 0)
    {
      puts ("barrier_init failed");
      return 1;
    }

  if (pthread_barrierattr_destroy (&ba) != 0)
    {
      puts ("barrierattr_destroy failed");
      return 1;
    }

  err = pthread_mutex_trylock (m);
  if (err == 0)
    {
      puts ("mutex_trylock succeeded");
      return 1;
    }
  else if (err != EBUSY)
    {
      puts ("mutex_trylock didn't return EBUSY");
      return 1;
    }

  *p = 0;

  if (pthread_mutex_unlock (m) != 0)
    {
      puts ("parent: 1st mutex_unlock failed");
      return 1;
    }

  puts ("going to fork now");
  pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      return 1;
    }
  else if (pid == 0)
    {
      if (pthread_mutex_lock (m) != 0)
	{
	  puts ("child: mutex_lock failed");
	  return 1;
	}

      int e = pthread_barrier_wait (b);
      if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
	{
	  puts ("child: barrier_wait failed");
	  return 1;
	}

      if ((*p)++ != 0)
	{
	  puts ("child: *p != 0");
	  return 1;
	}

      if (pthread_mutex_unlock (m) != 0)
	{
	  puts ("child: mutex_unlock failed");
	  return 1;
	}

      puts ("child done");
    }
  else
    {
      int e = pthread_barrier_wait (b);
      if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
	{
	  puts ("parent: barrier_wait failed");
	  return 1;
	}

      if (pthread_mutex_lock (m) != 0)
	{
	  puts ("parent: 2nd mutex_lock failed");
	  return 1;
	}

      if (*p != 1)
	{
	  puts ("*p != 1");
	  return 1;
	}

      if (pthread_mutex_unlock (m) != 0)
	{
	  puts ("parent: 2nd mutex_unlock failed");
	  return 1;
	}

      if (pthread_mutex_destroy (m) != 0)
	{
	  puts ("mutex_destroy failed");
	  return 1;
	}

      if (pthread_barrier_destroy (b) != 0)
	{
	  puts ("barrier_destroy failed");
	  return 1;
	}

      puts ("parent done");
    }

  return 0;
}
static void *
tf (void *arg)
{
  struct flock fl =
    {
      .l_type = F_WRLCK,
      .l_start = 0,
      .l_whence = SEEK_SET,
      .l_len = 10
    };
  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("fourth fcntl failed");
      exit (1);
    }

  pthread_mutex_unlock (&lock);

  pthread_mutex_lock (&lock2);

  return NULL;
}


static int
do_test (void)
{
  char tmp[] = "/tmp/tst-flock2-XXXXXX";

  fd = mkstemp (tmp);
  if (fd == -1)
    {
      puts ("mkstemp failed");
      return 1;
    }

  unlink (tmp);

  int i;
  for (i = 0; i < 20; ++i)
    write (fd, "foobar xyzzy", 12);

  pthread_barrier_t *b;
  b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE,
	    MAP_SHARED, fd, 0);
  if (b == MAP_FAILED)
    {
      puts ("mmap failed");
      return 1;
    }

  pthread_barrierattr_t ba;
  if (pthread_barrierattr_init (&ba) != 0)
    {
      puts ("barrierattr_init failed");
      return 1;
    }

  if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("barrierattr_setpshared failed");
      return 1;
    }

  if (pthread_barrier_init (b, &ba, 2) != 0)
    {
      puts ("barrier_init failed");
      return 1;
    }

  if (pthread_barrierattr_destroy (&ba) != 0)
    {
      puts ("barrierattr_destroy failed");
      return 1;
    }

  struct flock fl =
    {
      .l_type = F_WRLCK,
      .l_start = 0,
      .l_whence = SEEK_SET,
      .l_len = 10
    };
  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("first fcntl failed");
      return 1;
    }

  pid_t pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      return 1;
    }

  if (pid == 0)
    {
      /* Make sure the child does not stay around indefinitely.  */
      alarm (10);

      /* Try to get the lock.  */
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("child:  second flock succeeded");
	  return 1;
	}
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_UNLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
	{
	  puts ("third fcntl failed");
	  return 1;
	}
    }

  pthread_barrier_wait (b);

  pthread_t th;
  if (pid == 0)
    {
      if (pthread_mutex_lock (&lock) != 0)
	{
	  puts ("1st locking of lock failed");
	  return 1;
	}

      if (pthread_mutex_lock (&lock2) != 0)
	{
	  puts ("1st locking of lock2 failed");
	  return 1;
	}

      if (pthread_create (&th, NULL, tf, NULL) != 0)
	{
	  puts ("pthread_create failed");
	  return 1;
	}

      if (pthread_mutex_lock (&lock) != 0)
	{
	  puts ("2nd locking of lock failed");
	  return 1;
	}

      puts ("child locked file");
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_WRLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("fifth fcntl succeeded");
	  return 1;
	}

      puts ("file locked by child");
    }

  pthread_barrier_wait (b);

  if (pid == 0)
    {
      if (pthread_mutex_unlock (&lock2) != 0)
	{
	  puts ("unlock of lock2 failed");
	  return 1;
	}

      if (pthread_join (th, NULL) != 0)
	{
	  puts ("join failed");
	  return 1;
	}

      puts ("child's thread terminated");
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_WRLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("fifth fcntl succeeded");
	  return 1;
	}

      puts ("file still locked");
    }

  pthread_barrier_wait (b);

  if (pid == 0)
    {
      _exit (0);
    }

  int status;
  if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
    {
      puts ("waitpid failed");
      return 1;
    }
  puts ("child terminated");

  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("sixth fcntl failed");
      return 1;
    }

  return status;
}
Пример #13
0
Файл: 2-1.c Проект: jiezh/h5vcc
int main()
{

    /* Make sure there is process-shared capability. */
#ifndef PTHREAD_PROCESS_SHARED
    fprintf(stderr,"process-shared attribute is not available for testing\n");
    return PTS_UNSUPPORTED;
#endif

    static pthread_barrier_t* barrier;
    pthread_barrierattr_t ba;
    int	pshared = PTHREAD_PROCESS_SHARED;

    char 	shm_name[] = "tmp_pthread_barrierattr_getpshared";
    int 	shm_fd;
    int 	pid;
    int 	loop;
    int	serial = 0;
    int	rc;
    int	status = 0;
    struct sigaction act;

    /* Set up parent to handle SIGALRM */
    act.sa_flags = 0;
    act.sa_handler = sig_handler;
    sigfillset(&act.sa_mask);
    sigaction(SIGALRM, &act, 0);

    /* Initialize a barrier attributes object */
    if(pthread_barrierattr_init(&ba) != 0)
    {
        printf("Error at pthread_barrierattr_init()\n");
        return PTS_UNRESOLVED;
    }

    /* Set the pshard value to private to shared */
    if(pthread_barrierattr_setpshared(&ba, pshared) != 0)
    {
        printf("Error at pthread_barrierattr_setpshared()\n");
        return PTS_UNRESOLVED;
    }

    if(pthread_barrierattr_getpshared(&ba, &pshared) != 0)
    {
        printf("Test FAILED: Error at pthread_barrierattr_getpshared()\n");
        return PTS_FAIL;
    }

    if(pshared != PTHREAD_PROCESS_SHARED)
    {
        printf("Test FAILED: Incorrect pshared value %d\n", pshared);
        return PTS_FAIL;
    }

    /* Create shared object */
    shm_unlink(shm_name);
    shm_fd = shm_open(shm_name, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
    if(shm_fd == -1)
    {
        perror("Error at shm_open()");
        return PTS_UNRESOLVED;
    }

    if(ftruncate(shm_fd, sizeof(pthread_barrier_t)) != 0)
    {
        perror("Error at ftruncate()");
        shm_unlink(shm_name);
        return PTS_UNRESOLVED;
    }

    /* Map the shared memory object to my memory */
    barrier = mmap(NULL, sizeof(pthread_barrier_t), PROT_READ|PROT_WRITE,
                   MAP_SHARED, shm_fd, 0);

    if(barrier == MAP_FAILED)
    {
        perror("Error at first mmap()");
        shm_unlink(shm_name);
        return PTS_UNRESOLVED;
    }

    /* Initialize a barrier */
    if((pthread_barrier_init(barrier, &ba, 2)) != 0)
    {
        printf("Error at pthread_barrier_init()\n");
        return PTS_UNRESOLVED;
    }

    /* Cleanup */
    if((pthread_barrierattr_destroy(&ba)) != 0)
    {
        printf("Error at pthread_barrierattr_destroy()\n");
        return PTS_UNRESOLVED;
    }

    /* Fork a child process */
    pid = fork();
    if(pid == -1)
    {
        perror("Error at fork()");
        return PTS_UNRESOLVED;
    }
    else if(pid == 0)
    {
        /* Child */
        /* Map the shared object to child's memory */
        barrier = mmap(NULL, sizeof(pthread_barrier_t), PROT_READ|PROT_WRITE,
                       MAP_SHARED, shm_fd, 0);

        if(barrier == MAP_FAILED)
        {
            perror("child: Error at first mmap()");
            return PTS_UNRESOLVED;
        }
    }
    else
    {
        printf("parent pid : %d, child pid : %d\n", getpid(), pid);
        printf("parent: send me SIGALRM 2 secs later in case I am blocked\n");
        alarm(2);
    }

    for(loop = 0; loop < LOOP_NUM; loop++)
    {
        rc = pthread_barrier_wait(barrier);
        if(rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD)
        {
            printf("Test FAILED: %d: pthread_barrier_wait() got unexpected "
                   "return code : %d\n" , getpid(), rc);
            exit(PTS_FAIL);
        }
        else if(rc == PTHREAD_BARRIER_SERIAL_THREAD)
        {
            serial++;
            printf("process %d: get PTHREAD_BARRIER_SERIAL_THREAD\n"
                   , getpid());
        }

    }

    if(pid > 0)
    {
        /* parent */
        if( wait(&status) != pid)
        {
            printf("parent: error at waitpid()\n");
            return PTS_UNRESOLVED;
        }

        if(!WIFEXITED(status))
        {
            printf("Child exited abnormally\n");
            return PTS_UNRESOLVED;
        }

        if((WEXITSTATUS(status) + serial) != LOOP_NUM)
        {
            printf("status = %d\n", status);
            printf("serial = %d\n", serial);
            printf("Test FAILED: One of the two processes should get "
                   "PTHREAD_BARRIER_SERIAL_THREAD\n");
            return PTS_FAIL;
        }

        /* Cleanup */
        if(pthread_barrier_destroy(barrier) != 0)
        {
            printf("Error at pthread_barrier_destroy()");
            return PTS_UNRESOLVED;
        }

        if((shm_unlink(shm_name)) != 0)
        {
            perror("Error at shm_unlink()");
            return PTS_UNRESOLVED;
        }

        printf("Test PASSED\n");
        return PTS_PASS;
    }

    if(pid == 0)
    {
        exit(serial);
    }

    return PTS_UNRESOLVED;
}