Files

90 lines
2.3 KiB
C
Raw Permalink Normal View History

2026-05-31 14:34:00 -04:00
#include <assert.h>
#include <inttypes.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
// Use the struct here for passing arguments to the runner() threads.
// All instances of this struct should point to the same pthread_mutex_t
// and shared variables.
typedef struct args {
pthread_mutex_t *lock;
int64_t *shared;
} arg_t;
/* Function to run in concurrent threads. The argument passed should be a
pointer to a pthread_mutex_t to be used for mutual exclusion. Within the
nested for-loop structure, use the mutex to protect the the increments
and decrements of the shared variable. To get the timing right for the
unit tests, experiment with placing the lock/unlock calls in different
places (e.g., around both for-loops, inside the outer one, inside the
inner one, etc.) */
void *
runner (void *arg)
{
// Retrieve the shared pointer and mutex from the passed struct.
arg_t *args = (arg_t *) arg;
pthread_mutex_t *lock = args->lock;
int64_t *shared = args->shared;
for (int j = 0; j < 1000000; j++)
{
pthread_mutex_lock (lock);
for (int i = 0; i < 100; i++)
{
*shared += 1;
*shared -= 1;
}
pthread_mutex_unlock (lock);
}
pthread_exit (NULL);
}
/* Simple fork-join routine that creates two threads running the runner()
function above. Pass the lock and a pointer to the shared variable to
both threads. When both threads complete, return the shared variable,
which should have a value of 0.
*/
int64_t
run (void)
{
int64_t shared = 0;
pthread_mutex_t lock;
if (pthread_mutex_init (&lock, NULL) != 0)
{
fprintf (stderr, "Failed to initialize mutex\n");
return shared;
}
arg_t args;
args.lock = &lock;
args.shared = &shared;
pthread_t t1, t2;
if (pthread_create (&t1, NULL, runner, &args) != 0)
{
fprintf (stderr, "Failed to create thread 1\n");
pthread_mutex_destroy (&lock);
return shared;
}
if (pthread_create (&t2, NULL, runner, &args) != 0)
{
fprintf (stderr, "Failed to create thread 2\n");
pthread_cancel (t1);
pthread_join (t1, NULL);
pthread_mutex_destroy (&lock);
return shared;
}
pthread_join (t1, NULL);
pthread_join (t2, NULL);
pthread_mutex_destroy (&lock);
return shared;
}