#include #include #include #define NFRAMES 12288 #define PTSIZE 2048 typedef struct { unsigned short int *list; unsigned short int *hist; } ptentry; typedef struct { int fno; int pno; int owner; } ffentry; typedef struct _node { int item; struct _node *next; } node; typedef struct { node *F; node *B; } queue; typedef struct { int n; int m; int *size; int **sidx; int *scnt; } simdata; typedef struct { /* System-wide data structures */ int nff; /* Number of free frames */ int NFFMIN; /* Minimum number of free frames */ ffentry *fflist; /* Array of free frames */ queue readylist; /* Ready queue for round-robin scheduling */ /* Per-process data structures */ ptentry *pagetable; /* Page table of the process */ /* For statistical purpose */ int *npageaccess; /* Number of page accesses made by the process */ int *npagefault; /* Number of page faults encountered by the process */ int *npagereplacement; /* Number of page replacements encountered by the process */ int *nattempt1; /* Number of loads avoided during page replacements */ int *nattempt2; /* Number of no-owner pages during page replacements */ int *nattempt3; /* Number of own pages during page replacements */ int *nattempt4; /* Number of other-owner pages during page replacements */ } kerneldata; queue initQ ( ) { return (queue){NULL, NULL}; } int emptyQ ( queue Q ) { return (Q.F == NULL); } int front ( queue Q ) { if (Q.F == NULL) return -1; return Q.F -> item; } queue enQ ( queue Q, int x ) { node *p; p = (node *)malloc(sizeof(node)); p -> item = x; p -> next = NULL; if (Q.F == NULL) { Q.F = Q.B = p; } else { Q.B -> next = p; Q.B = p; } return Q; } queue deQ ( queue Q ) { node *p; if (Q.F == NULL) return Q; p = Q.F; Q.F = Q.F -> next; if (Q.F == NULL) Q.B = NULL; free(p); return Q; } simdata readsimdata ( ) { FILE *fp; int n, m; simdata S; int i, j; fp = (FILE *)fopen("search.txt", "r"); fscanf(fp, "%d%d", &n, &m); S.n = n; S.m = m; S.size = (int *)malloc(n * sizeof(int)); S.sidx = (int **)malloc(n * sizeof(int *)); S.scnt = (int *)malloc(n * sizeof(int)); for (i=0; i> 10) + 10; /* Logical page number */ if ((KD.pagetable[i].list[p] & (1U << 15)) == 0) { /* Page not loaded */ #ifdef VERBOSE printf(" Fault on Page %4d:", p); #endif ++(KD.npagefault[i]); if (KD.nff > KD.NFFMIN) { /* Enough free frames available */ --(KD.nff); pframe = KD.fflist[KD.nff].fno; KD.pagetable[i].list[p] = pframe | (1U << 15); KD.pagetable[i].hist[p] = 0xffff; #ifdef VERBOSE printf(" Free frame %d found\n", pframe); #endif } else { /* Page replacement needed */ ++(KD.npagereplacement[i]); /* Find the victim page (smallest history) */ minhist = 1000000000; q = -1; for (j=10; j>= 1; if ((KD.pagetable[i].list[j]) & (1U << 14)) { /* if reference bit is set */ KD.pagetable[i].hist[j] |= (1U << 15); /* store 1 in msb of history */ KD.pagetable[i].list[j] ^= (1U << 14); /* clear reference bits */ } } } ++(SD.scnt[i]); if (SD.scnt[i] < SD.m) { KD.readylist = enQ(KD.readylist, i); } else { /* Return all frames occupied by process i to system pool */ for (j=0; j