#include #include #include #include #include int m, n; int *AVAILABLE, **ALLOC, **NEED, *REQ, reqfrom; char reqtype; pthread_mutex_t rmtx = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t pmtx = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t *cwait; pthread_mutex_t *cmtx; pthread_barrier_t BOS, REQB, *ACKB; typedef struct _node { int from; int *request; struct _node *next; } node; typedef struct { node *F; node *B; } RQ; RQ initQ ( ) { RQ Q; Q.F = (node *)malloc(sizeof(node)); Q.F -> from = -1; Q.F -> request = NULL; Q.F -> request = NULL; Q.B = NULL; return Q; } int emptyQ ( RQ Q ) { return (Q.B == NULL); } node *frontQ ( RQ Q ) { if (emptyQ(Q)) return NULL; return Q.F -> next; } RQ enQ ( RQ Q, int i ) { node *p; int j; p = (node *)malloc(sizeof(node)); p -> from = i; p -> request = (int *)malloc(m * sizeof(int)); for (j=0; j request)[j] = REQ[j]; p -> next = NULL; if (Q.B == NULL) { Q.F -> next = Q.B = p; } else { Q.B -> next = p; Q.B = p; } return Q; } RQ deQ ( RQ Q ) { node *p; if (emptyQ(Q)) return Q; p = Q.F -> next; Q.F -> next = Q.F -> next -> next; if (Q.F -> next == NULL) Q.B = NULL; free(p -> request); free(p); return Q; } void prnQ ( RQ Q ) { node *p; printf("\t\tWaiting threads:"); p = Q.F -> next; while (p) { printf(" %d", p -> from); p = p -> next; } printf("\n"); } void timed_wait ( int t ) { usleep(t * 50000); } void *tmain ( void *arg ) { int i, j, wtime, flag; char fname[64], rt[32]; FILE *fp; i = *((int *)arg); printf("\tThread %d born\n", i); sprintf(fname, "input/thread%02d.txt", i); fp = (FILE *)fopen(fname, "r"); for (j=0; j 0) flag = 1; } pthread_mutex_lock(&pmtx); printf("\tThread %d sends resource request: type = %s\n", i, (flag) ? "ADDITIONAL" : "RELEASE"); pthread_mutex_unlock(&pmtx); pthread_barrier_wait(&REQB); pthread_barrier_wait(ACKB+i); pthread_mutex_unlock(&rmtx); if (flag) pthread_cond_wait(cwait+i,cmtx+i); pthread_mutex_unlock(cmtx+i); pthread_mutex_lock(&pmtx); if (flag) printf("\tThread %d is granted its last resource request\n", i); else printf("\tThread %d is done with its resource release request\n", i); pthread_mutex_unlock(&pmtx); } } fclose(fp); pthread_exit(NULL); } void initsession ( ) { int i, j; FILE *fp; fp = (FILE *)fopen("input/system.txt","r"); fscanf(fp, "%d%d", &m, &n); AVAILABLE = (int *)malloc(m * sizeof(int)); for (j=0; j 0) { flag = 1; } } return flag; } int resourceavailable ( node *q ) { int j, flag; flag = 1; for (j=0; j request)[j] > AVAILABLE[j]) { flag = 0; break; } } pthread_mutex_lock(&pmtx); if (flag == 0) printf(" +++ Insufficient resources to grant request of thread %d\n", q -> from); pthread_mutex_unlock(&pmtx); return flag; } int issafe ( int *exited ) { int *WORK, *FINISH, i, j, flag; WORK = (int *)malloc(m * sizeof(int)); for (j=0; j WORK[j]) break; if (j == m) { for (j=0; j from; REQ = q -> request; for (j=0; j next; while (q) { if (canserve(q,exited)) { i = q -> from; for (j=0; j request)[j]; if (req) { ALLOC[i][j] += req; NEED[i][j] -= req; AVAILABLE[j] -= req; } } p -> next = q -> next; free(q -> request); free(q); q = p -> next; pthread_mutex_lock(&pmtx); printf("Master thread grants resource request for thread %d\n", i); pthread_mutex_unlock(&pmtx); pthread_mutex_lock(cmtx+i); pthread_cond_signal(cwait+i); pthread_mutex_unlock(cmtx+i); } else { p = q; q = q -> next; } } if (Q.F -> next == NULL) { Q.B = NULL; } else { Q.B = Q.F -> next; while (Q.B -> next != NULL) Q.B = Q.B -> next; } return Q; } void releaseresources ( int i ) { int j; for (j=0; j