|
Packit |
5e354d |
/* t-thread.c
|
|
Packit |
5e354d |
* Copyright 2012 g10 Code GmbH
|
|
Packit |
5e354d |
*
|
|
Packit |
5e354d |
* This file is free software; as a special exception the author gives
|
|
Packit |
5e354d |
* unlimited permission to copy and/or distribute it, with or without
|
|
Packit |
5e354d |
* modifications, as long as this notice is preserved.
|
|
Packit |
5e354d |
*
|
|
Packit |
5e354d |
* This file is distributed in the hope that it will be useful, but
|
|
Packit |
5e354d |
* WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
|
Packit |
5e354d |
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
Packit |
5e354d |
*/
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
#include "t-support.h"
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
static int counter;
|
|
Packit |
5e354d |
static npth_mutex_t counter_mutex;
|
|
Packit |
5e354d |
static int thread_twoone_ready;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
static void *
|
|
Packit |
5e354d |
thread_one (void *arg)
|
|
Packit |
5e354d |
{
|
|
Packit |
5e354d |
int rc, i;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
info_msg ("thread-one started");
|
|
Packit |
5e354d |
npth_usleep (10); /* Give the other thread some time to start. */
|
|
Packit |
5e354d |
for (i=0; i < 10; i++)
|
|
Packit |
5e354d |
{
|
|
Packit |
5e354d |
/* We would not need the mutex here, but we use it to allow the
|
|
Packit |
5e354d |
system to switch to another thread. */
|
|
Packit |
5e354d |
rc = npth_mutex_lock (&counter_mutex);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
counter++;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
rc = npth_mutex_unlock (&counter_mutex);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
}
|
|
Packit |
5e354d |
info_msg ("thread-one terminated");
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
return (void*)4711;
|
|
Packit |
5e354d |
}
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
static void *
|
|
Packit |
5e354d |
thread_twoone (void *arg)
|
|
Packit |
5e354d |
{
|
|
Packit |
5e354d |
int rc, i;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
npth_setname_np (npth_self (), "thread-twoone");
|
|
Packit |
5e354d |
info_msg ("thread-twoone started");
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
rc = npth_detach (npth_self ());
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
while (counter < 100)
|
|
Packit |
5e354d |
{
|
|
Packit |
5e354d |
npth_usleep (1000);
|
|
Packit |
5e354d |
counter++;
|
|
Packit |
5e354d |
}
|
|
Packit |
5e354d |
info_msg ("thread-twoone terminated");
|
|
Packit |
5e354d |
thread_twoone_ready = 1;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
return NULL;
|
|
Packit |
5e354d |
}
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
static void *
|
|
Packit |
5e354d |
thread_two (void *arg)
|
|
Packit |
5e354d |
{
|
|
Packit |
5e354d |
int rc, i;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
info_msg ("thread-two started");
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
for (i=0; i < 10; i++)
|
|
Packit |
5e354d |
{
|
|
Packit |
5e354d |
rc = npth_mutex_lock (&counter_mutex);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
counter--;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
if (i == 5)
|
|
Packit |
5e354d |
{
|
|
Packit |
5e354d |
npth_t tid;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
info_msg ("creating thread-twoone");
|
|
Packit |
5e354d |
rc = npth_create (&tid, NULL, thread_twoone, NULL);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
npth_usleep (10); /* Give new thread some time to start. */
|
|
Packit |
5e354d |
}
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
rc = npth_mutex_unlock (&counter_mutex);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
}
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
info_msg ("busy waiting for thread twoone");
|
|
Packit |
5e354d |
while (!thread_twoone_ready)
|
|
Packit |
5e354d |
npth_sleep (0);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
info_msg ("thread-two terminated");
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
return (void*)4722;
|
|
Packit |
5e354d |
}
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
int
|
|
Packit |
5e354d |
main (int argc, char *argv[])
|
|
Packit |
5e354d |
{
|
|
Packit |
5e354d |
int rc;
|
|
Packit |
5e354d |
npth_attr_t tattr;
|
|
Packit |
5e354d |
int state;
|
|
Packit |
5e354d |
npth_t tid1, tid2;
|
|
Packit |
5e354d |
void *retval;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
if (argc >= 2 && !strcmp (argv[1], "--verbose"))
|
|
Packit |
5e354d |
opt_verbose = 1;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
rc = npth_init ();
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
rc = npth_mutex_init (&counter_mutex, NULL);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
rc = npth_attr_init (&tattr);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
rc = npth_attr_getdetachstate (&tattr, &state);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
if ( state != NPTH_CREATE_JOINABLE )
|
|
Packit |
5e354d |
fail_msg ("new tattr is not joinable");
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
info_msg ("creating thread-one");
|
|
Packit |
5e354d |
rc = npth_create (&tid1, &tattr, thread_one, NULL);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
npth_setname_np (tid1, "thread-one");
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
info_msg ("creating thread-two");
|
|
Packit |
5e354d |
rc = npth_create (&tid2, &tattr, thread_two, NULL);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
npth_setname_np (tid2, "thread-two");
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
rc = npth_attr_destroy (&tattr);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
info_msg ("waiting for thread-one to terminate");
|
|
Packit |
5e354d |
rc = npth_join (tid1, &retval);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
if (retval != (void*)4711)
|
|
Packit |
5e354d |
fail_msg ("thread-one returned an unexpected value");
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
info_msg ("waiting for thread-two to terminate");
|
|
Packit |
5e354d |
rc = npth_join (tid2, &retval);
|
|
Packit |
5e354d |
fail_if_err (rc);
|
|
Packit |
5e354d |
if (retval != (void*)4722)
|
|
Packit |
5e354d |
fail_msg ("thread-two returned an unexpected value");
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
if (counter != 100)
|
|
Packit |
5e354d |
fail_msg ("counter value not as expected");
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
return 0;
|
|
Packit |
5e354d |
}
|