P10 lab code added

This commit is contained in:
Andreas Gieriet
2020-05-10 02:07:29 +02:00
parent c7d4ec972e
commit 382018f539
40 changed files with 1917 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
For Mac users
"pthread_mutex_lock(&lock)" is slow on MACs compared to Linux:
use instead: "while (pthread_mutex_trylock(&lock) > 0) {} ;"
which implements a spin lock
+46
View File
@@ -0,0 +1,46 @@
/*******************************************************************************
* File: coffeTeller.c
* Purpose: coffe teller with pthreads
* Course: bsy
* Author: M. Thaler, 2011
* Revision: 5/2012
* Version: v.fs20
*******************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include "commonDefs.h"
//******************************************************************************
void *coffeeTeller(void* data) {
int i;
cData *cD = (cData *) data;
// now start selling coffee
printf("\nCoffee teller machine starting\n\n");
i = 0;
while (i < ITERATIONS) {
if (cD->coinCount != cD->selCount1 + cD->selCount2) {
printf("error c = %5d s1 =%6d s2 =%6d diff: %4d\ti = %d\n",
cD->coinCount, cD->selCount1, cD->selCount2,
cD->coinCount - cD->selCount1 - cD->selCount2,
i);
cD->coinCount = 0;
cD->selCount1 = cD->selCount2 = 0;
}
if (i%1000000 == 0) printf("working\n");
i++;
}
pthread_exit(0);
}
//******************************************************************************
+17
View File
@@ -0,0 +1,17 @@
#ifndef MY_DEFINITIONS_TELLER_H
#define MY_DEFINITIONS_TELLER_H
/*******************************************************************************
* File: coffeTeller.h
* Purpose: coffe teller with pthreads
* Course: bsy
* Author: M. Thaler, 2011
* Revision: 5/2012
* Version: v.fs20
*******************************************************************************/
void *coffeeTeller(void* data);
//******************************************************************************
#endif
+32
View File
@@ -0,0 +1,32 @@
#ifndef MY_DEFINITIONS_HEADER
#define MY_DEFINITIONS_HEADER
/*******************************************************************************
* File: commonDefs.h
* Purpose: header file for common definitions
* Course: bsy
* Author: M. Thaler, 2011
* Revision: 5/2012
* Version: v.fs20
*******************************************************************************/
#define ITERATIONS (100*1000*1000)
//******************************************************************************
#define CUSTOMERS 4 // number of customers to be started
//******************************************************************************
// common data
typedef struct {
int coinCount; // number of paid coffees
int selCount1; // number of chosen coffees of type 1
int selCount2; // number of chosen coffees of type 2
pthread_mutex_t lock; // common lock
} cData;
//******************************************************************************
#endif
+44
View File
@@ -0,0 +1,44 @@
/*******************************************************************************
* File: customer.c
* Purpose: customer thread
* Course: bsy
* Author: M. Thaler, 2011
* Revision: 5/2012
* Version: v.fs20
*******************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include "commonDefs.h"
#include "mrand.h"
//*****************************************************************************
void *customer(void* data) {
float ranNum;
int i;
rand_t randnum;
cData *cD = (cData *) data;
rand_seed(&randnum, 0);
// put coin and select coffee
for (i = 0; i < ITERATIONS; i++) {
ranNum = rand_float(&randnum);
cD->coinCount += 1;
if (ranNum < 0.5)
cD->selCount1 += 1;
else
cD->selCount2 += 1;
}
pthread_exit(0);
}
//*****************************************************************************
+16
View File
@@ -0,0 +1,16 @@
#ifndef MY_DEFINITIONS_CUSTOMER_H
#define MY_DEFINITIONS_CUSTOMER_H
/*******************************************************************************
* File: customer.h
* Purpose: customer thread
* Course: bsy
* Author: M. Thaler, 2011
* Revision: 5/2012
* Version: v.fs20
*******************************************************************************/
void *customer(void* data);
//******************************************************************************
#endif
+33
View File
@@ -0,0 +1,33 @@
# Author M. Thaler
# Version v.fs20
CMP= gcc -std=gnu99
CMPFLAGS= -Wall -g
LIB= -pthread
EXENAME1= startApp.e
INCLS= commonDefs.h
FILES= startApp.o coffeeTeller.o customer.o
doit:
@make --no-print-directory clean
@make --no-print-directory coffeeTeller
coffeeTeller: $(FILES)
$(CMP) $(CMPFLAGS) $(FILES) $(LIB) -o $(EXENAME1)
.c.o: $(INCLS)
$(CMP) -c $(CMPFLAGS) $<
.cc.o: $(INCLS)
$(CMP) -c $(CMPFLAGS) $<
all:
@make clean
make doit
clean:
@rm -f *.e *.o
purge:
@make clean
+102
View File
@@ -0,0 +1,102 @@
#ifndef MY_THREADSAVE_RANDOM_GENERATOR
#define MY_THREADSAVE_RANDOM_GENERATOR
/******************************************************************************
* File: mrand.h
* Purpose: simple portable thread save random generator
* ccording to Schrage
* Author: M. Thaler, 5/2012, BSy
* Version: v.fs20
******************************************************************************/
#include <sys/time.h>
//******************************************************************************
#define MMM_MR 2147483563
#define AAA_MR 40014
#define QQQ_MR 53668
#define RRR_MR 12211
#define MRAND_MAX (MMM_MR-1)
//******************************************************************************
typedef int rand_t;
// seed ------------------------------------------------------------------------
void rand_seed(rand_t *srand, int seed) {
struct timeval prandom_seed;
gettimeofday(&prandom_seed, NULL);
if (seed > 0)
*srand = seed;
else
*srand = (prandom_seed.tv_usec);
}
// integer random value -------------------------------------------------------
// range 0 .. MRAND_MAX (inclusive)
int rand_int(rand_t *srand) {
int nx;
nx = AAA_MR * (*srand % QQQ_MR) - RRR_MR * (*srand / QQQ_MR);
*srand = (nx > 0) ? nx : nx + MMM_MR;
return (*srand);
}
// float random value ---------------------------------------------------------
// range 0.0 .. 1.0 (inclusive)
float rand_float(rand_t *srand) {
float fx;
*srand = rand_int(srand);
fx = (float)(*srand) / ((float)MRAND_MAX);
return (fx);
}
// double random value --------------------------------------------------------
// range 0.0 .. 1.0 (inclusive)
double rand_double(rand_t *srand) {
double fx;
*srand = rand_int(srand);
fx = (double)(*srand) / ((double)MRAND_MAX);
return (fx);
}
// unsigned int random range --------------------------------------------------
// range low .. high
unsigned int rand_range(unsigned int low, unsigned int high, rand_t *srand) {
unsigned int rv;
double prop;
prop = ((double)(high - low)) * rand_double(srand);
rv = low + ((unsigned int) prop);
return(rv);
}
// unsigned int probability ---------------------------------------------------
// returns 0 or 1
unsigned int rand_prob(double prob, rand_t *srand) {
if (rand_double(srand) >= 1.0-prob)
return 1;
else
return 0;
}
// unsigned int toss coin -----------------------------------------------------
// returns 0 or 1
unsigned int toss_coin(rand_t *srand) {
if (rand_float(srand) >= 0.5)
return 1;
else
return 0;
}
//******************************************************************************
#endif
+59
View File
@@ -0,0 +1,59 @@
/*******************************************************************************
* File: startApp.c
* Purpose: mutex with locks
* Course: bsy
* Author: M. Thaler, 2011
* Revision: 5/2012
* Version: v.fs20
*******************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
#include <pthread.h>
#include "commonDefs.h"
#include "coffeeTeller.h"
#include "customer.h"
//******************************************************************************
// common data
cData cD;
//******************************************************************************
int main(void) {
unsigned int j;
int pthr;
pthread_t tellerThread, customerThreads[CUSTOMERS];
cD.coinCount = 0;
cD.selCount1 = 0;
cD.selCount2 = 0;
pthread_mutex_init(&(cD.lock), NULL);
// start teller and customers now that everything is set up
pthr = pthread_create(&tellerThread, NULL, coffeeTeller, &cD);
assert(pthr == 0);
for (j = 0; j < CUSTOMERS; j++) {
pthr = pthread_create(&(customerThreads[j]), NULL, customer, &cD);
assert(pthr == 0);
}
// wait for all threads to terminate
pthread_join(tellerThread, NULL);
for (j = 0; j < CUSTOMERS; j++) {
pthr = pthread_join(customerThreads[j], NULL);
assert(pthr == 0);
}
}
//******************************************************************************