P10 lab code added
This commit is contained in:
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
Reference in New Issue
Block a user