-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSwapAlgorithm.cpp
More file actions
112 lines (94 loc) · 2.81 KB
/
SwapAlgorithm.cpp
File metadata and controls
112 lines (94 loc) · 2.81 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
#include "SwapAlgorithm.h"
#include <Windows.h>
SwapAlgorithm::~SwapAlgorithm() {
}
LRU::LRU(int _capacity) : capacity(_capacity), victim(0), firstAccessed(null), lastAccessed(null) {
entries = new Entry[capacity];
for (int i = 0; i < capacity; i++) {
entries[i].next = entries[i].previous = null;
}
}
LRU::~LRU() {
delete[] entries;
}
int LRU::getSwapEntry() {
if (victim < capacity) {
return victim++;
} else {
return lastAccessed;
}
}
void LRU::update(int entrie) {
if (entrie != firstAccessed) {
if (entrie != lastAccessed) {
if (entries[entrie].next != null) {
entries[entries[entrie].next].previous = entries[entrie].previous;
}
if (entries[entrie].previous != null) {
entries[entries[entrie].previous].next = entries[entrie].next;
}
} else {
lastAccessed = entries[entrie].next;
entries[lastAccessed].previous = null;
}
entries[entrie].previous = firstAccessed;
entries[firstAccessed].next = entrie;
firstAccessed = entrie;
entries[firstAccessed].next = null;
}
}
LRURequest::LRURequest(CallID _callID, int _entry) : callID(_callID), entry(_entry), semHandle(NULL){
}
LRURequest::LRURequest(CallID _callID) : callID(_callID), entry(-1) {
semHandle = CreateSemaphore(NULL, 0, 1, NULL);
}
LRURequest::~LRURequest() {
if (semHandle != NULL) {
CloseHandle(semHandle);
}
}
LRURequestHandler::LRURequestHandler(LRURequestBuffer *_buffer, LRU *_lru) : buffer(_buffer), lru(_lru) {
}
LRURequestHandler::~LRURequestHandler() {
waitToComplete();
}
void LRURequestHandler::handleRequest() {
LRURequest *request = buffer->get();
if (request->callID == LRURequest::UPDATE) {
lru->update(request->entry);
delete request;
//request handler is responsible for deallocatio
}
else if (request->callID == LRURequest::GET_SWAP_ENTRY) {
request->entry = lru->getSwapEntry();
ReleaseSemaphore(request->semHandle, 1, NULL);
//user threads are responsible for deallocation beacuse they will be blocked
}
}
ThreadSafeLRU::ThreadSafeLRU(int _lruCapacity, int _bufferCapacity) {
lru = new LRU(_lruCapacity);
buffer = new LRURequestBuffer(_bufferCapacity);
//creating and starting handler thread
handler = new LRURequestHandler(buffer, lru);
handler->start();
}
ThreadSafeLRU::~ThreadSafeLRU() {
handler->stop();
delete handler;
delete buffer;
delete lru;
}
void ThreadSafeLRU::update(int entry) {
LRURequest *request = new LRURequest(LRURequest::UPDATE, entry);
buffer->put(request);
handler->putRequest();
}
int ThreadSafeLRU::getSwapEntry() {
LRURequest *request = new LRURequest(LRURequest::GET_SWAP_ENTRY);
buffer->put(request);
handler->putRequest();
WaitForSingleObject(request->semHandle, INFINITE);
int retEntry = request->entry;
delete request;
return retEntry;
}