1 #include "lbs_i.h"
2
3 Define_Module( LBS_I )
4
5 void LBS_I::activity()
6 {
7 // get parameters
8 simtime_t delta_t = par("delta_t");
9
10 // search servers and save reference to its workload parameter
11 // as well as their rate
12 cModule *compound = parentModule();
13
14 for (int i = 0; i<serverCount; i++) {
15 cModule *svr = compound->submodule("server", i);
16 if ((svr==0) || (strcmp(svr->className(), "Server")!=0)) {
17 throw cException("server[] contains non-Server");
18 }
19 server[i] = (Server*) svr;
20 rate[i] = svr->par("rate");
21 }
22
23 // create update-message and issue it immediately
24 cMessage *updateMsg = new cMessage("update-balancer");
25 scheduleAt(simTime() + delta_t, updateMsg);
26 update();
27
28 // message loop
29 for (;;) {
30 // get message
31 cMessage *msg = receive();
32
33 if (msg==updateMsg) {
34 // update received, so do it and issue the message again delta_t secs later
35 update();
36 scheduleAt(simTime() + delta_t, updateMsg);
37 } else {
38 // send the message to the current server to use
39 send(msg, "out", serverToUse);
40 }
41 }
42
43 }
44
45 void LBS_I::update()
46 {
47 // search server with minimum workload (count the number of occurences)
48 int i;
49 int count = 0;
50 double load = 100000000;
51 for (i = 0; i<serverCount; i++) {
52 // get queue length
53 long l = server[i]->getJobsInSystem();
54 if (l>0) --l;
55 // calculate performance measure and save it
56 double bl = (double) l/rate[i];
57 balancing[i] = bl;
58 if (bl<load) {
59 load = bl;
60 count = 1;
61 } else if (bl==load) {
62 count++;
63 }
64 }
65 // choose one server with minimum workload randomly
66 int serverNo = (int) uniform(0, count, rg);
67 // find this server
68 for (i = 0; i<serverCount; i++) {
69 if (load==balancing[i]) {
70 if (serverNo==0) break;
71 serverNo--;
72 }
73 }
74 // check on error
75 if (serverNo!=0) throw cException("error while choosing server");
76
77 // use the selected server until next update()
78 serverToUse = i;
79 }
80
81 void LBS_I::initialize()
82 {
83 // get parameters
84 rg = par("random_generator");
85 serverCount = par("server_count");
86 // create arrays
87 server = new Server *[serverCount];
88 rate = new double[serverCount];
89 balancing = new double[serverCount];
90 }
91
92 void LBS_I::finish()
93 {
94 delete [] server;
95 delete [] rate;
96 delete [] balancing;
97 }
98
99