-
Notifications
You must be signed in to change notification settings - Fork 0
/
worker.cpp
129 lines (114 loc) · 2.58 KB
/
worker.cpp
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
#include <cstdio>
#include <ctime>
#include <string>
#include <exception>
#include <stdexcept>
#include <memory>
#include "worker.h"
void* BaseWorker::Handle()
{
while (State != ENDED)
{
TakeRequests();
HandleRequest();
}
}
void BaseWorker::HandleRequest()
{
//if (Id!=0) printf("HANDLE.Id:%d\n",);
if (State == RUNNING && Requests.empty())
{
Calculate();
CollabSync();
SendCalculations();
CollabSync();
ReceiveCalculations();
IterNumber++;
if (IterNumber == IterCount)
{
Requests.push_front(BaseRequest("STOP"));
}
}
if (Requests.empty())
return;
if (Requests.front() == "RUN" && State == STOPPED)
{
IterNumber = 0;
IterCount = Requests.front().GetIterCount();
State = RUNNING;
Requests.pop_front();
}
else if (Requests.front() == "STOP" && State == RUNNING)
{
SendFinalReport();
State = STOPPED;
Requests.pop_front();
ClearRequests();
State = ENDED;
}
else if (Requests.front() == "QUIT")
{
State = ENDED;
}
else {
HandleOtherRequests();
}
}
void BaseWorker::HandleOtherRequests()
{
fprintf(stderr, "Request handling error! Request: %s\nId:%u\n", Requests.front().GetType().c_str(), Id);
Requests.pop_front();
}
void BaseWorker::Calculate()
{
for (size_t y = 1; y < OldField.size() - 1; ++y)
{
for (size_t x = 0; x < OldField[0].size(); ++x)
{
if ((OldField[y][x] == 1) && (NeighboursCount(x, y) == 3 || NeighboursCount(x, y) == 2))
Field[y][x] = 1;
else if ((OldField[y][x] == 0) && NeighboursCount(x, y) == 3)
Field[y][x] = 0;
else Field[y][x] = 0;
}
}
Field.swap(OldField);
}
size_t BaseWorker::NeighboursCount(size_t x, size_t y)
{
size_t Cnt = 0;
for (int i = -1; i < 2; ++i)
{
for (int j = -1; j < 2; ++j)
{
if (i*i + j*j > 0)
if (OldField[(OldField.size() + y + i) % OldField.size()][(OldField[0].size()+ j + x) % OldField[0].size()])
Cnt++;
}
}
return Cnt;
}
void LocalWorker::SendCalculations()
{
(*SendFieldTop) = OldField[1];
(*SendFieldBottom) = OldField[OldField.size() - 2];
}
void LocalWorker::ReceiveCalculations()
{
OldField[0] = (*ReceiveFieldTop);
OldField.back() = (*ReceiveFieldBottom);
}
LocalWorker::LocalWorker(unsigned number, LocalWorkerData localData):LocalWorkerData(localData)
{
BaseWorker::Id = number;
OldField = *SrcField;
Field = OldField;
Height = OldField.size() - 2;
Width = OldField[0].size();
State = STOPPED;
}
void LocalWorker::SendFinalReport()
{
(*SrcField) = OldField;
SyncWithMaster();
}