From a72eedc5b6733401638eb0d09f2ada5de553a4d8 Mon Sep 17 00:00:00 2001 From: Remzi Arpaci-Dusseau Date: Mon, 10 Sep 2018 10:34:11 -0500 Subject: [PATCH] Added common include for simple C programs, and threads-intro code --- include/common.h | 21 +++++++++++++++++++++ include/common_threads.h | 33 +++++++++++++++++++++++++++++++++ threads-intro/Makefile | 14 ++++++++++++++ threads-intro/t0.c | 28 ++++++++++++++++++++++++++++ threads-intro/t1.c | 40 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+) create mode 100644 include/common.h create mode 100644 include/common_threads.h create mode 100644 threads-intro/Makefile create mode 100644 threads-intro/t0.c create mode 100644 threads-intro/t1.c diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..1202765 --- /dev/null +++ b/include/common.h @@ -0,0 +1,21 @@ +#ifndef __common_h__ +#define __common_h__ + +#include +#include +#include + +double GetTime() { + struct timeval t; + int rc = gettimeofday(&t, NULL); + assert(rc == 0); + return (double) t.tv_sec + (double) t.tv_usec/1e6; +} + +void Spin(int howlong) { + double t = GetTime(); + while ((GetTime() - t) < (double) howlong) + ; // do nothing in loop +} + +#endif // __common_h__ diff --git a/include/common_threads.h b/include/common_threads.h new file mode 100644 index 0000000..a587122 --- /dev/null +++ b/include/common_threads.h @@ -0,0 +1,33 @@ +#ifndef __common_threads_h__ +#define __common_threads_h__ + +#include +#include +#include + +#ifdef __linux__ +#include +#endif + +#define Pthread_create(thread, attr, start_routine, arg) assert(pthread_create(thread, attr, start_routine, arg) == 0); +#define Pthread_join(thread, value_ptr) assert(pthread_join(thread, value_ptr) == 0); + +#define Pthread_mutex_lock(m) assert(pthread_mutex_lock(m) == 0); +#define Pthread_mutex_unlock(m) assert(pthread_mutex_unlock(m) == 0); +#define Pthread_cond_signal(cond) assert(pthread_cond_signal(cond) == 0); +#define Pthread_cond_wait(cond, mutex) assert(pthread_cond_wait(cond, mutex) == 0); + +#define Mutex_init(m) assert(pthread_mutex_init(m, NULL) == 0); +#define Mutex_lock(m) assert(pthread_mutex_lock(m) == 0); +#define Mutex_unlock(m) assert(pthread_mutex_unlock(m) == 0); +#define Cond_init(cond) assert(pthread_cond_init(cond, NULL) == 0); +#define Cond_signal(cond) assert(pthread_cond_signal(cond) == 0); +#define Cond_wait(cond, mutex) assert(pthread_cond_wait(cond, mutex) == 0); + +#ifdef __linux__ +#define Sem_init(sem, value) assert(sem_init(sem, 0, value) == 0); +#define Sem_wait(sem) assert(sem_wait(sem) == 0); +#define Sem_post(sem) assert(sem_post(sem) == 0); +#endif // __linux__ + +#endif // __common_threads_h__ diff --git a/threads-intro/Makefile b/threads-intro/Makefile new file mode 100644 index 0000000..8bb94fa --- /dev/null +++ b/threads-intro/Makefile @@ -0,0 +1,14 @@ + +FLAGS = -Wall -pthread +INCLUDES = ../include + +all: t0 t1 + +clean: + rm -f t0 t1 + +t0: t0.c + gcc -I $(INCLUDES) -o t0 t0.c $(FLAGS) + +t1: t1.c + gcc -I $(INCLUDES) -o t1 t1.c $(FLAGS) diff --git a/threads-intro/t0.c b/threads-intro/t0.c new file mode 100644 index 0000000..1d238a8 --- /dev/null +++ b/threads-intro/t0.c @@ -0,0 +1,28 @@ +#include "common.h" +#include "common_threads.h" +#include +#include +#include + +void *mythread(void *arg) { + printf("%s\n", (char *) arg); + return NULL; +} + +int main(int argc, char *argv[]) { + if (argc != 1) { + fprintf(stderr, "usage: main\n"); + exit(1); + } + + pthread_t p1, p2; + printf("main: begin\n"); + Pthread_create(&p1, NULL, mythread, "A"); + Pthread_create(&p2, NULL, mythread, "B"); + // join waits for the threads to finish + Pthread_join(p1, NULL); + Pthread_join(p2, NULL); + printf("main: end\n"); + return 0; +} + diff --git a/threads-intro/t1.c b/threads-intro/t1.c new file mode 100644 index 0000000..7dc2571 --- /dev/null +++ b/threads-intro/t1.c @@ -0,0 +1,40 @@ +#include "common.h" +#include "common_threads.h" +#include +#include +#include + +int max; +volatile int counter = 0; // shared global variable + +void *mythread(void *arg) { + char *letter = arg; + int i; // stack (private per thread) + printf("%s: begin [addr of i: %p]\n", letter, &i); + for (i = 0; i < max; i++) { + counter = counter + 1; // shared: only one + } + printf("%s: done\n", letter); + return NULL; +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "usage: main-first \n"); + exit(1); + } + max = atoi(argv[1]); + + pthread_t p1, p2; + printf("main: begin [counter = %d] [%x]\n", counter, + (unsigned int) &counter); + Pthread_create(&p1, NULL, mythread, "A"); + Pthread_create(&p2, NULL, mythread, "B"); + // join waits for the threads to finish + Pthread_join(p1, NULL); + Pthread_join(p2, NULL); + printf("main: done\n [counter: %d]\n [should: %d]\n", + counter, max*2); + return 0; +} +