Skip to content

Instantly share code, notes, and snippets.

@parano
Created April 19, 2013 04:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save parano/9c7290220a230b82de37 to your computer and use it in GitHub Desktop.
Save parano/9c7290220a230b82de37 to your computer and use it in GitHub Desktop.
use peterson method to implement semaphore
/*
* =====================================================================================
*
* Filename: mutex_semaphore.c
*
* Description: use peterson method to implement semaphore
*
* Version: 1.0
* Created: 04/16/2013 03:27:04 PM
* Revision: none
* Compiler: gcc
*
* Author: Chaoyu Yang,
* Organization:
*
* =====================================================================================
*/
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#define FALSE 0
#define TRUE 1
#define N 4 // number of processes, from 1 to 4
int account1 = 0, account2 = 0;
int turn[N];
int stage[N+1];
void enterRegion(int process) {
int i, j;
for (i = 1; i <= N - 1; i++) {
stage[process] = i;
turn[i] = process;
for (j = 1; j <= N; j++) {
if (j == process)
continue;
while (stage[j] >= i && turn[i] == process)
;
}
}
}
void leaveRegion(int process) {
stage[process] = FALSE;
}
typedef struct {
int value;
}semaphore;
semaphore S;
void init(semaphore *s, int v) {
s->value = v;
}
void wait(semaphore *s, int i) {
enterRegion(i);
while(s->value <= 0) {
leaveRegion(i);
/*sched_yield();*/
sleep(0);
enterRegion(i);
}
s->value--;
leaveRegion(i);
}
void signal(semaphore *s, int i) {
enterRegion(i);
s->value ++;
leaveRegion(i);
}
void * bankingTranscation(void *arg)
{
int counter = 0;
int i = (int)arg;
do {
int r = rand()%100;
if(r % 2 == 1)
r *= -1;
wait(&S, i);
//criticial region
account1 -= r;
account2 += r;
//end of creticial region
signal(&S, i);
counter++;
} while(counter < 1000000);
if (account1 + account2 != 0)
printf("Error\n");
pthread_exit((void *)2);
}
int main ()
{
clock_t begin, end;
double time_spent;
begin = clock();
init(&S,1);
pthread_t tid1, tid2, tid3, tid4;
pthread_create(&tid1, NULL, bankingTranscation, (void *)1);
pthread_create(&tid2, NULL, bankingTranscation, (void *)2);
pthread_create(&tid3, NULL, bankingTranscation, (void *)3);
pthread_create(&tid4, NULL, bankingTranscation, (void *)4);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
pthread_join(tid4, NULL);
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Time consumed: %.6g \n", time_spent);
pthread_exit(NULL);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment