Skip to content

Instantly share code, notes, and snippets.

Created June 16, 2012 19:56
Show Gist options
  • Save anonymous/2942372 to your computer and use it in GitHub Desktop.
Save anonymous/2942372 to your computer and use it in GitHub Desktop.
stdin
/*!
* \file
* Author: Markus J. Kusano
*
* A small program recreating a bug found in SPLASH-2
*
* See README for more information
*/
#include <pthread.h>
#include <stdio.h>
/* Comment out to remove debugging messages and calls to sleep() to attempt to
* force the bug */
#define DEBUG
#ifdef DEBUG
#include <unistd.h>
#endif
/*!
* ID ``pool''. Threads in the worker() function obtain their local id from
* this variable.
*
* \sa worker()
*/
int gid;
/*!
* Variable where the result is stored. The program does not do any actual
* work. Result is initialized to zero by main(). The thread with myid == 0 in
* the worker() function will store the variable local to worker() data into
* result.
*
* \sa worker()
*/
int result;
/*!
* Lock that synchronizes read/write access to gid variable.
*/
pthread_mutex_t gidLock = PTHREAD_MUTEX_INITIALIZER;
/*!
* A function that emulates work being done from SPLASH-2. Each thread is given
* local id, myid. myid is generated by assigning the current value of gid to
* myid and then incrementing gid. The operation is protected by gidLock.
*
* \param arg Unused
*/
void *worker(void *arg);
void *worker(void *arg) {
#ifdef DEBUG
printf("Entered worker function\n");
#endif
int myid;
int data = 999;
pthread_mutex_lock(&gidLock);
myid = gid;
gid++;
#ifdef DEBUG
printf("myid == %d\n", myid);
#endif
pthread_mutex_unlock(&gidLock);
/* work */
if (myid == 0) {
#ifdef DEBUG
printf("Sleeping since myid == 0\n");
sleep(1);
#endif
result = data;
}
return NULL;
}
/*!
* Globals (gid and result) are initialized to 0. Two threads are created (t1
* and t2) that spawn in the worker() function. The main() thread then waits
* for the second thread to return by calling pthread_join().
*
* It was first attempted to have the main thread enter the worker function
* after creating one child worker() thread. This seemed to stall the main()
* thread for some reason. It was not discovered why this occured.
*
* After thread2 (t2) returns, the main thread stores the value of global
* variable result into local variable tmp and then prints temp using printf().
*
* There is assumed atomicity in one of the worker functions (the one with myid
* == 0) will have stored the data into result. If t2 finishes before t1 and
* main prints out the result, there is a chance that result will still have
* the initialized value of 0.
*
* The thread with myid == 0 sets result to 999 to simulate doing work.
*/
int main() {
pthread_t t1, t2;
int tmp;
/* initialize globals */
gid = 0;
result = 0;
pthread_create(&t1, NULL, worker, NULL);
pthread_create(&t2, NULL, worker, NULL);
pthread_join(t2, NULL);
#ifdef DEBUG
printf("Parent thread exited worker function\n");
#endif
tmp = result;
printf("%d\n", tmp);
pthread_exit((void *) 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment