1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
/* t-thread.c
* Copyright 2012 g10 Code GmbH
*
* This file is free software; as a special exception the author gives
* unlimited permission to copy and/or distribute it, with or without
* modifications, as long as this notice is preserved.
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "t-support.h"
static int counter;
static npth_mutex_t counter_mutex;
static int thread_twoone_ready;
static void *
thread_one (void *arg)
{
int rc, i;
info_msg ("thread-one started");
npth_usleep (10); /* Give the other thread some time to start. */
for (i=0; i < 10; i++)
{
/* We would not need the mutex here, but we use it to allow the
system to switch to another thread. */
rc = npth_mutex_lock (&counter_mutex);
fail_if_err (rc);
counter++;
rc = npth_mutex_unlock (&counter_mutex);
fail_if_err (rc);
}
info_msg ("thread-one terminated");
return (void*)4711;
}
static void *
thread_twoone (void *arg)
{
int rc;
npth_setname_np (npth_self (), "thread-twoone");
info_msg ("thread-twoone started");
rc = npth_detach (npth_self ());
fail_if_err (rc);
while (counter < 100)
{
npth_usleep (1000);
counter++;
}
info_msg ("thread-twoone terminated");
thread_twoone_ready = 1;
return NULL;
}
static void *
thread_two (void *arg)
{
int rc, i;
info_msg ("thread-two started");
for (i=0; i < 10; i++)
{
rc = npth_mutex_lock (&counter_mutex);
fail_if_err (rc);
counter--;
if (i == 5)
{
npth_t tid;
info_msg ("creating thread-twoone");
rc = npth_create (&tid, NULL, thread_twoone, NULL);
fail_if_err (rc);
npth_usleep (10); /* Give new thread some time to start. */
}
rc = npth_mutex_unlock (&counter_mutex);
fail_if_err (rc);
}
info_msg ("busy waiting for thread twoone");
while (!thread_twoone_ready)
npth_sleep (0);
info_msg ("thread-two terminated");
return (void*)4722;
}
int
main (int argc, char *argv[])
{
int rc;
npth_attr_t tattr;
int state;
npth_t tid1, tid2;
void *retval;
if (argc >= 2 && !strcmp (argv[1], "--verbose"))
opt_verbose = 1;
rc = npth_init ();
fail_if_err (rc);
rc = npth_mutex_init (&counter_mutex, NULL);
fail_if_err (rc);
rc = npth_attr_init (&tattr);
fail_if_err (rc);
rc = npth_attr_getdetachstate (&tattr, &state);
fail_if_err (rc);
if ( state != NPTH_CREATE_JOINABLE )
fail_msg ("new tattr is not joinable");
info_msg ("creating thread-one");
rc = npth_create (&tid1, &tattr, thread_one, NULL);
fail_if_err (rc);
npth_setname_np (tid1, "thread-one");
info_msg ("creating thread-two");
rc = npth_create (&tid2, &tattr, thread_two, NULL);
fail_if_err (rc);
npth_setname_np (tid2, "thread-two");
rc = npth_attr_destroy (&tattr);
fail_if_err (rc);
info_msg ("waiting for thread-one to terminate");
rc = npth_join (tid1, &retval);
fail_if_err (rc);
if (retval != (void*)4711)
fail_msg ("thread-one returned an unexpected value");
info_msg ("waiting for thread-two to terminate");
rc = npth_join (tid2, &retval);
fail_if_err (rc);
if (retval != (void*)4722)
fail_msg ("thread-two returned an unexpected value");
if (counter != 100)
fail_msg ("counter value not as expected");
return 0;
}
|