-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlcloud_cache.c
More file actions
174 lines (150 loc) · 5.34 KB
/
Copy pathlcloud_cache.c
File metadata and controls
174 lines (150 loc) · 5.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
////////////////////////////////////////////////////////////////////////////////
//
// File : lcloud_cache.c
// Description : This is the cache implementation for the LionCloud
// assignment for CMPSC311.
//
// Author : Cole Schutzman
// Last Modified : 4/19/20
//
// Includes
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <cmpsc311_log.h>
#include <lcloud_cache.h>
#include "lcloud_support.h"
// Functions
int getLine(LcDeviceId did, uint16_t sec, uint16_t blk);
//Structs
typedef struct CACHE_LINE {
char data[256];
uint64_t lastUsed;
LcDeviceId device;
uint16_t sec;
uint16_t block;
} CACHE_LINE;
//Global variables
int i; //Used for loops, declared now for convienience
CACHE_LINE *cache; //The cache
uint64_t hits = 0; //Number of cache hits
uint64_t misses = 0; //Number of cache misses
int numLines = 0; //Number of blocks stored in cache
int maxBlocks;
CACHE_LINE *cache;
////////////////////////////////////////////////////////////////////////////////
//
// Function : lcloud_getcache
// Description : Search the cache for a block
//
// Inputs : did - device number of block to find
// sec - sector number of block to find
// blk - block number of block to find
// Outputs : cache block if found (pointer), NULL if not or failure
char * lcloud_getcache( LcDeviceId did, uint16_t sec, uint16_t blk ) {
int num = getLine(did, sec, blk); //Which line in cache, if any
if (num == -1) { //If block is not in cache, return NULL, increment misses
misses++;
return (NULL);
}
else { //Block in cache, update hits and last used
cache[num].lastUsed = -1;
hits++;
for(int j=0;j<numLines;j++) {
cache[j].lastUsed++;
}
}
return cache[num].data;
}
////////////////////////////////////////////////////////////////////////////////
//
// Function : lcloud_putcache
// Description : Put a value in the cache
//
// Inputs : did - device number of block to insert
// sec - sector number of block to insert
// blk - block number of block to insert
// Outputs : 0 if succesfully inserted, -1 if failure
int lcloud_putcache( LcDeviceId did, uint16_t sec, uint16_t blk, char *block ) {
int large = 0; //Stores the least recently used vlaue to compare against
int line = 0; //Which line in cache to put the block
int num = getLine(did, sec, blk);
//Block is not in cache and cache is not full
if (num == -1 && numLines < maxBlocks) {
line = numLines;
numLines++;
}
//Block is not in cache but cache is full, evict least recent block
else if(num == -1) {
for(i=0;i<maxBlocks;i++) {
if(cache[i].lastUsed > large) {
large = cache[i].lastUsed;
line = i;
}
}
}
//Cache in block
else {
line = num;
}
//Set cache line
cache[line].device = did;
cache[line].sec = sec;
cache[line].block = blk;
cache[line].lastUsed = 0;
memcpy(cache[line].data,block,256);
return( 0 );
}
////////////////////////////////////////////////////////////////////////////////
//
// Function : lcloud_initcache
// Description : Initialze the cache by setting up metadata a cache elements.
//
// Inputs : maxblocks - the max number number of blocks
// Outputs : 0 if successful, -1 if failure
int lcloud_initcache( int maxblocks ) {
cache = (CACHE_LINE *)malloc(sizeof(CACHE_LINE) * maxblocks);
if(cache == NULL) {
return -1;
}
maxBlocks = maxblocks;
//Initialize each values to nonsense
for(i=0;i<maxBlocks;i++) {
cache[i].lastUsed = -1;
cache[i].device = -1;
cache[i].sec = -1;
cache[i].block = -1;
}
return( 0 );
}
////////////////////////////////////////////////////////////////////////////////
//
// Function : lcloud_closecache
// Description : Clean up the cache when program is closing
//
// Inputs : none
// Outputs : 0 if successful, -1 if failure
int lcloud_closecache( void ) {
free(cache);
logMessage(LcDriverLLevel,"NUMBER OF HITS: %"PRIu64,hits/2); //Divide hits by 2 because getcache is called twice per
logMessage(LcDriverLLevel,"NUMBER OF MISSES: %"PRIu64,misses);
float ratio = (float)(hits/2) / (float)((hits/2)+misses);
logMessage(LcDriverLLevel,"HIT RATIO: %.2f",ratio); //Divide hits by 2 because getcache is called twice per
return( 0 );
}
////////////////////////////////////////////////////////////////////////////////
//
// Function : getLine
// Description : Finds which line, if any the block is stored
//
// Inputs : did - The device ID the sector is in, sec - The sector the block is stored in, block - the block the data is tored in
// Outputs : 0 if successful, -1 if failure
int getLine(LcDeviceId did, uint16_t sec, uint16_t blk) {
for(i=0;i<numLines;i++) {
if (cache[i].device == did && cache[i].sec == sec && cache[i].block == blk) {
return i;
}
}
return -1;
}