diff options
author | toni <toni@devlap.local> | 2015-11-30 09:56:57 +0100 |
---|---|---|
committer | toni <toni@devlap.local> | 2015-11-30 11:08:11 +0100 |
commit | 7197dcc620d71f052d4114d7419132b8c0204178 (patch) | |
tree | 5de247a408a42d2a5c5e57af3e60a16ac7947480 /parallel | |
parent | 0c7a4259f5d34a332886c9a62ed223784242ade7 (diff) |
added multithreading sync/memory examples
Diffstat (limited to 'parallel')
-rw-r--r-- | parallel/.gitignore | 1 | ||||
-rw-r--r-- | parallel/Atomic.java | 18 | ||||
-rw-r--r-- | parallel/cig_smoker_problem.c | 123 | ||||
-rw-r--r-- | parallel/cig_smoker_problem_stm.c | 151 | ||||
-rw-r--r-- | parallel/nosync.c | 68 | ||||
-rw-r--r-- | parallel/stm.c | 71 |
6 files changed, 432 insertions, 0 deletions
diff --git a/parallel/.gitignore b/parallel/.gitignore new file mode 100644 index 0000000..6b468b6 --- /dev/null +++ b/parallel/.gitignore @@ -0,0 +1 @@ +*.class diff --git a/parallel/Atomic.java b/parallel/Atomic.java new file mode 100644 index 0000000..d091e0a --- /dev/null +++ b/parallel/Atomic.java @@ -0,0 +1,18 @@ +public class Main { + + public static volatile boolean running = true; + public static int cnt = 0; + +public static void main(String[] args) throws InterruptedException { + System.out.println("start"); + Thread t = new Thread( () -> { System.out.println("Ich bin ein Thread"); while (running) { cnt++; }; } ); + t.start(); + Thread.sleep(1000); + running = false; + t.join(); + System.out.println("ende"); + System.out.println("ausgefuhrt: " + cnt); + System.err.println(cnt); +} + +} diff --git a/parallel/cig_smoker_problem.c b/parallel/cig_smoker_problem.c new file mode 100644 index 0000000..9d0928b --- /dev/null +++ b/parallel/cig_smoker_problem.c @@ -0,0 +1,123 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <pthread.h> +#include <semaphore.h> + +#include <assert.h> + + +enum thrd_ids { + AGENT_A = 0, + AGENT_B, + AGENT_C, + SMOKER_T, + SMOKER_P, + SMOKER_M, + THRD_MAX +}; + +static pthread_t thrds[THRD_MAX]; + +enum sem_ids { + AGENTSEM = 0, + TOBACCO, + PAPER, + MATCH, + SEM_MAX +}; + +static sem_t sems[SEM_MAX]; + + +static void *agenta_thread(void *args) +{ + while (1) { + sem_wait(&sems[AGENTSEM]); + sem_post(&sems[TOBACCO]); + sem_post(&sems[PAPER]); + printf("AGENT_A: +1 TOBACCO , +1 PAPER\n"); + } + return NULL; +} + +static void *agentb_thread(void *args) +{ + while (1) { + sem_wait(&sems[AGENTSEM]); + sem_post(&sems[PAPER]); + sem_post(&sems[MATCH]); + printf("AGENT_B: +1 PAPER, +1 MATCH\n"); + } + return NULL; +} + +static void *agentc_thread(void *args) +{ + while (1) { + sem_wait(&sems[AGENTSEM]); + sem_post(&sems[TOBACCO]); + sem_post(&sems[MATCH]); + printf("AGENT_C: +1 TOBACCO, +1 MATCH\n"); + } + return NULL; +} + +static void *smokerm_thread(void *args) +{ + while (1) { + sem_wait(&sems[TOBACCO]); + sem_wait(&sems[PAPER]); + sem_post(&sems[AGENTSEM]); + printf("SMOKER_M: +1 PAPER , \n"); + } + return NULL; +} + +static void *smokert_thread(void *args) +{ + while (1) { + sem_wait(&sems[PAPER]); + sem_wait(&sems[MATCH]); + sem_post(&sems[AGENTSEM]); + printf("SMOKER_T\n"); + } + return NULL; +} + +static void *smokerp_thread(void *args) +{ + while (1) { + sem_wait(&sems[TOBACCO]); + sem_wait(&sems[MATCH]); + sem_post(&sems[AGENTSEM]); + printf("SMOKER_P\n"); + } + return NULL; +} + +int +main(int argc, char *argv[]) +{ + int i; + + for (i = 0; i < SEM_MAX; i++) { + assert( sem_init(&sems[i], 0, 0) == 0 ); + } + + assert( pthread_create(&thrds[AGENT_A], NULL, agenta_thread, NULL) == 0 ); + assert( pthread_create(&thrds[AGENT_B], NULL, agentb_thread, NULL) == 0 ); + assert( pthread_create(&thrds[AGENT_C], NULL, agentc_thread, NULL) == 0 ); + assert( pthread_create(&thrds[SMOKER_M], NULL, smokerm_thread, NULL) == 0 ); + assert( pthread_create(&thrds[SMOKER_T], NULL, smokert_thread, NULL) == 0 ); + assert( pthread_create(&thrds[SMOKER_P], NULL, smokerp_thread, NULL) == 0 ); + + while (1) { + sleep( random() % 5 ); + sem_post(&sems[AGENTSEM]); + } + return 0; +} + + diff --git a/parallel/cig_smoker_problem_stm.c b/parallel/cig_smoker_problem_stm.c new file mode 100644 index 0000000..a167789 --- /dev/null +++ b/parallel/cig_smoker_problem_stm.c @@ -0,0 +1,151 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <pthread.h> +#include <immintrin.h> + +#include <assert.h> + + +enum thrd_ids { + AGENT_A = 0, + AGENT_B, + AGENT_C, + SMOKER_T, + SMOKER_P, + SMOKER_M, + THRD_MAX +}; + +static pthread_t thrds[THRD_MAX]; + +/* memory shared by all threads */ +/* only atomic operations are allowed */ +static unsigned int agent_tasks = 0; +static unsigned int tobacco = 0; +static unsigned int paper = 0; +static unsigned int match = 0; + + +static void *agenta_thread(void *args) +{ + while (1) { + __transaction_atomic { + if (agent_tasks > 0) { + agent_tasks--; + tobacco++; paper++; + } + } + printf("AGENT_A: +1 TOBACCO , +1 PAPER\n"); + sleep( random() % 5 ); + } + return NULL; +} + +static void *agentb_thread(void *args) +{ + while (1) { + __transaction_atomic { + if (agent_tasks > 0) { + agent_tasks--; + paper++; match++; + } + } + printf("AGENT_B: +1 PAPER, +1 MATCH\n"); + sleep( random() % 5 ); + } + return NULL; +} + +static void *agentc_thread(void *args) +{ + while (1) { + __transaction_atomic { + if (agent_tasks > 0) { + agent_tasks--; + tobacco++; match++; + } + } + printf("AGENT_C: +1 TOBACCO, +1 MATCH\n"); + sleep( random() % 5 ); + } + return NULL; +} + +static void *smokerm_thread(void *args) +{ + while (1) { + __transaction_atomic { + if (tobacco > 0 && paper > 0) { + agent_tasks++; + tobacco--; paper--; + } + } + printf("SMOKER_M: -1 TOBACCO, -1 PAPER\n"); + sleep( random() % 5 ); + } + return NULL; +} + +static void *smokert_thread(void *args) +{ + while (1) { + __transaction_atomic { + if (paper > 0 && match > 0) { + agent_tasks++; + paper--; match--; + } + } + printf("SMOKER_T: -1 PAPER, -1 MATCH\n"); + sleep( random() % 5 ); + } + return NULL; +} + +static void *smokerp_thread(void *args) +{ + while (1) { + __transaction_atomic { + if (tobacco > 0 && match > 0) { + agent_tasks++; + tobacco--; match--; + } + } + printf("SMOKER_P: -1 TOBACCO, -1 MATCH\n"); + sleep( random() % 5 ); + } + return NULL; +} + +int +main(int argc, char *argv[]) +{ + assert( pthread_create(&thrds[AGENT_A], NULL, agenta_thread, NULL) == 0 ); + assert( pthread_create(&thrds[AGENT_B], NULL, agentb_thread, NULL) == 0 ); + assert( pthread_create(&thrds[AGENT_C], NULL, agentc_thread, NULL) == 0 ); + assert( pthread_create(&thrds[SMOKER_M], NULL, smokerm_thread, NULL) == 0 ); + assert( pthread_create(&thrds[SMOKER_T], NULL, smokert_thread, NULL) == 0 ); + assert( pthread_create(&thrds[SMOKER_P], NULL, smokerp_thread, NULL) == 0 ); + + while (1) { + unsigned char succ = 0; + unsigned int t_tasks, t_tobacco, t_paper, t_match; + sleep(1); + __transaction_atomic { + t_tasks = agent_tasks; + t_tobacco = tobacco; + t_paper = paper; + t_match = match; + succ = 1; + } + if (succ == 1) { + printf("*** STATUS: %u agent_tasks , %u tobacco , %u paper , %u matches\n", t_tasks, t_tobacco, t_paper, t_match); + } else { + printf("*** ATOMIC OPERATIONS NOT EXECUTED ***\n"); + } + } + return 0; +} + + diff --git a/parallel/nosync.c b/parallel/nosync.c new file mode 100644 index 0000000..9ddc5a3 --- /dev/null +++ b/parallel/nosync.c @@ -0,0 +1,68 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <pthread.h> + +#include <assert.h> + + +struct thread_data { + pthread_t thrd; + int id; + int result; +}; + + +#define NTHREADS 8 +static const unsigned int nthreads = NTHREADS; +static const unsigned int iterations = 4000; +static struct thread_data thrds[NTHREADS]; + +/* r/w by threads */ +static int sum = 0; + + +void * +thread_func(void *arg) +{ + int i; + int s; + struct thread_data *td = (struct thread_data *) arg; + + printf("Thread %d started ..\n", td->id); + + /* critical section - no sync */ + s = sum; // READ + for (i = 0; i < iterations; i++) { + s++; + } + sum = s; // WRITE + + return NULL; +} + +int +main(int argc, char *argv[]) +{ + int i; + + for (i = 0; i < nthreads; i++) { + thrds[i].id = i; + thrds[i].result = 0; + assert( pthread_create( &(thrds[i].thrd), NULL, thread_func, (void*)&thrds[i] ) == 0 ); + } + + for (i = 0; i < nthreads; i++) { + assert( pthread_join(thrds[i].thrd, NULL) == 0 ); + } + + printf("Expected result: sum == %d\n", iterations*nthreads); + if (sum == iterations*nthreads) { + printf("It worked randomly, lucky dude ..\n"); + } else { + printf("This should be the common occasion: sum == %d\n", sum); + } + + return 0; +} diff --git a/parallel/stm.c b/parallel/stm.c new file mode 100644 index 0000000..15f5bbf --- /dev/null +++ b/parallel/stm.c @@ -0,0 +1,71 @@ +/* + * compile with: gcc -Wall -fgnu-tm -O2 -s stm.c -o stm + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <pthread.h> +#include <immintrin.h> + + +#include <assert.h> + + +struct thread_data { + pthread_t thrd; + int id; + int result; +}; + + +#define NTHREADS 8 +static const unsigned int nthreads = NTHREADS; +static const unsigned int iterations = 4000; +static struct thread_data thrds[NTHREADS]; + +/* r/w by threads */ +static int sum = 0; + + +void * +thread_func(void *arg) +{ + int i; + struct thread_data *td = (struct thread_data *) arg; + + printf("Thread %d started ..\n", td->id); + + /* critical section - stm */ + for (i = 0; i < iterations; i++) { + __transaction_atomic { sum++; } + } + + return NULL; +} + +int +main(int argc, char *argv[]) +{ + int i; + + for (i = 0; i < nthreads; i++) { + thrds[i].id = i; + thrds[i].result = 0; + assert( pthread_create( &(thrds[i].thrd), NULL, thread_func, (void*)&thrds[i] ) == 0 ); + } + + for (i = 0; i < nthreads; i++) { + assert( pthread_join(thrds[i].thrd, NULL) == 0 ); + } + + printf("Expected result: sum == %d\n", iterations*nthreads); + if (sum == iterations*nthreads) { + printf("STM worked! sum == %d\n", sum); + } else { + printf("Wrong result? Maybe your GNU-STM does not work. (sum == %d)\n", sum); + } + + return 0; +} |