Message ID | 1440515272-9453-6-git-send-email-j.m.torrespalma@gmail.com |
---|---|
State | New |
Headers | show |
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
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 --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"