For Avtar2008 Only Tutorial for Project VII

profilekpecet
sequent_program_for_students1.doc

#include <stdio.h>

#include <stdarg.h>

#include <signal.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <unistd.h>

#include <setjmp.h>

#define WMODE 0666

#define IFLAG (IPC_CREAT | IPC_EXCL)

#define on_line_CPUs 10

#define MAXPROCS 20

#define MaxSahredSegments 100

#define shared

#define L_FAILED 1

#define READ 0

#define WRITE 1

#define Trace 0

typedef struct {

int fd_sem[2];

int count;

int nprocs;

int s_intit_barrier_is_called;

} barrier_type;

typedef barrier_type *sbarrier_t;

typedef struct {

int fd_sem[2];

int free;

}lock_type;

typedef lock_type *slock_t;

int *key, *shmids, shmidsId = -1, *global_counter, *m_numprocs, *park;

int *child_running, *first_time, *turn, *last_sync, *m_fork_is_active; int *m_single_is_active, *m_park_procs_active;

int *m_lock_is_active;

int s_lock_mutex[2], s_wait_barrier_mutex[2];

unsigned *pids;

int m_lock_sem[2], child_sem[2], m_single_sem[2], parrent_wait_sem[2], m_sync_sem[2], m_sync_mutex[2], park_sem[2];

int created = 0;

jmp_buf *position, *pos;

void ClosePipe(int pd[])

{

close(pd[READ]);

close(pd[WRITE]);

}

void clean()

{ int i, TempKey = *key;

if ((shmidsId != -1)&&(shmctl(shmidsId,IPC_RMID, (struct shmid_ds *) 0) < 0)){

printf("\nERROR: Shmctl faild here- bye!\n");

exit(1);

}

for (i = 1; i <= TempKey; i++)

if((shmids[i] != 0)&&(shmctl(shmids[i],IPC_RMID,(struct shmid_ds *) 0)< 0)){

printf("\nERROR: Shmctl faild there- bye!\n");

exit(1);

}

ClosePipe(s_lock_mutex);

ClosePipe(s_wait_barrier_mutex);

ClosePipe(m_lock_sem);

ClosePipe(child_sem);

ClosePipe(m_single_sem);

ClosePipe(parrent_wait_sem);

ClosePipe(m_sync_sem);

ClosePipe(m_sync_mutex);

ClosePipe(park_sem);

exit(2);

}

void error_exit(char *s)

{

printf("\nERROR: %s - bye!\n", s);

clean();

exit(1);

}

void make_semaphore(int pd[], int n)

{ int i;

char junk[2] = "M";

if (pipe(pd) == -1)

error_exit("pipe(pd) faild, can not create pipe\n");

for (i=1; i <= n; i++)

if(write(pd[WRITE], junk, 2*sizeof(char)) == -1)

error_exit("write() faild, check semaphore creation.\n");

}

void p(int pd[])

{ char junk[2] = "P";

if (Trace) printf("Enter p\n");

if (read(pd[READ], junk, 2*sizeof(char)) == -1)

error_exit("P() faild, check semaphore creation.\n");

else

if (Trace) printf("In p, read from pipe the string = %s\n", junk);

if (Trace) printf("Exit p, pd[READ] = %d\n", pd[READ]);

}

void v(int pd[])

{ char junk[2] = "V";

if (Trace) printf("Enter v\n");

if(write(pd[WRITE], junk, 2*sizeof(char)) == -1)

error_exit("write() faild, check semaphore creation.\n");

else

if (Trace) printf("In v, write to pipe the string = %s\n", junk);

if (Trace) printf("Exit v\n");

}

char *shmalloc(unsigned size)

{ int *a;

++(*key);

if((shmids[*key] = shmget(*key, size, IFLAG | WMODE)) == -1)

error_exit("Shmget faild");

if((a = (int *)shmat(shmids[*key], (char *) 0, 0)) == (int *) -1)

error_exit("Shmat faild");

return (char *)a;

}

void initialize()

{ int *a, i;

signal(SIGSEGV, clean);

signal(SIGINT, clean);

signal(SIGFPE, clean);

signal(SIGTERM, clean);

if((shmidsId = shmget(0, MaxSahredSegments * sizeof(unsigned),

IFLAG | WMODE)) == -1)

error_exit("Shmget1 faild");

if((shmids = (int *)shmat(shmidsId, (char *) 0, 0)) == (int *) -1)

error_exit("Shmat faild");

for (i = 1; i < MaxSahredSegments; i++) shmids[i] = -1;

if((shmids[1] = shmget(1, sizeof(unsigned), IFLAG | WMODE)) == -1)

error_exit("Shmget2 faild");

if((key = (int *)shmat(shmids[1], (char *) 0, 0)) == (int *) -1)

error_exit("Shmat faild");

*key = 1;

pids = (unsigned *) shmalloc(on_line_CPUs * sizeof(unsigned));

for (i = 0; i < on_line_CPUs; i++) pids[i] = 0;

pids[0] = getpid();

for (i = 1; i < on_line_CPUs; i++) pids[i] = 0;

m_numprocs = (int *) shmalloc(sizeof(unsigned));

*m_numprocs = on_line_CPUs/2;

global_counter = (int *) shmalloc(sizeof(int));

child_running = (int *) shmalloc(sizeof(int));

*child_running = 0;

first_time = (int *) shmalloc(sizeof(int));

*first_time = 1;

park = (int *) shmalloc(on_line_CPUs * sizeof(int));

for (i = 1; i < on_line_CPUs; i++) park[i] = 0;

turn = (int *) shmalloc(sizeof(int));

position = (jmp_buf *) shmalloc(sizeof(jmp_buf));

pos = (jmp_buf *) shmalloc(sizeof(jmp_buf));

last_sync = (int *) shmalloc(sizeof(int));

m_fork_is_active = (int *) shmalloc(sizeof(int));

*m_fork_is_active = 0;

m_single_is_active = (int *) shmalloc(sizeof(int));

*m_single_is_active = 0;

m_lock_is_active = (int *) shmalloc(sizeof(int));

*m_lock_is_active = 0;

m_park_procs_active = (int *) shmalloc(sizeof(int));

*m_park_procs_active = 0;

make_semaphore(m_sync_sem,0);

make_semaphore(m_sync_mutex, 1);

make_semaphore(m_lock_sem, 1);

make_semaphore(child_sem, 0);

make_semaphore(m_single_sem, 0);

make_semaphore(parrent_wait_sem, 0);

make_semaphore(s_lock_mutex, 1);

make_semaphore(s_wait_barrier_mutex, 1);

make_semaphore(park_sem, 0);

}

int m_set_procs(int nprocs)

{

if (nprocs >= on_line_CPUs) {

printf("cannot set more that %d processes\n", on_line_CPUs - 1);

error_exit("system is terminated");

}

if (*child_running)

error_exit("cannot call m_set_procs while child of m_fork is running");

*m_numprocs = nprocs;

return 0;

}

m_kill_procs()

{ int i;

if (Trace) printf("Enter m_kill_procs\n");

if (*child_running)

error_exit("can not call m_kill by a child of m_fork");

for (i = 1; i < *m_numprocs; i++)

if (pids[i] != 0) {

kill(pids[i], SIGKILL);

pids[i] = 0;

}

*first_time = 1;

if (Trace) printf("Exit m_kill_procs\n");

}

void m_fork(void (func)(), ...)

{ va_list ap;

char **pp;

int i = 0, j;

if (Trace) printf("Enter m_fork\n");

if (!(*first_time)) m_kill_procs();

*turn = *m_numprocs;

*last_sync = *m_numprocs;

*m_fork_is_active = 1;

*global_counter = 0;

*child_running = 1;

va_start(ap, func);

pp = (char **) ap;

/* *child_spin = 1; */

for (i = 1; i < *m_numprocs; i++)

if (pids[0] == getpid())

if (fork() == 0) {

pids[i] = getpid();

func(

pp[0], pp[1],pp[2],pp[3],pp[4],pp[5],pp[6],pp[7],pp[8],pp[9],

pp[10],pp[11],pp[12],pp[13],pp[14],pp[15],pp[16],pp[17],pp[18],pp[19],

pp[20],pp[21],pp[22],pp[23],pp[24],pp[25],pp[26],pp[27],pp[28],pp[29],

pp[30],pp[31],pp[32],pp[33],pp[34],pp[35],pp[36],pp[37],pp[38],pp[39],

pp[40],pp[41],pp[42],pp[43],pp[44],pp[45],pp[46],pp[47],pp[48],pp[49]

);

v(child_sem);

while(1)

if(park[i]){

p(park_sem);

park[i] = 0;

longjmp(*pos, 1);

}

}

func(

pp[0], pp[1],pp[2],pp[3],pp[4],pp[5],pp[6],pp[7],pp[8],pp[9],

pp[10],pp[11],pp[12],pp[13],pp[14],pp[15],pp[16],pp[17],pp[18],pp[19],

pp[20],pp[21],pp[22],pp[23],pp[24],pp[25],pp[26],pp[27],pp[28],pp[29],

pp[30],pp[31],pp[32],pp[33],pp[34],pp[35],pp[36],pp[37],pp[38],pp[39],

pp[40],pp[41],pp[42],pp[43],pp[44],pp[45],pp[46],pp[47],pp[48],pp[49]

);

for (j = 1; j < *m_numprocs; j++)

p(child_sem);

*child_running = 0;

*m_fork_is_active = 0;

*first_time = 0;

if (Trace) printf("Exit m_fork\n");

}

m_get_myid()

{ int i = 0;

unsigned pid;

pid = getpid();

while ((i < *m_numprocs) && (pids[i] != pid))

i++;

return i;

}

void m_lock()

{

*m_lock_is_active = 1;

p(m_lock_sem);

}

void m_unlock()

{

v(m_lock_sem);

*m_lock_is_active = 0;

}

//Write your complete program (including the header files) below this line. Assume there is nothing above this line.

#include <stdio.h>