summaryrefslogtreecommitdiff
path: root/lab08/mutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'lab08/mutex.c')
-rw-r--r--lab08/mutex.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/lab08/mutex.c b/lab08/mutex.c
new file mode 100644
index 0000000..7015569
--- /dev/null
+++ b/lab08/mutex.c
@@ -0,0 +1,212 @@
+/* Example code to demonstrate behavior of multi-core, threaded application
+ *
+ * Written by: Mike Anderson
+ * The PTR Group, Inc.
+ * mike@theptrgroup.com
+ *
+ * License: GPLv2
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <signal.h>
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+
+pthread_mutex_t mutex_fix; /* protect the critical region */
+
+pthread_t looperThId;
+pthread_t conflictThId;
+
+volatile int value1;
+volatile int value2;
+volatile int counter = 0;
+volatile int bTimeToExit = FALSE;
+
+int bUseMutex = FALSE; /* The "s" option */
+
+
+/* Conflict thread */
+void *conflictTh(void *arg)
+{
+ int same;
+ unsigned long loopCount = 0;
+ struct timespec sleep_time = {
+ .tv_sec = 0,
+ .tv_nsec = 7 * 1000 * 1000,
+ };
+
+ while (!bTimeToExit) {
+ if (bUseMutex) {
+ // Acquire mutex using pthread_mutex_lock(3p)
+ }
+
+ same = (value1 == value2);
+ if (!same)
+ printf("\nHey! value1 = %d, value2 = %d\n", value1,
+ value2);
+
+ loopCount++;
+ if ((loopCount % 1000) == 0) {
+ printf("\nConflict thread Counter = %lu \n", loopCount);
+ fflush(stdout);
+ counter = 0;
+ }
+
+ if (bUseMutex) {
+ // Release mutex using pthread_mutex_unlock(3p);
+ }
+
+ /* Sleep for 7ms */
+ nanosleep(&sleep_time, NULL);
+ }
+
+ return NULL;
+}
+
+/* Main loop thread */
+void *looperTh(void *arg)
+{
+ int counterTemp;
+ struct timespec sleep_time = {
+ .tv_sec = 0,
+ .tv_nsec = 13 * 1000 * 1000,
+ };
+
+
+ /* give the conflict thread a chance to start */
+ sleep(1);
+
+ while (!bTimeToExit) {
+ if (bUseMutex) {
+ // Acquire mutex using pthread_mutex_lock(3p)
+ }
+
+ value1 = counter;
+ value2 = counter;
+ counterTemp = counter++;
+
+ if (bUseMutex) {
+ // Release mutex using pthread_mutex_unlock(3p);
+ }
+
+ if ((counterTemp % 1000000) == 0) {
+ printf("Main loop counter = %d \r", counterTemp);
+ fflush(stdout);
+
+ /* Sleep for 13ms */
+ nanosleep(&sleep_time, NULL);
+ }
+ }
+
+ return NULL;
+}
+
+/* Ctrl-C Signal Handler */
+void gotCtrlC(int sig)
+{
+ printf("\nGot Ctrl-C! Shutting down...\n");
+
+ bTimeToExit = TRUE;
+}
+
+void print_usage(char *program)
+{
+ fprintf(stderr, "Usage: %s [options]\n%s", program,
+ "-h This help\n"
+ "-s (Use mutex to enforce synchronization)\n");
+}
+
+void parse_options(int argc, char *argv[])
+{
+ int c;
+
+ opterr = 0; /* get opt stuff */
+
+ while ((c = getopt(argc, argv, "hs")) != -1) {
+ switch (c) {
+ case 's':
+ bUseMutex = TRUE;
+ break;
+ case '?':
+ if (isprint(optopt))
+ fprintf(stderr, "Unknown option '-%c'.\n",
+ optopt);
+ else
+ fprintf(stderr,
+ "Unknown option character '\\x%x'.\n",
+ optopt);
+ /*FALLTHRU*/
+ case 'h':
+ default:
+ print_usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ printf("Options in effect:\n");
+ if (bUseMutex)
+ printf(" Thread synchronization using mutexes is in effect \n");
+ else
+ printf(" Mutex-based thread synchronization is off \n");
+}
+
+int main(int argc, char *argv[])
+{
+ int res;
+
+ /* Parse the command line arguments */
+ parse_options(argc, argv);
+
+ printf("\nUse ^C to exit application...\n");
+
+ /* Set up the ^C signal handler so we can shut down cleanly */
+ (void)signal(SIGINT, gotCtrlC);
+
+ /* Go ahead and initialize the mutex in case we need it */
+ // Initialize the mutex using pthread_mutex_init(3p)
+ if (res != 0) {
+ perror("Mutex initialization failed");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Create the main loop thread */
+ res = pthread_create(&looperThId, NULL, looperTh, NULL);
+ if (res != 0) {
+ perror("Main loop thread creation failed");
+ exit(EXIT_FAILURE);
+ }
+
+
+ /* Create the conflict thread */
+ res = pthread_create(&conflictThId, NULL, conflictTh, NULL);
+ if (res != 0) {
+ perror("Conflict thread creation failed");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("\nMain is waiting for threads to finish...\n");
+ res = pthread_join(conflictThId, NULL);
+ if (res != 0) {
+ perror("Thread join with conflictTh() failed");
+ exit(EXIT_FAILURE);
+ }
+ res = pthread_join(looperThId, NULL);
+ if (res != 0) {
+ perror("Thread join with looperTh() failed");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("Threads joined -- exiting main\n");
+ // Destroy the mutex using pthread_mutex_destroy(3p);
+
+ return EXIT_SUCCESS;
+}