diff mbox

[v2,5/5] Add test cases for ISO C11 threads

Message ID 1440515272-9453-6-git-send-email-j.m.torrespalma@gmail.com
State New, archived
Headers show

Commit Message

Juan Manuel Torres Palma Aug. 25, 2015, 3:07 p.m. UTC
This patch adds to testsuite new test cases to test all of
the new introduced functionality. All the ISO C11 functions,
types and macros are tested.

2015-08-25  Juan Manuel Torres Palma  <jmtorrespalma@gmail.com>

	* nptl/Makefile (tests): Add new test files.
	* nptl/tst-call-once.c : New file. Tests C11 functions and types.
	* nptl/tst-cnd-basic.c: Likewise.
	* nptl/tst-cnd-broadcast.c: Likewise.
	* nptl/tst-cnd-timedwait.c: Likewise.
	* nptl/tst-mtx-basic.c: Likewise.
	* nptl/tst-mtx-recursive.c: Likewise.
	* nptl/tst-mtx-timedlock.c: Likewise.
	* nptl/tst-mtx-trylock.c: Likewise.
	* nptl/tst-thrd-basic.c: Likewise.
	* nptl/tst-thrd-detach.c: Likewise.
	* nptl/tst-thrd-sleep.c: Likewise.
	* nptl/tst-tss-basic.c: Likewise.

Comments

Juan Manuel Torres Palma Sept. 3, 2015, 10:27 p.m. UTC | #1
Ping.

2015-08-26 0:07 GMT+09:00 Juan Manuel Torres Palma <j.m.torrespalma@gmail.com>:
> This patch adds to testsuite new test cases to test all of
> the new introduced functionality. All the ISO C11 functions,
> types and macros are tested.
>
> 2015-08-25  Juan Manuel Torres Palma  <jmtorrespalma@gmail.com>
>
>         * nptl/Makefile (tests): Add new test files.
>         * nptl/tst-call-once.c : New file. Tests C11 functions and types.
>         * nptl/tst-cnd-basic.c: Likewise.
>         * nptl/tst-cnd-broadcast.c: Likewise.
>         * nptl/tst-cnd-timedwait.c: Likewise.
>         * nptl/tst-mtx-basic.c: Likewise.
>         * nptl/tst-mtx-recursive.c: Likewise.
>         * nptl/tst-mtx-timedlock.c: Likewise.
>         * nptl/tst-mtx-trylock.c: Likewise.
>         * nptl/tst-thrd-basic.c: Likewise.
>         * nptl/tst-thrd-detach.c: Likewise.
>         * nptl/tst-thrd-sleep.c: Likewise.
>         * nptl/tst-tss-basic.c: Likewise.
>
> diff --git a/nptl/Makefile b/nptl/Makefile
> index 9c3ffb8..4a88816 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -292,7 +292,12 @@ tests = tst-typesizes \
>         tst-getpid3 \
>         tst-setuid3 \
>         tst-initializers1 $(addprefix tst-initializers1-,c89 gnu89 c99 gnu99) \
> -       tst-bad-schedattr
> +       tst-bad-schedattr \
> +       tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
> +       tst-thrd-basic tst-cnd-timedwait tst-thrd-detach \
> +       tst-mtx-basic tst-thrd-sleep tst-mtx-recursive tst-tss-basic \
> +       tst-call-once tst-mtx-timedlock
> +
>  xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
>         tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
>  test-srcs = tst-oddstacklimit
> diff --git a/nptl/tst-call-once.c b/nptl/tst-call-once.c
> new file mode 100644
> index 0000000..9eeb5c2
> --- /dev/null
> +++ b/nptl/tst-call-once.c
> @@ -0,0 +1,77 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +
> +/* Flag that controls the first thread access.  */
> +static once_flag flag = ONCE_FLAG_INIT;
> +
> +/* Function called only once.  */
> +void
> +do_once (void)
> +{
> +  printf ("Called once\n");
> +}
> +
> +/* Code executed by each thread.  */
> +int
> +func (void* data)
> +{
> +  call_once (&flag, do_once);
> +  thrd_exit(thrd_success);
> +}
> +
> +
> +#define N 20
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t ids[N];
> +  unsigned char i;
> +
> +
> +  /* Create N new threads.  */
> +  for (i = 0; i < N; ++i)
> +  {
> +    if (thrd_create (&ids[i], func, NULL) != thrd_success)
> +    {
> +      printf ("Create failed\n");
> +      _exit (1);
> +    }
> +  }
> +
> +  /* Join threads.  */
> +  for (i = 0; i < N; ++i)
> +  {
> +    if (thrd_join (ids[i], NULL) != thrd_success)
> +    {
> +      printf ("Join failed\n");
> +      _exit (1);
> +    }
> +  }
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-cnd-basic.c b/nptl/tst-cnd-basic.c
> new file mode 100644
> index 0000000..8e72051
> --- /dev/null
> +++ b/nptl/tst-cnd-basic.c
> @@ -0,0 +1,92 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Shared condition variable between child and parent.  */
> +static cnd_t cond;
> +
> +/* Mutex needed to signal and wait threads.  */
> +static mtx_t mutex;
> +
> +int
> +signal_parent (void)
> +{
> +  /* Send signal to parent.  */
> +  printf ("Child signaling\n");
> +  if (cnd_signal (&cond) != thrd_success)
> +  {
> +    printf ("Child signal error.\n");
> +    _exit (1);
> +  }
> +
> +  thrd_exit (thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +
> +  /* Initialize cond and mutex.  */
> +  if (cnd_init (&cond) != thrd_success
> +      || mtx_init (&mutex, mtx_plain) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) signal_parent, NULL)
> +       != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Wait on cond, until child thread signals.  */
> +  if (cnd_wait (&cond, &mutex) != thrd_success)
> +  {
> +    printf ("Parent lock failed\n");
> +    _exit (1);
> +  }
> +  printf ("Parent received signal, continuing\n");
> +
> +  /* Joining is not mandatory here, but still done
> +     to assure child thread ends correctly..  */
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed.\n");
> +    _exit (1);
> +  }
> +
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  /* Destroy cond.  */
> +  cnd_destroy (&cond);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-cnd-broadcast.c b/nptl/tst-cnd-broadcast.c
> new file mode 100644
> index 0000000..b93c9a9
> --- /dev/null
> +++ b/nptl/tst-cnd-broadcast.c
> @@ -0,0 +1,95 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Condition variable where child threads will wait.  */
> +cnd_t cond;
> +
> +/* Mutex to control wait on cond.  */
> +mtx_t mutex;
> +
> +/* Code executed by each thread.  */
> +int
> +child_wait (void* data)
> +{
> +  printf ("Arrived\n");
> +  /* Wait until parent thread sends broadcast here.  */
> +  mtx_lock (&mutex);
> +  cnd_wait (&cond, &mutex);
> +  mtx_unlock (&mutex);
> +
> +  printf ("Freed thread\n");
> +  thrd_exit (thrd_success);
> +}
> +
> +#define N 5
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t ids[N];
> +  unsigned char i;
> +
> +  cnd_init (&cond);
> +  mtx_init (&mutex, mtx_plain);
> +
> +  /* Create N new threads.  */
> +  for (i = 0; i < N; ++i)
> +  {
> +    if (thrd_create (&ids[i], child_wait, NULL) != thrd_success)
> +    {
> +      printf ("Create failed\n");
> +      _exit (1);
> +    }
> +  }
> +
> +  /* Wait for other threads to reach their wait func.  */
> +  thrd_sleep (&((struct timespec){.tv_sec = 2}), NULL);
> +
> +  /* Send broadcast.  */
> +  mtx_lock (&mutex);
> +  if (cnd_broadcast (&cond) != thrd_success)
> +  {
> +    printf ("Broadcast error");
> +    _exit (1);
> +  }
> +  mtx_unlock (&mutex);
> +
> +  /* Join threads.  */
> +  for (i = 0; i < N; ++i)
> +  {
> +    if (thrd_join (ids[i], NULL) != thrd_success)
> +    {
> +      printf ("Join failed\n");
> +      _exit (1);
> +    }
> +  }
> +
> +
> +  mtx_destroy (&mutex);
> +  cnd_destroy (&cond);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-cnd-timedwait.c b/nptl/tst-cnd-timedwait.c
> new file mode 100644
> index 0000000..c8aff19
> --- /dev/null
> +++ b/nptl/tst-cnd-timedwait.c
> @@ -0,0 +1,104 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Shared condition variable between child and parent.  */
> +static cnd_t cond;
> +
> +/* Mutex needed to signal and wait threads.  */
> +static mtx_t mutex;
> +
> +int
> +signal_parent (void)
> +{
> +  /* Send signal to parent.  */
> +  printf ("Child signaling\n");
> +  if (cnd_signal (&cond) != thrd_success)
> +  {
> +    printf ("Child signal error.\n");
> +    _exit (1);
> +  }
> +
> +  //thrd_exit(thrd_success);
> +  return 0;
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +  struct timespec w_time;
> +
> +  /* Initialize cond and mutex.  */
> +  if (cnd_init (&cond) != thrd_success
> +      || mtx_init (&mutex, mtx_timed) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Initialize waiting time.  */
> +  clock_gettime (CLOCK_REALTIME, &w_time);
> +  w_time.tv_nsec += 150000;
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) signal_parent, NULL)
> +       != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Wait on cond, until child thread signals.  */
> +  switch (cnd_timedwait (&cond, &mutex, &w_time))
> +  {
> +    case thrd_error:
> +      printf ("Parent lock failed\n");
> +      _exit (1);
> +    case thrd_timedout:
> +      printf ("Waiting too long, leaving\n");
> +      break;
> +    case thrd_success:
> +      printf ("Signaled successfully,\n");
> +      break;
> +  }
> +
> +  /* Joining is not mandatory here, but still done
> +     to assure child thread ends correctly..  */
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed.\n");
> +    _exit (1);
> +  }
> +
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  /* Destroy cond.  */
> +  cnd_destroy (&cond);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-mtx-basic.c b/nptl/tst-mtx-basic.c
> new file mode 100644
> index 0000000..ea7fdc6
> --- /dev/null
> +++ b/nptl/tst-mtx-basic.c
> @@ -0,0 +1,112 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Shared mutex between child and parent.  */
> +static mtx_t mutex;
> +
> +/* Shared counter to check possible race conditions.  */
> +static char shrd_counter;
> +
> +int
> +child_add (void)
> +{
> +  /* Lock mutex.  */
> +  if (mtx_lock (&mutex) != thrd_success)
> +  {
> +    printf ("Child lock error.\n");
> +    _exit (1);
> +  }
> +
> +  /* Critical section.  */
> +  printf ("Child locking\n");
> +  ++shrd_counter;
> +  printf ("Child unlocking\n");
> +
> +  /* Unlock mutex.  */
> +  if (mtx_unlock (&mutex) != thrd_success)
> +  {
> +    printf ("Child unlock error.\n");
> +    _exit (1);
> +  }
> +  thrd_exit (thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +
> +  /* Initialize mutex.  */
> +  mtx_init (&mutex, mtx_plain);
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) child_add, NULL) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Created thread\n");
> +
> +
> +  if (mtx_lock (&mutex) != thrd_success)
> +  {
> +    printf ("Parent lock failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Critical section.  */
> +  printf ("Parent locking\n");
> +  ++shrd_counter;
> +  printf ("Parent unlocking\n");
> +
> +  /* Unlock mutex.  */
> +  if (mtx_unlock (&mutex) != thrd_success)
> +  {
> +    printf ("Parent unlock error.\n");
> +    _exit (1);
> +  }
> +
> +
> +  /* Still have to wait until child is done.  */
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed.\n");
> +    _exit (1);
> +  }
> +
> +  /* Check result.  */
> +  if (shrd_counter != 2)
> +  {
> +    printf ("Counter has a wrong value.\n");
> +    _exit (1);
> +  }
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-mtx-recursive.c b/nptl/tst-mtx-recursive.c
> new file mode 100644
> index 0000000..e28faed
> --- /dev/null
> +++ b/nptl/tst-mtx-recursive.c
> @@ -0,0 +1,57 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +
> +int
> +do_test (void)
> +{
> +
> +  static mtx_t mutex;
> +
> +  /* Initialize mutex.  */
> +  mtx_init (&mutex, mtx_recursive);
> +
> +  /* Lock mutex first time.  */
> +  if (mtx_lock (&mutex) != thrd_success)
> +  {
> +    printf ("First lock failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Mutex locked once\n");
> +
> +  /* Lock mutex second time, if not recursive should deadlock.  */
> +  if (mtx_lock (&mutex) != thrd_success)
> +  {
> +    printf ("Second lock failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Mutex locked twice\n");
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  return 0;
> +}
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-mtx-timedlock.c b/nptl/tst-mtx-timedlock.c
> new file mode 100644
> index 0000000..5bfec09
> --- /dev/null
> +++ b/nptl/tst-mtx-timedlock.c
> @@ -0,0 +1,124 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Shared mutex between child and parent.  */
> +static mtx_t mutex;
> +
> +/* Shared counter to check possible race conditions.  */
> +static char shrd_counter;
> +
> +/* Maximum amount of time waiting for mutex.  */
> +static struct timespec wait_time;
> +
> +/* Function to choose an action to do, depending on mtx_timedlock
> +   return value.  */
> +static inline void
> +choose_action (int action, char* thread_name)
> +{
> +  switch (action)
> +  {
> +    case thrd_success:
> +
> +      /* Critical section.  */
> +      printf ("%s locking.\n", thread_name);
> +      ++shrd_counter;
> +      printf ("%s unlocking.\n", thread_name);
> +
> +      /* Unlock mutex.  */
> +      if (mtx_unlock (&mutex) != thrd_success)
> +      {
> +        printf ("%s unlock error.\n", thread_name);
> +        _exit (1);
> +      }
> +      break;
> +
> +    case thrd_timedout:
> +      printf ("Waiting for mutex too long, %s leaving.\n", thread_name);
> +      break;
> +
> +    case thrd_error:
> +      printf ("%s lock error.\n", thread_name);
> +      _exit (1);
> +      break;
> +  }
> +
> +}
> +
> +int
> +child_add (void)
> +{
> +  char child_name[] = "Child";
> +
> +  /* Try to lock mutex.  */
> +  choose_action (mtx_timedlock (&mutex, &wait_time), child_name);
> +  thrd_exit (thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +  thrd_t id;
> +  char parent_name[] = "Parent";
> +
> +  /* Initialize mutex.  */
> +  mtx_init (&mutex, mtx_timed);
> +
> +  /* Initialize waiting time.  */
> +  clock_gettime (CLOCK_REALTIME, &wait_time);
> +  /* Tiny amount of time, to assure that if any thread
> +     finds it busy, will receive thrd_timedout.  */
> +  wait_time.tv_nsec += 1;
> +
> +
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) child_add, NULL) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Try to lock mutex.  */
> +  choose_action (mtx_timedlock (&mutex, &wait_time), parent_name);
> +
> +  /* Still have to wait until child is done.  */
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed.\n");
> +    _exit (1);
> +  }
> +
> +  /* Check result.  */
> +  if (shrd_counter != 2 && shrd_counter != 1)
> +  {
> +    printf ("Counter has a wrong value: %i.\n", shrd_counter);
> +    _exit (1);
> +  }
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-mtx-trylock.c b/nptl/tst-mtx-trylock.c
> new file mode 100644
> index 0000000..fa75066
> --- /dev/null
> +++ b/nptl/tst-mtx-trylock.c
> @@ -0,0 +1,114 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Shared mutex between child and parent.  */
> +static mtx_t mutex;
> +
> +/* Shared counter to check possible race conditions.  */
> +static char shrd_counter;
> +
> +/* Function to choose an action to do, depending on mtx_trylock
> +   return value.  */
> +static inline void
> +choose_action (int action, char* thread_name)
> +{
> +  switch (action)
> +  {
> +    case thrd_success:
> +
> +      /* Critical section.  */
> +      printf ("%s locking\n", thread_name);
> +      ++shrd_counter;
> +      printf ("%s unlocking\n", thread_name);
> +
> +      /* Unlock mutex.  */
> +      if (mtx_unlock (&mutex) != thrd_success)
> +      {
> +        printf ("%s unlock error.\n", thread_name);
> +        _exit (1);
> +      }
> +      break;
> +
> +    case thrd_busy:
> +      printf ("Mutex is taken, %s leaving.\n", thread_name);
> +      break;
> +
> +    case thrd_error:
> +      printf ("%s lock error.\n", thread_name);
> +      _exit (1);
> +      break;
> +  }
> +
> +}
> +
> +int
> +child_add (void)
> +{
> +  char child_name[] = "Child";
> +
> +  /* Try to lock mutex.  */
> +  choose_action (mtx_trylock (&mutex), child_name);
> +
> +  thrd_exit(thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +  thrd_t id;
> +  char parent_name[] = "Parent";
> +
> +  /* Initialize mutex.  */
> +  mtx_init (&mutex, mtx_plain);
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) child_add, NULL) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Try to lock mutex.  */
> +  choose_action (mtx_trylock (&mutex), parent_name);
> +
> +  /* Still have to wait until child is done.  */
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed.\n");
> +    _exit (1);
> +  }
> +
> +  /* Check result.  */
> +  if (shrd_counter != 2 && shrd_counter != 1)
> +  {
> +    printf ("Counter has a wrong value: %i.\n", shrd_counter);
> +    _exit (1);
> +  }
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-thrd-basic.c b/nptl/tst-thrd-basic.c
> new file mode 100644
> index 0000000..53e0888
> --- /dev/null
> +++ b/nptl/tst-thrd-basic.c
> @@ -0,0 +1,63 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +
> +int
> +print_id (void *parent_id)
> +{
> +  printf ("Thread ID: %lu, Parent ID: %lu\n", thrd_current (),
> +       (thrd_t) parent_id);
> +  thrd_exit (thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +  int ret_val;
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, print_id, (void *) thrd_current ()) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Created thread\n");
> +
> +
> +  if (thrd_join (id, &ret_val) != thrd_success)
> +  {
> +    printf ("Join failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Joined thread\n");
> +
> +  printf ("Child returned %u\n", ret_val);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-thrd-detach.c b/nptl/tst-thrd-detach.c
> new file mode 100644
> index 0000000..ca0d7b0
> --- /dev/null
> +++ b/nptl/tst-thrd-detach.c
> @@ -0,0 +1,61 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <time.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +
> +int
> +dtch_thrd (void)
> +{
> +
> +  if (thrd_detach (thrd_current ()) != thrd_success)
> +  {
> +    printf ("Detach failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Succesfully detached\n");
> +
> +  return 0;
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) dtch_thrd, NULL) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Created thread\n");
> +
> +  thrd_sleep (&(struct timespec){.tv_sec = 2}, NULL);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-thrd-sleep.c b/nptl/tst-thrd-sleep.c
> new file mode 100644
> index 0000000..8557c6b
> --- /dev/null
> +++ b/nptl/tst-thrd-sleep.c
> @@ -0,0 +1,71 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <time.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +
> +int
> +go_to_sleep (struct timespec const *tl)
> +{
> +
> +  printf ("Time before sleeping: %s", ctime (&(time_t){time(NULL)}));
> +  if (thrd_sleep (tl, NULL) != 0)
> +  {
> +    printf ("Sleep failed\n");
> +    _exit (1);
> +  }
> +  printf ("Time after sleeping: %s", ctime (&(time_t){time(NULL)}));
> +
> +  return 0;
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +  /* Wait for 3 seconds.  */
> +  struct timespec wait_time = {.tv_sec = 3};
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) go_to_sleep,
> +        (void *) (&wait_time)) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Created thread\n");
> +
> +
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Joined thread\n");
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-tss-basic.c b/nptl/tst-tss-basic.c
> new file mode 100644
> index 0000000..0064c63
> --- /dev/null
> +++ b/nptl/tst-tss-basic.c
> @@ -0,0 +1,70 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Thread specific storage.  */
> +tss_t key;
> +
> +int
> +print_id (void *val)
> +{
> +  tss_create (&key, NULL);
> +  tss_set (key, (void *) 0xff);
> +  printf ("Child key: %u\n", key);
> +  printf ("Child value: %p\n", tss_get (key));
> +
> +
> +  thrd_exit(thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +  int ret_val;
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, print_id, NULL) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  if (thrd_join (id, &ret_val) != thrd_success)
> +  {
> +    printf ("Join failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Joined thread\n");
> +
> +  /* We check parent has the same key value, but
> +     no value, because was not assigned.  */
> +  printf ("Parent key: %u\n", key);
> +  printf ("Parent value: %p\n", tss_get (key));
> +  tss_delete (key);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> --
> 2.4.3
Juan Manuel Torres Palma Oct. 13, 2015, 10:09 a.m. UTC | #2
Ping^2

2015-08-25 17:07 GMT+02:00 Juan Manuel Torres Palma <j.m.torrespalma@gmail.com>:
> This patch adds to testsuite new test cases to test all of
> the new introduced functionality. All the ISO C11 functions,
> types and macros are tested.
>
> 2015-08-25  Juan Manuel Torres Palma  <jmtorrespalma@gmail.com>
>
>         * nptl/Makefile (tests): Add new test files.
>         * nptl/tst-call-once.c : New file. Tests C11 functions and types.
>         * nptl/tst-cnd-basic.c: Likewise.
>         * nptl/tst-cnd-broadcast.c: Likewise.
>         * nptl/tst-cnd-timedwait.c: Likewise.
>         * nptl/tst-mtx-basic.c: Likewise.
>         * nptl/tst-mtx-recursive.c: Likewise.
>         * nptl/tst-mtx-timedlock.c: Likewise.
>         * nptl/tst-mtx-trylock.c: Likewise.
>         * nptl/tst-thrd-basic.c: Likewise.
>         * nptl/tst-thrd-detach.c: Likewise.
>         * nptl/tst-thrd-sleep.c: Likewise.
>         * nptl/tst-tss-basic.c: Likewise.
>
> diff --git a/nptl/Makefile b/nptl/Makefile
> index 9c3ffb8..4a88816 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -292,7 +292,12 @@ tests = tst-typesizes \
>         tst-getpid3 \
>         tst-setuid3 \
>         tst-initializers1 $(addprefix tst-initializers1-,c89 gnu89 c99 gnu99) \
> -       tst-bad-schedattr
> +       tst-bad-schedattr \
> +       tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
> +       tst-thrd-basic tst-cnd-timedwait tst-thrd-detach \
> +       tst-mtx-basic tst-thrd-sleep tst-mtx-recursive tst-tss-basic \
> +       tst-call-once tst-mtx-timedlock
> +
>  xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
>         tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
>  test-srcs = tst-oddstacklimit
> diff --git a/nptl/tst-call-once.c b/nptl/tst-call-once.c
> new file mode 100644
> index 0000000..9eeb5c2
> --- /dev/null
> +++ b/nptl/tst-call-once.c
> @@ -0,0 +1,77 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +
> +/* Flag that controls the first thread access.  */
> +static once_flag flag = ONCE_FLAG_INIT;
> +
> +/* Function called only once.  */
> +void
> +do_once (void)
> +{
> +  printf ("Called once\n");
> +}
> +
> +/* Code executed by each thread.  */
> +int
> +func (void* data)
> +{
> +  call_once (&flag, do_once);
> +  thrd_exit(thrd_success);
> +}
> +
> +
> +#define N 20
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t ids[N];
> +  unsigned char i;
> +
> +
> +  /* Create N new threads.  */
> +  for (i = 0; i < N; ++i)
> +  {
> +    if (thrd_create (&ids[i], func, NULL) != thrd_success)
> +    {
> +      printf ("Create failed\n");
> +      _exit (1);
> +    }
> +  }
> +
> +  /* Join threads.  */
> +  for (i = 0; i < N; ++i)
> +  {
> +    if (thrd_join (ids[i], NULL) != thrd_success)
> +    {
> +      printf ("Join failed\n");
> +      _exit (1);
> +    }
> +  }
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-cnd-basic.c b/nptl/tst-cnd-basic.c
> new file mode 100644
> index 0000000..8e72051
> --- /dev/null
> +++ b/nptl/tst-cnd-basic.c
> @@ -0,0 +1,92 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Shared condition variable between child and parent.  */
> +static cnd_t cond;
> +
> +/* Mutex needed to signal and wait threads.  */
> +static mtx_t mutex;
> +
> +int
> +signal_parent (void)
> +{
> +  /* Send signal to parent.  */
> +  printf ("Child signaling\n");
> +  if (cnd_signal (&cond) != thrd_success)
> +  {
> +    printf ("Child signal error.\n");
> +    _exit (1);
> +  }
> +
> +  thrd_exit (thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +
> +  /* Initialize cond and mutex.  */
> +  if (cnd_init (&cond) != thrd_success
> +      || mtx_init (&mutex, mtx_plain) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) signal_parent, NULL)
> +       != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Wait on cond, until child thread signals.  */
> +  if (cnd_wait (&cond, &mutex) != thrd_success)
> +  {
> +    printf ("Parent lock failed\n");
> +    _exit (1);
> +  }
> +  printf ("Parent received signal, continuing\n");
> +
> +  /* Joining is not mandatory here, but still done
> +     to assure child thread ends correctly..  */
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed.\n");
> +    _exit (1);
> +  }
> +
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  /* Destroy cond.  */
> +  cnd_destroy (&cond);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-cnd-broadcast.c b/nptl/tst-cnd-broadcast.c
> new file mode 100644
> index 0000000..b93c9a9
> --- /dev/null
> +++ b/nptl/tst-cnd-broadcast.c
> @@ -0,0 +1,95 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Condition variable where child threads will wait.  */
> +cnd_t cond;
> +
> +/* Mutex to control wait on cond.  */
> +mtx_t mutex;
> +
> +/* Code executed by each thread.  */
> +int
> +child_wait (void* data)
> +{
> +  printf ("Arrived\n");
> +  /* Wait until parent thread sends broadcast here.  */
> +  mtx_lock (&mutex);
> +  cnd_wait (&cond, &mutex);
> +  mtx_unlock (&mutex);
> +
> +  printf ("Freed thread\n");
> +  thrd_exit (thrd_success);
> +}
> +
> +#define N 5
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t ids[N];
> +  unsigned char i;
> +
> +  cnd_init (&cond);
> +  mtx_init (&mutex, mtx_plain);
> +
> +  /* Create N new threads.  */
> +  for (i = 0; i < N; ++i)
> +  {
> +    if (thrd_create (&ids[i], child_wait, NULL) != thrd_success)
> +    {
> +      printf ("Create failed\n");
> +      _exit (1);
> +    }
> +  }
> +
> +  /* Wait for other threads to reach their wait func.  */
> +  thrd_sleep (&((struct timespec){.tv_sec = 2}), NULL);
> +
> +  /* Send broadcast.  */
> +  mtx_lock (&mutex);
> +  if (cnd_broadcast (&cond) != thrd_success)
> +  {
> +    printf ("Broadcast error");
> +    _exit (1);
> +  }
> +  mtx_unlock (&mutex);
> +
> +  /* Join threads.  */
> +  for (i = 0; i < N; ++i)
> +  {
> +    if (thrd_join (ids[i], NULL) != thrd_success)
> +    {
> +      printf ("Join failed\n");
> +      _exit (1);
> +    }
> +  }
> +
> +
> +  mtx_destroy (&mutex);
> +  cnd_destroy (&cond);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-cnd-timedwait.c b/nptl/tst-cnd-timedwait.c
> new file mode 100644
> index 0000000..c8aff19
> --- /dev/null
> +++ b/nptl/tst-cnd-timedwait.c
> @@ -0,0 +1,104 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Shared condition variable between child and parent.  */
> +static cnd_t cond;
> +
> +/* Mutex needed to signal and wait threads.  */
> +static mtx_t mutex;
> +
> +int
> +signal_parent (void)
> +{
> +  /* Send signal to parent.  */
> +  printf ("Child signaling\n");
> +  if (cnd_signal (&cond) != thrd_success)
> +  {
> +    printf ("Child signal error.\n");
> +    _exit (1);
> +  }
> +
> +  //thrd_exit(thrd_success);
> +  return 0;
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +  struct timespec w_time;
> +
> +  /* Initialize cond and mutex.  */
> +  if (cnd_init (&cond) != thrd_success
> +      || mtx_init (&mutex, mtx_timed) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Initialize waiting time.  */
> +  clock_gettime (CLOCK_REALTIME, &w_time);
> +  w_time.tv_nsec += 150000;
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) signal_parent, NULL)
> +       != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Wait on cond, until child thread signals.  */
> +  switch (cnd_timedwait (&cond, &mutex, &w_time))
> +  {
> +    case thrd_error:
> +      printf ("Parent lock failed\n");
> +      _exit (1);
> +    case thrd_timedout:
> +      printf ("Waiting too long, leaving\n");
> +      break;
> +    case thrd_success:
> +      printf ("Signaled successfully,\n");
> +      break;
> +  }
> +
> +  /* Joining is not mandatory here, but still done
> +     to assure child thread ends correctly..  */
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed.\n");
> +    _exit (1);
> +  }
> +
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  /* Destroy cond.  */
> +  cnd_destroy (&cond);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-mtx-basic.c b/nptl/tst-mtx-basic.c
> new file mode 100644
> index 0000000..ea7fdc6
> --- /dev/null
> +++ b/nptl/tst-mtx-basic.c
> @@ -0,0 +1,112 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Shared mutex between child and parent.  */
> +static mtx_t mutex;
> +
> +/* Shared counter to check possible race conditions.  */
> +static char shrd_counter;
> +
> +int
> +child_add (void)
> +{
> +  /* Lock mutex.  */
> +  if (mtx_lock (&mutex) != thrd_success)
> +  {
> +    printf ("Child lock error.\n");
> +    _exit (1);
> +  }
> +
> +  /* Critical section.  */
> +  printf ("Child locking\n");
> +  ++shrd_counter;
> +  printf ("Child unlocking\n");
> +
> +  /* Unlock mutex.  */
> +  if (mtx_unlock (&mutex) != thrd_success)
> +  {
> +    printf ("Child unlock error.\n");
> +    _exit (1);
> +  }
> +  thrd_exit (thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +
> +  /* Initialize mutex.  */
> +  mtx_init (&mutex, mtx_plain);
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) child_add, NULL) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Created thread\n");
> +
> +
> +  if (mtx_lock (&mutex) != thrd_success)
> +  {
> +    printf ("Parent lock failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Critical section.  */
> +  printf ("Parent locking\n");
> +  ++shrd_counter;
> +  printf ("Parent unlocking\n");
> +
> +  /* Unlock mutex.  */
> +  if (mtx_unlock (&mutex) != thrd_success)
> +  {
> +    printf ("Parent unlock error.\n");
> +    _exit (1);
> +  }
> +
> +
> +  /* Still have to wait until child is done.  */
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed.\n");
> +    _exit (1);
> +  }
> +
> +  /* Check result.  */
> +  if (shrd_counter != 2)
> +  {
> +    printf ("Counter has a wrong value.\n");
> +    _exit (1);
> +  }
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-mtx-recursive.c b/nptl/tst-mtx-recursive.c
> new file mode 100644
> index 0000000..e28faed
> --- /dev/null
> +++ b/nptl/tst-mtx-recursive.c
> @@ -0,0 +1,57 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +
> +int
> +do_test (void)
> +{
> +
> +  static mtx_t mutex;
> +
> +  /* Initialize mutex.  */
> +  mtx_init (&mutex, mtx_recursive);
> +
> +  /* Lock mutex first time.  */
> +  if (mtx_lock (&mutex) != thrd_success)
> +  {
> +    printf ("First lock failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Mutex locked once\n");
> +
> +  /* Lock mutex second time, if not recursive should deadlock.  */
> +  if (mtx_lock (&mutex) != thrd_success)
> +  {
> +    printf ("Second lock failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Mutex locked twice\n");
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  return 0;
> +}
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-mtx-timedlock.c b/nptl/tst-mtx-timedlock.c
> new file mode 100644
> index 0000000..5bfec09
> --- /dev/null
> +++ b/nptl/tst-mtx-timedlock.c
> @@ -0,0 +1,124 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Shared mutex between child and parent.  */
> +static mtx_t mutex;
> +
> +/* Shared counter to check possible race conditions.  */
> +static char shrd_counter;
> +
> +/* Maximum amount of time waiting for mutex.  */
> +static struct timespec wait_time;
> +
> +/* Function to choose an action to do, depending on mtx_timedlock
> +   return value.  */
> +static inline void
> +choose_action (int action, char* thread_name)
> +{
> +  switch (action)
> +  {
> +    case thrd_success:
> +
> +      /* Critical section.  */
> +      printf ("%s locking.\n", thread_name);
> +      ++shrd_counter;
> +      printf ("%s unlocking.\n", thread_name);
> +
> +      /* Unlock mutex.  */
> +      if (mtx_unlock (&mutex) != thrd_success)
> +      {
> +        printf ("%s unlock error.\n", thread_name);
> +        _exit (1);
> +      }
> +      break;
> +
> +    case thrd_timedout:
> +      printf ("Waiting for mutex too long, %s leaving.\n", thread_name);
> +      break;
> +
> +    case thrd_error:
> +      printf ("%s lock error.\n", thread_name);
> +      _exit (1);
> +      break;
> +  }
> +
> +}
> +
> +int
> +child_add (void)
> +{
> +  char child_name[] = "Child";
> +
> +  /* Try to lock mutex.  */
> +  choose_action (mtx_timedlock (&mutex, &wait_time), child_name);
> +  thrd_exit (thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +  thrd_t id;
> +  char parent_name[] = "Parent";
> +
> +  /* Initialize mutex.  */
> +  mtx_init (&mutex, mtx_timed);
> +
> +  /* Initialize waiting time.  */
> +  clock_gettime (CLOCK_REALTIME, &wait_time);
> +  /* Tiny amount of time, to assure that if any thread
> +     finds it busy, will receive thrd_timedout.  */
> +  wait_time.tv_nsec += 1;
> +
> +
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) child_add, NULL) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Try to lock mutex.  */
> +  choose_action (mtx_timedlock (&mutex, &wait_time), parent_name);
> +
> +  /* Still have to wait until child is done.  */
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed.\n");
> +    _exit (1);
> +  }
> +
> +  /* Check result.  */
> +  if (shrd_counter != 2 && shrd_counter != 1)
> +  {
> +    printf ("Counter has a wrong value: %i.\n", shrd_counter);
> +    _exit (1);
> +  }
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-mtx-trylock.c b/nptl/tst-mtx-trylock.c
> new file mode 100644
> index 0000000..fa75066
> --- /dev/null
> +++ b/nptl/tst-mtx-trylock.c
> @@ -0,0 +1,114 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Shared mutex between child and parent.  */
> +static mtx_t mutex;
> +
> +/* Shared counter to check possible race conditions.  */
> +static char shrd_counter;
> +
> +/* Function to choose an action to do, depending on mtx_trylock
> +   return value.  */
> +static inline void
> +choose_action (int action, char* thread_name)
> +{
> +  switch (action)
> +  {
> +    case thrd_success:
> +
> +      /* Critical section.  */
> +      printf ("%s locking\n", thread_name);
> +      ++shrd_counter;
> +      printf ("%s unlocking\n", thread_name);
> +
> +      /* Unlock mutex.  */
> +      if (mtx_unlock (&mutex) != thrd_success)
> +      {
> +        printf ("%s unlock error.\n", thread_name);
> +        _exit (1);
> +      }
> +      break;
> +
> +    case thrd_busy:
> +      printf ("Mutex is taken, %s leaving.\n", thread_name);
> +      break;
> +
> +    case thrd_error:
> +      printf ("%s lock error.\n", thread_name);
> +      _exit (1);
> +      break;
> +  }
> +
> +}
> +
> +int
> +child_add (void)
> +{
> +  char child_name[] = "Child";
> +
> +  /* Try to lock mutex.  */
> +  choose_action (mtx_trylock (&mutex), child_name);
> +
> +  thrd_exit(thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +  thrd_t id;
> +  char parent_name[] = "Parent";
> +
> +  /* Initialize mutex.  */
> +  mtx_init (&mutex, mtx_plain);
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) child_add, NULL) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  /* Try to lock mutex.  */
> +  choose_action (mtx_trylock (&mutex), parent_name);
> +
> +  /* Still have to wait until child is done.  */
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed.\n");
> +    _exit (1);
> +  }
> +
> +  /* Check result.  */
> +  if (shrd_counter != 2 && shrd_counter != 1)
> +  {
> +    printf ("Counter has a wrong value: %i.\n", shrd_counter);
> +    _exit (1);
> +  }
> +
> +  /* Destroy mutex.  */
> +  mtx_destroy (&mutex);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-thrd-basic.c b/nptl/tst-thrd-basic.c
> new file mode 100644
> index 0000000..53e0888
> --- /dev/null
> +++ b/nptl/tst-thrd-basic.c
> @@ -0,0 +1,63 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +
> +int
> +print_id (void *parent_id)
> +{
> +  printf ("Thread ID: %lu, Parent ID: %lu\n", thrd_current (),
> +       (thrd_t) parent_id);
> +  thrd_exit (thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +  int ret_val;
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, print_id, (void *) thrd_current ()) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Created thread\n");
> +
> +
> +  if (thrd_join (id, &ret_val) != thrd_success)
> +  {
> +    printf ("Join failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Joined thread\n");
> +
> +  printf ("Child returned %u\n", ret_val);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-thrd-detach.c b/nptl/tst-thrd-detach.c
> new file mode 100644
> index 0000000..ca0d7b0
> --- /dev/null
> +++ b/nptl/tst-thrd-detach.c
> @@ -0,0 +1,61 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <time.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +
> +int
> +dtch_thrd (void)
> +{
> +
> +  if (thrd_detach (thrd_current ()) != thrd_success)
> +  {
> +    printf ("Detach failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Succesfully detached\n");
> +
> +  return 0;
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) dtch_thrd, NULL) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Created thread\n");
> +
> +  thrd_sleep (&(struct timespec){.tv_sec = 2}, NULL);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-thrd-sleep.c b/nptl/tst-thrd-sleep.c
> new file mode 100644
> index 0000000..8557c6b
> --- /dev/null
> +++ b/nptl/tst-thrd-sleep.c
> @@ -0,0 +1,71 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <time.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +
> +int
> +go_to_sleep (struct timespec const *tl)
> +{
> +
> +  printf ("Time before sleeping: %s", ctime (&(time_t){time(NULL)}));
> +  if (thrd_sleep (tl, NULL) != 0)
> +  {
> +    printf ("Sleep failed\n");
> +    _exit (1);
> +  }
> +  printf ("Time after sleeping: %s", ctime (&(time_t){time(NULL)}));
> +
> +  return 0;
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +  /* Wait for 3 seconds.  */
> +  struct timespec wait_time = {.tv_sec = 3};
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, (thrd_start_t) go_to_sleep,
> +        (void *) (&wait_time)) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Created thread\n");
> +
> +
> +  if (thrd_join (id, NULL) != thrd_success)
> +  {
> +    printf ("Join failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Joined thread\n");
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> diff --git a/nptl/tst-tss-basic.c b/nptl/tst-tss-basic.c
> new file mode 100644
> index 0000000..0064c63
> --- /dev/null
> +++ b/nptl/tst-tss-basic.c
> @@ -0,0 +1,70 @@
> +/* Copyright (C) 2015 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <threads.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +/* Thread specific storage.  */
> +tss_t key;
> +
> +int
> +print_id (void *val)
> +{
> +  tss_create (&key, NULL);
> +  tss_set (key, (void *) 0xff);
> +  printf ("Child key: %u\n", key);
> +  printf ("Child value: %p\n", tss_get (key));
> +
> +
> +  thrd_exit(thrd_success);
> +}
> +
> +int
> +do_test (void)
> +{
> +
> +  thrd_t id;
> +  int ret_val;
> +
> +  /* Create new thread.  */
> +  if (thrd_create (&id, print_id, NULL) != thrd_success)
> +  {
> +    printf ("Create failed\n");
> +    _exit (1);
> +  }
> +
> +  if (thrd_join (id, &ret_val) != thrd_success)
> +  {
> +    printf ("Join failed\n");
> +    _exit (1);
> +  }
> +  else
> +    printf ("Joined thread\n");
> +
> +  /* We check parent has the same key value, but
> +     no value, because was not assigned.  */
> +  printf ("Parent key: %u\n", key);
> +  printf ("Parent value: %p\n", tss_get (key));
> +  tss_delete (key);
> +
> +  return 0;
> +}
> +
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> --
> 2.4.3
diff mbox

Patch

diff --git a/nptl/Makefile b/nptl/Makefile
index 9c3ffb8..4a88816 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -292,7 +292,12 @@  tests = tst-typesizes \
 	tst-getpid3 \
 	tst-setuid3 \
 	tst-initializers1 $(addprefix tst-initializers1-,c89 gnu89 c99 gnu99) \
-	tst-bad-schedattr
+	tst-bad-schedattr \
+	tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
+	tst-thrd-basic tst-cnd-timedwait tst-thrd-detach \
+	tst-mtx-basic tst-thrd-sleep tst-mtx-recursive tst-tss-basic \
+	tst-call-once tst-mtx-timedlock
+
 xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
 	tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
 test-srcs = tst-oddstacklimit
diff --git a/nptl/tst-call-once.c b/nptl/tst-call-once.c
new file mode 100644
index 0000000..9eeb5c2
--- /dev/null
+++ b/nptl/tst-call-once.c
@@ -0,0 +1,77 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+/* Flag that controls the first thread access.  */
+static once_flag flag = ONCE_FLAG_INIT;
+
+/* Function called only once.  */
+void
+do_once (void)
+{
+  printf ("Called once\n");
+}
+
+/* Code executed by each thread.  */
+int
+func (void* data)
+{
+  call_once (&flag, do_once);
+  thrd_exit(thrd_success);
+}
+
+
+#define N 20
+
+int
+do_test (void)
+{
+
+  thrd_t ids[N];
+  unsigned char i;
+
+
+  /* Create N new threads.  */
+  for (i = 0; i < N; ++i)
+  {
+    if (thrd_create (&ids[i], func, NULL) != thrd_success)
+    {
+      printf ("Create failed\n");
+      _exit (1);
+    }
+  }
+
+  /* Join threads.  */
+  for (i = 0; i < N; ++i)
+  {
+    if (thrd_join (ids[i], NULL) != thrd_success)
+    {
+      printf ("Join failed\n");
+      _exit (1);
+    }
+  }
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-cnd-basic.c b/nptl/tst-cnd-basic.c
new file mode 100644
index 0000000..8e72051
--- /dev/null
+++ b/nptl/tst-cnd-basic.c
@@ -0,0 +1,92 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Shared condition variable between child and parent.  */
+static cnd_t cond;
+
+/* Mutex needed to signal and wait threads.  */
+static mtx_t mutex;
+
+int
+signal_parent (void)
+{
+  /* Send signal to parent.  */
+  printf ("Child signaling\n");
+  if (cnd_signal (&cond) != thrd_success)
+  {
+    printf ("Child signal error.\n");
+    _exit (1);
+  }
+
+  thrd_exit (thrd_success);
+}
+
+int
+do_test (void)
+{
+
+  thrd_t id;
+
+  /* Initialize cond and mutex.  */
+  if (cnd_init (&cond) != thrd_success
+      || mtx_init (&mutex, mtx_plain) != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+
+  /* Create new thread.  */
+  if (thrd_create (&id, (thrd_start_t) signal_parent, NULL)
+       != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+
+  /* Wait on cond, until child thread signals.  */
+  if (cnd_wait (&cond, &mutex) != thrd_success)
+  {
+    printf ("Parent lock failed\n");
+    _exit (1);
+  }
+  printf ("Parent received signal, continuing\n");
+
+  /* Joining is not mandatory here, but still done
+     to assure child thread ends correctly..  */
+  if (thrd_join (id, NULL) != thrd_success)
+  {
+    printf ("Join failed.\n");
+    _exit (1);
+  }
+
+
+  /* Destroy mutex.  */
+  mtx_destroy (&mutex);
+
+  /* Destroy cond.  */
+  cnd_destroy (&cond);
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-cnd-broadcast.c b/nptl/tst-cnd-broadcast.c
new file mode 100644
index 0000000..b93c9a9
--- /dev/null
+++ b/nptl/tst-cnd-broadcast.c
@@ -0,0 +1,95 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Condition variable where child threads will wait.  */
+cnd_t cond;
+
+/* Mutex to control wait on cond.  */
+mtx_t mutex;
+
+/* Code executed by each thread.  */
+int
+child_wait (void* data)
+{
+  printf ("Arrived\n");
+  /* Wait until parent thread sends broadcast here.  */
+  mtx_lock (&mutex);
+  cnd_wait (&cond, &mutex);
+  mtx_unlock (&mutex);
+
+  printf ("Freed thread\n");
+  thrd_exit (thrd_success);
+}
+
+#define N 5
+
+int
+do_test (void)
+{
+
+  thrd_t ids[N];
+  unsigned char i;
+
+  cnd_init (&cond);
+  mtx_init (&mutex, mtx_plain);
+
+  /* Create N new threads.  */
+  for (i = 0; i < N; ++i)
+  {
+    if (thrd_create (&ids[i], child_wait, NULL) != thrd_success)
+    {
+      printf ("Create failed\n");
+      _exit (1);
+    }
+  }
+
+  /* Wait for other threads to reach their wait func.  */
+  thrd_sleep (&((struct timespec){.tv_sec = 2}), NULL);
+
+  /* Send broadcast.  */
+  mtx_lock (&mutex);
+  if (cnd_broadcast (&cond) != thrd_success)
+  {
+    printf ("Broadcast error");
+    _exit (1);
+  }
+  mtx_unlock (&mutex);
+
+  /* Join threads.  */
+  for (i = 0; i < N; ++i)
+  {
+    if (thrd_join (ids[i], NULL) != thrd_success)
+    {
+      printf ("Join failed\n");
+      _exit (1);
+    }
+  }
+
+
+  mtx_destroy (&mutex);
+  cnd_destroy (&cond);
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-cnd-timedwait.c b/nptl/tst-cnd-timedwait.c
new file mode 100644
index 0000000..c8aff19
--- /dev/null
+++ b/nptl/tst-cnd-timedwait.c
@@ -0,0 +1,104 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Shared condition variable between child and parent.  */
+static cnd_t cond;
+
+/* Mutex needed to signal and wait threads.  */
+static mtx_t mutex;
+
+int
+signal_parent (void)
+{
+  /* Send signal to parent.  */
+  printf ("Child signaling\n");
+  if (cnd_signal (&cond) != thrd_success)
+  {
+    printf ("Child signal error.\n");
+    _exit (1);
+  }
+
+  //thrd_exit(thrd_success);
+  return 0;
+}
+
+int
+do_test (void)
+{
+
+  thrd_t id;
+  struct timespec w_time;
+
+  /* Initialize cond and mutex.  */
+  if (cnd_init (&cond) != thrd_success
+      || mtx_init (&mutex, mtx_timed) != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+
+  /* Initialize waiting time.  */
+  clock_gettime (CLOCK_REALTIME, &w_time);
+  w_time.tv_nsec += 150000;
+
+  /* Create new thread.  */
+  if (thrd_create (&id, (thrd_start_t) signal_parent, NULL)
+       != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+
+  /* Wait on cond, until child thread signals.  */
+  switch (cnd_timedwait (&cond, &mutex, &w_time))
+  {
+    case thrd_error:
+      printf ("Parent lock failed\n");
+      _exit (1);
+    case thrd_timedout:
+      printf ("Waiting too long, leaving\n");
+      break;
+    case thrd_success:
+      printf ("Signaled successfully,\n");
+      break;
+  }
+
+  /* Joining is not mandatory here, but still done
+     to assure child thread ends correctly..  */
+  if (thrd_join (id, NULL) != thrd_success)
+  {
+    printf ("Join failed.\n");
+    _exit (1);
+  }
+
+
+  /* Destroy mutex.  */
+  mtx_destroy (&mutex);
+
+  /* Destroy cond.  */
+  cnd_destroy (&cond);
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-mtx-basic.c b/nptl/tst-mtx-basic.c
new file mode 100644
index 0000000..ea7fdc6
--- /dev/null
+++ b/nptl/tst-mtx-basic.c
@@ -0,0 +1,112 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Shared mutex between child and parent.  */
+static mtx_t mutex;
+
+/* Shared counter to check possible race conditions.  */
+static char shrd_counter;
+
+int
+child_add (void)
+{
+  /* Lock mutex.  */
+  if (mtx_lock (&mutex) != thrd_success)
+  {
+    printf ("Child lock error.\n");
+    _exit (1);
+  }
+
+  /* Critical section.  */
+  printf ("Child locking\n");
+  ++shrd_counter;
+  printf ("Child unlocking\n");
+
+  /* Unlock mutex.  */
+  if (mtx_unlock (&mutex) != thrd_success)
+  {
+    printf ("Child unlock error.\n");
+    _exit (1);
+  }
+  thrd_exit (thrd_success);
+}
+
+int
+do_test (void)
+{
+
+  thrd_t id;
+
+  /* Initialize mutex.  */
+  mtx_init (&mutex, mtx_plain);
+
+  /* Create new thread.  */
+  if (thrd_create (&id, (thrd_start_t) child_add, NULL) != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+  else
+    printf ("Created thread\n");
+
+
+  if (mtx_lock (&mutex) != thrd_success)
+  {
+    printf ("Parent lock failed\n");
+    _exit (1);
+  }
+
+  /* Critical section.  */
+  printf ("Parent locking\n");
+  ++shrd_counter;
+  printf ("Parent unlocking\n");
+
+  /* Unlock mutex.  */
+  if (mtx_unlock (&mutex) != thrd_success)
+  {
+    printf ("Parent unlock error.\n");
+    _exit (1);
+  }
+
+
+  /* Still have to wait until child is done.  */
+  if (thrd_join (id, NULL) != thrd_success)
+  {
+    printf ("Join failed.\n");
+    _exit (1);
+  }
+
+  /* Check result.  */
+  if (shrd_counter != 2)
+  {
+    printf ("Counter has a wrong value.\n");
+    _exit (1);
+  }
+
+  /* Destroy mutex.  */
+  mtx_destroy (&mutex);
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-mtx-recursive.c b/nptl/tst-mtx-recursive.c
new file mode 100644
index 0000000..e28faed
--- /dev/null
+++ b/nptl/tst-mtx-recursive.c
@@ -0,0 +1,57 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+int
+do_test (void)
+{
+
+  static mtx_t mutex;
+
+  /* Initialize mutex.  */
+  mtx_init (&mutex, mtx_recursive);
+
+  /* Lock mutex first time.  */
+  if (mtx_lock (&mutex) != thrd_success)
+  {
+    printf ("First lock failed\n");
+    _exit (1);
+  }
+  else
+    printf ("Mutex locked once\n");
+
+  /* Lock mutex second time, if not recursive should deadlock.  */
+  if (mtx_lock (&mutex) != thrd_success)
+  {
+    printf ("Second lock failed\n");
+    _exit (1);
+  }
+  else
+    printf ("Mutex locked twice\n");
+
+  /* Destroy mutex.  */
+  mtx_destroy (&mutex);
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-mtx-timedlock.c b/nptl/tst-mtx-timedlock.c
new file mode 100644
index 0000000..5bfec09
--- /dev/null
+++ b/nptl/tst-mtx-timedlock.c
@@ -0,0 +1,124 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Shared mutex between child and parent.  */
+static mtx_t mutex;
+
+/* Shared counter to check possible race conditions.  */
+static char shrd_counter;
+
+/* Maximum amount of time waiting for mutex.  */
+static struct timespec wait_time;
+
+/* Function to choose an action to do, depending on mtx_timedlock
+   return value.  */
+static inline void
+choose_action (int action, char* thread_name)
+{
+  switch (action)
+  {
+    case thrd_success:
+
+      /* Critical section.  */
+      printf ("%s locking.\n", thread_name);
+      ++shrd_counter;
+      printf ("%s unlocking.\n", thread_name);
+
+      /* Unlock mutex.  */
+      if (mtx_unlock (&mutex) != thrd_success)
+      {
+        printf ("%s unlock error.\n", thread_name);
+        _exit (1);
+      }
+      break;
+
+    case thrd_timedout:
+      printf ("Waiting for mutex too long, %s leaving.\n", thread_name);
+      break;
+
+    case thrd_error:
+      printf ("%s lock error.\n", thread_name);
+      _exit (1);
+      break;
+  }
+
+}
+
+int
+child_add (void)
+{
+  char child_name[] = "Child";
+
+  /* Try to lock mutex.  */
+  choose_action (mtx_timedlock (&mutex, &wait_time), child_name);
+  thrd_exit (thrd_success);
+}
+
+int
+do_test (void)
+{
+  thrd_t id;
+  char parent_name[] = "Parent";
+
+  /* Initialize mutex.  */
+  mtx_init (&mutex, mtx_timed);
+
+  /* Initialize waiting time.  */
+  clock_gettime (CLOCK_REALTIME, &wait_time);
+  /* Tiny amount of time, to assure that if any thread
+     finds it busy, will receive thrd_timedout.  */
+  wait_time.tv_nsec += 1;
+
+
+
+  /* Create new thread.  */
+  if (thrd_create (&id, (thrd_start_t) child_add, NULL) != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+
+  /* Try to lock mutex.  */
+  choose_action (mtx_timedlock (&mutex, &wait_time), parent_name);
+
+  /* Still have to wait until child is done.  */
+  if (thrd_join (id, NULL) != thrd_success)
+  {
+    printf ("Join failed.\n");
+    _exit (1);
+  }
+
+  /* Check result.  */
+  if (shrd_counter != 2 && shrd_counter != 1)
+  {
+    printf ("Counter has a wrong value: %i.\n", shrd_counter);
+    _exit (1);
+  }
+
+  /* Destroy mutex.  */
+  mtx_destroy (&mutex);
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-mtx-trylock.c b/nptl/tst-mtx-trylock.c
new file mode 100644
index 0000000..fa75066
--- /dev/null
+++ b/nptl/tst-mtx-trylock.c
@@ -0,0 +1,114 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Shared mutex between child and parent.  */
+static mtx_t mutex;
+
+/* Shared counter to check possible race conditions.  */
+static char shrd_counter;
+
+/* Function to choose an action to do, depending on mtx_trylock
+   return value.  */
+static inline void
+choose_action (int action, char* thread_name)
+{
+  switch (action)
+  {
+    case thrd_success:
+
+      /* Critical section.  */
+      printf ("%s locking\n", thread_name);
+      ++shrd_counter;
+      printf ("%s unlocking\n", thread_name);
+
+      /* Unlock mutex.  */
+      if (mtx_unlock (&mutex) != thrd_success)
+      {
+        printf ("%s unlock error.\n", thread_name);
+        _exit (1);
+      }
+      break;
+
+    case thrd_busy:
+      printf ("Mutex is taken, %s leaving.\n", thread_name);
+      break;
+
+    case thrd_error:
+      printf ("%s lock error.\n", thread_name);
+      _exit (1);
+      break;
+  }
+
+}
+
+int
+child_add (void)
+{
+  char child_name[] = "Child";
+
+  /* Try to lock mutex.  */
+  choose_action (mtx_trylock (&mutex), child_name);
+
+  thrd_exit(thrd_success);
+}
+
+int
+do_test (void)
+{
+  thrd_t id;
+  char parent_name[] = "Parent";
+
+  /* Initialize mutex.  */
+  mtx_init (&mutex, mtx_plain);
+
+  /* Create new thread.  */
+  if (thrd_create (&id, (thrd_start_t) child_add, NULL) != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+
+  /* Try to lock mutex.  */
+  choose_action (mtx_trylock (&mutex), parent_name);
+
+  /* Still have to wait until child is done.  */
+  if (thrd_join (id, NULL) != thrd_success)
+  {
+    printf ("Join failed.\n");
+    _exit (1);
+  }
+
+  /* Check result.  */
+  if (shrd_counter != 2 && shrd_counter != 1)
+  {
+    printf ("Counter has a wrong value: %i.\n", shrd_counter);
+    _exit (1);
+  }
+
+  /* Destroy mutex.  */
+  mtx_destroy (&mutex);
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-thrd-basic.c b/nptl/tst-thrd-basic.c
new file mode 100644
index 0000000..53e0888
--- /dev/null
+++ b/nptl/tst-thrd-basic.c
@@ -0,0 +1,63 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+int
+print_id (void *parent_id)
+{
+  printf ("Thread ID: %lu, Parent ID: %lu\n", thrd_current (),
+	(thrd_t) parent_id);
+  thrd_exit (thrd_success);
+}
+
+int
+do_test (void)
+{
+
+  thrd_t id;
+  int ret_val;
+
+  /* Create new thread.  */
+  if (thrd_create (&id, print_id, (void *) thrd_current ()) != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+  else
+    printf ("Created thread\n");
+
+
+  if (thrd_join (id, &ret_val) != thrd_success)
+  {
+    printf ("Join failed\n");
+    _exit (1);
+  }
+  else
+    printf ("Joined thread\n");
+
+  printf ("Child returned %u\n", ret_val);
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-thrd-detach.c b/nptl/tst-thrd-detach.c
new file mode 100644
index 0000000..ca0d7b0
--- /dev/null
+++ b/nptl/tst-thrd-detach.c
@@ -0,0 +1,61 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <time.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+int
+dtch_thrd (void)
+{
+
+  if (thrd_detach (thrd_current ()) != thrd_success)
+  {
+    printf ("Detach failed\n");
+    _exit (1);
+  }
+  else
+    printf ("Succesfully detached\n");
+
+  return 0;
+}
+
+int
+do_test (void)
+{
+
+  thrd_t id;
+
+  /* Create new thread.  */
+  if (thrd_create (&id, (thrd_start_t) dtch_thrd, NULL) != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+  else
+    printf ("Created thread\n");
+
+  thrd_sleep (&(struct timespec){.tv_sec = 2}, NULL);
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-thrd-sleep.c b/nptl/tst-thrd-sleep.c
new file mode 100644
index 0000000..8557c6b
--- /dev/null
+++ b/nptl/tst-thrd-sleep.c
@@ -0,0 +1,71 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <time.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+int
+go_to_sleep (struct timespec const *tl)
+{
+
+  printf ("Time before sleeping: %s", ctime (&(time_t){time(NULL)}));
+  if (thrd_sleep (tl, NULL) != 0)
+  {
+    printf ("Sleep failed\n");
+    _exit (1);
+  }
+  printf ("Time after sleeping: %s", ctime (&(time_t){time(NULL)}));
+
+  return 0;
+}
+
+int
+do_test (void)
+{
+
+  thrd_t id;
+  /* Wait for 3 seconds.  */
+  struct timespec wait_time = {.tv_sec = 3};
+
+  /* Create new thread.  */
+  if (thrd_create (&id, (thrd_start_t) go_to_sleep,
+        (void *) (&wait_time)) != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+  else
+    printf ("Created thread\n");
+
+
+  if (thrd_join (id, NULL) != thrd_success)
+  {
+    printf ("Join failed\n");
+    _exit (1);
+  }
+  else
+    printf ("Joined thread\n");
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-tss-basic.c b/nptl/tst-tss-basic.c
new file mode 100644
index 0000000..0064c63
--- /dev/null
+++ b/nptl/tst-tss-basic.c
@@ -0,0 +1,70 @@ 
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Thread specific storage.  */
+tss_t key;
+
+int
+print_id (void *val)
+{
+  tss_create (&key, NULL);
+  tss_set (key, (void *) 0xff);
+  printf ("Child key: %u\n", key);
+  printf ("Child value: %p\n", tss_get (key));
+
+
+  thrd_exit(thrd_success);
+}
+
+int
+do_test (void)
+{
+
+  thrd_t id;
+  int ret_val;
+
+  /* Create new thread.  */
+  if (thrd_create (&id, print_id, NULL) != thrd_success)
+  {
+    printf ("Create failed\n");
+    _exit (1);
+  }
+
+  if (thrd_join (id, &ret_val) != thrd_success)
+  {
+    printf ("Join failed\n");
+    _exit (1);
+  }
+  else
+    printf ("Joined thread\n");
+
+  /* We check parent has the same key value, but
+     no value, because was not assigned.  */
+  printf ("Parent key: %u\n", key);
+  printf ("Parent value: %p\n", tss_get (key));
+  tss_delete (key);
+
+  return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"