#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#define n 10
#define Allocated 1
#define UnAllocated 0
#define READY 1
#define BLOCKED -1
#define ERR_NO_SPACE 999
#define N_SEM 10
#define RANGE_ERR 666
typedef struct pcb
{
sem_t sema;
int id;
int priority;
struct pcb *next;
struct pcb *prev;
int state;
int alloc;
int type;
} pcb_t;
typedef struct queue
{
pcb_t *front;
pcb_t *rear;
pcb_t *pcb_table[n];
int state;
} que_t;
/* New Added */
typedef struct {
int val;
int alloc;
que_t qa;
} sema_t;
/* /////////////// */
que_t
init_queue (que_t * qq)
{
qq->front = NULL;
qq->rear = NULL;
return *qq;
};
pcb_t
init_pcb (pcb_t * pp)
{
pp
->id
= rand () % 10 + 1;
pp
->priority
= rand () % 5 + 1;
return *pp;
};
void
print_list (pcb_t * head)
{
pcb_t *current = head;
while (current != NULL)
{
current = current->next;
}
};
void
enqueue (pcb_t * pp, que_t * qq)
{
if (qq->front == NULL && qq->rear == NULL)
{
qq->rear = pp;
qq->front = pp;
pp->next = NULL;
}
else
{
qq->rear->next = pp;
qq->rear = pp;
pp->next = NULL;
}
};
pcb_t* dequeue (que_t * qq)
{
if (qq->front == NULL && qq->rear == NULL)
{
}
else
{
pcb_t *temp = qq->front;
qq->front = qq->front->next;
printf ("Removed item is: %d\n", temp
->id
);
return &temp;
}
}
int
isFull (que_t * qq)
{
int full = 0;
if (qq->rear->priority == n - 1)
{
full = 1;
}
return full;
}
int
isEmpty (que_t * qq)
{
int empty = 0;
if (qq->front == qq->rear + 1)
{
empty = 1;
}
return empty;
}
void insert(pcb_t *pp, que_t *qq) {
que_t check;
check.state = qq->state;
check.front = qq->front;
check.rear = qq->front;
if (qq->front == NULL && qq->rear == NULL) {
enqueue(pp, qq);
}
else if (qq->rear->priority < pp->priority) {
enqueue(pp, qq);
}
else if (qq->front->priority > pp->priority) {
qq->front = pp;
pp->next = check.front;
printf("%d added to queue.\n", pp
->id
);
}
else if (qq->front->priority < pp->priority) {
while (check.front->priority < pp->priority && check.front->next != NULL) {
check.front = check.front->next;
}
while (check.rear->next != check.front) {
check.rear = check.rear->next;
}
check.rear->next = pp;
if (check.front == NULL) {
pp->next = NULL;
}
else {
pp->next = check.front;
printf("%d added to queue.\n", pp
->id
);
}
}
else {
}
}
void delete(pcb_t *pp, que_t *qq) {
pcb_t *temp = qq->front;
if (qq->front == NULL && qq->rear == NULL) {
}
else if (pp->id == qq->front->id) {
dequeue(qq);
}
else if (pp->id == qq->rear->id) {
while (temp->next->next != NULL) {
temp = temp->next;
}
temp->next = NULL;
qq->rear = temp;
}
else {
while (pp->id != temp->next->id) {
temp = temp->next;
}
temp->next = temp->next->next;
}
}
void
Print (que_t * qq)
{
pcb_t *pp;
for (pp = qq->front; pp != 0; pp = pp->next)
{
}
}
pcb_t pcb_table[n];
que_t fcfsQueue;
que_t pbQueue;
int pid;
void fcfsFunction(int i)
{
pcb_t Array[10];
pcb_t pp=init_pcb(&pp);
pp.id=i;
pcb_table[i]=pp;
enqueue(&pcb_table[i], &fcfsQueue);
Print(&fcfsQueue);
}
void pbFunction(int i)
{
int jj;
pcb_t Array[10];
pcb_t pp=init_pcb(&pp);
pp.id=i;
pp.priority=pcb_table[i].priority;
pcb_table[i]=pp;
insert(&pcb_table[i], &pbQueue);
printf(" ~~#~~Priority Based Queue\n");
Print(&pbQueue);
}
void *scheduler()
{
sem_wait(&pcb_table[pid].sema);
sleep(2);
if(pcb_table[pid].type == 0 && pcb_table[pid].state == READY) {
fcfsFunction(pid);
} else if (pcb_table[pid].type == 1 && pcb_table[pid].state == READY) {
pbFunction(pid);
}
else if (pcb_table[pid].state == BLOCKED) {
printf(" Sorry seems BLOCKED ... PID = %d!\n",pid
);
}
sem_post(&pcb_table[pid].sema);
}
void block(int pid) {
pcb_table[pid].state = BLOCKED;
printf("# Memory Address %d is BLOCKED\n",pid
);
}
void unblock(int pid) {
pcb_table[pid].state = READY;
printf("# Memory Address %d is READY\n",pid
);
}
void deletePid(int pid) {
pcb_t* pt;
pt=&pcb_table[pid];
pt->state = NULL;
pt->alloc = UnAllocated;
if (pt->type == 0) {
delete(pt,&fcfsQueue);
} else if(pt->type == 1) {
delete(pt,&pbQueue);
printf("PRIORITY BASEDDDDD\n");
}
printf("# Memory Address %d is DELETED!\n",pid
);
}
int make_proc(int address , int type , int prio) {
printf("process number %i\n",address
);
int i; pcb_t* pt;
for(i=0; i<=n; i++) {
pt=&pcb_table[i];
if(pt->alloc = UnAllocated) {
break;
}
else if(i==n) {
return ERR_NO_SPACE;
}
else if (pt->priority || pt->state == BLOCKED) {
continue;
}
pid = i;
printf(" Memory location %d seems free...implementing there\n",i
);
break;
}
pt=&(pcb_table[pid]);
pt->type = type;
pt->priority = prio;
pthread_t p;
if (!pt->state) {
pt->state = READY;
}
sem_init(&pt->sema,NULL,1);
pt->alloc = Allocated;
pthread_create(&p,NULL,scheduler,NULL);
pthread_join(p, NULL);
printf("bye process number %i!\n",address
);
printf("//////////////////////////////////////\n");
}
/* NEW CODE */
sema_t sem_table[N_SEM];
sema_wait(int s) {
sema_t* sp;
if( s<0 || s>N_SEM -1) {
return (RANGE_ERR);
}
sp = &(sem_table[s]);
sp->val--;
if(sp->val < 0) {
enqueue(&pcb_table[pid],&sp->qa);
Print(&sp->qa);
block(pid);
}
}
sema_signal(int s) {
sema_t *sp; pcb_t* pp;
if( s<0 || s>N_SEM -1) {
return (RANGE_ERR);
}
sp=&(sem_table[s]);
sp->val++;
if(sp->val<=0) {
pp = dequeue(&sp->qa);
unblock(&pp->id);
}
}
alloc_sem() {
int i;
for(i=0;i<N_SEM;i++) {
if(sem_table[i].alloc = UnAllocated) {
printf("\nitem %d is already Allocated!\n",i
);
continue;
}
printf("\nSetting its alloc / val / qa.front for %d\n",i
);
sem_table[i].alloc = Allocated;
sem_table[i].val = 0;
sem_table[i].qa.front = NULL;
}
return (ERR_NO_SPACE);
}
/* ///////////////////// */
int
main ()
{
alloc_sem();
int i =0;
for(i=0;i<N_SEM;i++){
sema_wait(i);
sema_signal(i);
}
// make_proc (PROCESS_ID , TYPE_OF_PROCESS[PRIORITY BASED / FCFS] , PRIORITY ) //
// HERE ALL OF THEM ARE FCFS
// block(0);
// make_proc(0,0,3);
// make_proc(3,0,2);
// make_proc(2,0,1);
// unblock(0);
// deletePid(1);
// make_proc(5,0,0);
// make_proc(1,0,6);
// make_proc(6,0,5);
return 0;
}