mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-08 16:36:21 +00:00
106 lines
2.1 KiB
C
106 lines
2.1 KiB
C
/* Use a semaphore to implement mutual exclusion. */
|
|
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h> /* printf() */
|
|
#include <pthread.h>
|
|
#include <semaphore.h>
|
|
#include <unistd.h> /* sleep() */
|
|
|
|
|
|
/* Local functions declarations. */
|
|
|
|
static void* thread_func(void*);
|
|
|
|
|
|
/* Local variables. */
|
|
|
|
/* s_sem protects s_d3. */
|
|
static sem_t s_sem;
|
|
|
|
static double s_d1; /* accessed before thread creation and in the created */
|
|
/* thread (not a race). */
|
|
static double s_d2; /* accessed in the created thread and after the join */
|
|
/* (not a race). */
|
|
static double s_d3; /* accessed simultaneously from both threads (race). */
|
|
static int s_debug = 0;
|
|
static int s_do_printf = 0;
|
|
static int s_do_mutual_exclusion = 0;
|
|
|
|
|
|
/* Function definitions. */
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
int optchar;
|
|
pthread_t threadid;
|
|
|
|
while ((optchar = getopt(argc, argv, "dmp")) != EOF)
|
|
{
|
|
switch (optchar)
|
|
{
|
|
case 'd':
|
|
s_debug = 1;
|
|
break;
|
|
case 'm':
|
|
s_do_mutual_exclusion = 1;
|
|
break;
|
|
case 'p':
|
|
s_do_printf = 1;
|
|
break;
|
|
default:
|
|
assert(0);
|
|
}
|
|
}
|
|
|
|
sem_init(&s_sem, 0, 1);
|
|
|
|
/*
|
|
* Switch to line-buffered mode, such that timing information can be
|
|
* obtained for each printf() call with strace.
|
|
*/
|
|
setlinebuf(stdout);
|
|
|
|
if (s_debug)
|
|
{
|
|
printf("&s_d1 = %p; &s_d2 = %p; &s_d3 = %p\n", &s_d1, &s_d2, &s_d3);
|
|
}
|
|
|
|
s_d1 = 1;
|
|
s_d3 = 3;
|
|
|
|
pthread_create(&threadid, 0, thread_func, 0);
|
|
|
|
sleep(1); /* Wait until thread_func() finished. */
|
|
|
|
{
|
|
if (s_do_mutual_exclusion) sem_wait(&s_sem);
|
|
s_d3++;
|
|
if (s_do_mutual_exclusion) sem_post(&s_sem);
|
|
}
|
|
|
|
/* Wait until the thread finished. */
|
|
pthread_join(threadid, 0);
|
|
if (s_do_printf) printf("s_d2 = %g (should be 2)\n", s_d2);
|
|
if (s_do_printf) printf("s_d3 = %g (should be 5)\n", s_d3);
|
|
|
|
sem_destroy(&s_sem);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void* thread_func(void* thread_arg)
|
|
{
|
|
if (s_do_printf)
|
|
{
|
|
printf("s_d1 = %g (should be 1)\n", s_d1);
|
|
}
|
|
s_d2 = 2;
|
|
{
|
|
if (s_do_mutual_exclusion) sem_wait(&s_sem);
|
|
s_d3++;
|
|
if (s_do_mutual_exclusion) sem_post(&s_sem);
|
|
}
|
|
return 0;
|
|
}
|