COMS 4995 Advanced Systems Programming

Index of 2024-1/code/07

Parent directory
Makefile
bank0.c
bank1.c

Makefile

CC = gcc

# compile and link with -pthread
CFLAGS  = -pthread -g -Wall
LDFLAGS = -pthread

executables = bank0   bank1
objects     = bank0.o bank1.o

.PHONY: default
default: $(executables)

$(executables):

$(objects):

.PHONY: clean
clean:
	rm -f *~ *.out $(objects) $(executables)

.PHONY: all
all: clean default

bank0.c

#include <stdio.h>
#include <pthread.h> // pthread_create, pthread_join

int balance = 0;

void* deposit(void *arg) {        
    for (int i = 0; i < 1e7; i++) {
        ++balance;
    }
    long r = 10 * (long)arg;
    return (void *)r;
}

void* withdraw(void *arg) {        
    for (int i = 0; i < 1e7; i++) {
        --balance;
    }
    long r = 10 * (long)arg;
    return (void *)r;
}

int main() {
    /* int pthread_create(pthread_t *thread, 
                          const pthread_attr_t *attr,
                          void *(*start_routine)(void *), 
                          void *arg); 
           Returns: 0 if OK, error number on failure */

    pthread_t t1, t2;
    pthread_create(&t1, NULL, &deposit,  (void*)1);        
    pthread_create(&t2, NULL, &withdraw, (void*)2);

    /* int pthread_join(pthread_t thread, void **retval);
           Returns: 0 if OK, error number on failure */

    void *r1;
    void *r2;
    pthread_join(t1, &r1);
    pthread_join(t2, &r2);

    printf("t1 returned %ld\n", (long)r1);
    printf("t2 returned %ld\n", (long)r2);
    printf("balance = %d\n", balance);
}

bank1.c

#include <stdio.h>
#include <pthread.h> // pthread_create, pthread_join

int balance = 0;

pthread_mutex_t balance_lock = PTHREAD_MUTEX_INITIALIZER;

void* deposit(void *arg) {        
    for (int i = 0; i < 1e7; i++) {
        pthread_mutex_lock(&balance_lock);
        ++balance;
        pthread_mutex_unlock(&balance_lock);
    }
    long r = 10 * (long)arg;
    return (void *)r;
}

void* withdraw(void *arg) {        
    for (int i = 0; i < 1e7; i++) {
        pthread_mutex_lock(&balance_lock);
        --balance;
        pthread_mutex_unlock(&balance_lock);
    }
    long r = 10 * (long)arg;
    return (void *)r;
}

int main() {
    /* int pthread_create(pthread_t *thread, 
                          const pthread_attr_t *attr,
                          void *(*start_routine)(void *), 
                          void *arg); 
           Returns: 0 if OK, error number on failure */

    pthread_t t1, t2;
    pthread_create(&t1, NULL, &deposit,  (void*)1);        
    pthread_create(&t2, NULL, &withdraw, (void*)2);

    /* int pthread_join(pthread_t thread, void **retval);
           Returns: 0 if OK, error number on failure */

    void *r1;
    void *r2;
    pthread_join(t1, &r1);
    pthread_join(t2, &r2);

    printf("t1 returned %ld\n", (long)r1);
    printf("t2 returned %ld\n", (long)r2);
    printf("balance = %d\n", balance);
}