-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadSimulation.cpp
More file actions
157 lines (131 loc) · 5.06 KB
/
Copy pathThreadSimulation.cpp
File metadata and controls
157 lines (131 loc) · 5.06 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
#include <iostream>
#include <queue>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <random>
#include <vector>
#include <map>
#include <iomanip>
#include <ctime>
struct SimThread {
int id;
std::string name;
int burstTime;
int remainingBurstTime; // This tracks remaining burst time
SimThread(int id, std::string name, int burstTime)
: id(id), name(name), burstTime(burstTime), remainingBurstTime(burstTime) {}
};
// Utility to get current time string
std::string currentTime() {
auto now = std::chrono::system_clock::now();
std::time_t t = std::chrono::system_clock::to_time_t(now);
std::tm* now_tm = std::localtime(&t);
char buffer[10];
std::strftime(buffer, sizeof(buffer), "%H:%M:%S", now_tm);
return std::string(buffer);
}
class ThreadScheduler {
private:
std::queue<SimThread> taskQueue;
std::mutex queueMutex;
std::condition_variable cv;
bool done = false;
std::map<int, std::vector<std::string>> processorAssignments;
std::mutex printMutex;
int timeQuantum; // Time slice for Round Robin scheduling
public:
ThreadScheduler(int tq) : timeQuantum(tq) {}
void addThread(const SimThread& t) {
std::lock_guard<std::mutex> lock(queueMutex);
taskQueue.push(t);
std::cout << "[+] Added thread " << t.name << " with burst time: " << t.burstTime << "ms\n";
cv.notify_one();
}
void runWithProcessors(int numProcessors) {
std::vector<std::thread> processors;
for (int i = 0; i < numProcessors; ++i) {
processors.emplace_back([this, i]() {
while (true) {
SimThread t(0, "", 0);
{
std::unique_lock<std::mutex> lock(queueMutex);
cv.wait(lock, [this]() { return !taskQueue.empty() || done; });
if (taskQueue.empty() && done)
return;
t = taskQueue.front();
taskQueue.pop();
processorAssignments[i].push_back(t.name);
}
{
std::lock_guard<std::mutex> lock(printMutex);
std::cout << "[" << currentTime() << "] [P" << i << "] Assigned: " << t.name
<< " (burst: " << t.burstTime << "ms)\n";
}
// Run for the time quantum or remaining time, whichever is smaller
int timeToRun = std::min(timeQuantum, t.remainingBurstTime);
std::this_thread::sleep_for(std::chrono::milliseconds(timeToRun));
t.remainingBurstTime -= timeToRun;
// If there is remaining burst time, push it back into the queue
if (t.remainingBurstTime > 0) {
{
std::lock_guard<std::mutex> lock(queueMutex);
taskQueue.push(t);
}
{
std::lock_guard<std::mutex> lock(printMutex);
std::cout << "[" << currentTime() << "] [P" << i << "] Preempted: " << t.name
<< " (remaining burst: " << t.remainingBurstTime << "ms)\n";
}
} else {
{
std::lock_guard<std::mutex> lock(printMutex);
std::cout << "[" << currentTime() << "] [P" << i << "] Completed: " << t.name << "\n";
}
}
}
});
}
for (auto& p : processors)
p.join();
printAssignmentSummary(numProcessors);
}
void printAssignmentSummary(int numProcessors) {
std::cout << "\n=== Processor Assignment Summary ===\n";
for (int i = 0; i < numProcessors; ++i) {
std::cout << "Processor P" << i << " handled: ";
if (processorAssignments[i].empty()) {
std::cout << "None";
} else {
for (const auto& tName : processorAssignments[i]) {
std::cout << tName << " ";
}
}
std::cout << "\n";
}
}
void markDone() {
std::lock_guard<std::mutex> lock(queueMutex);
done = true;
cv.notify_all();
}
};
int main() {
ThreadScheduler scheduler(500); // 500ms time quantum for Round Robin
const int numThreads = 10;
const int numProcessors = 4;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dist(500, 2500); // burst times between 500–2500 ms
for (int i = 1; i <= numThreads; ++i) {
int burst = dist(gen);
scheduler.addThread(SimThread(i, "T" + std::to_string(i), burst));
}
std::thread schedulerThread([&scheduler, numProcessors]() {
scheduler.runWithProcessors(numProcessors);
});
scheduler.markDone();
schedulerThread.join();
return 0;
}