NetSim Source Code Help
Loading...
Searching...
No Matches
Scheduling.c
Go to the documentation of this file.
1#include "main.h"
2#include "Scheduling.h"
3#include "NetSim_Plot.h"
4#pragma comment(lib,"Metrics.lib")
5
7{
8 ADD = 1,
10};
11#define fnGetList(pstruPacketlist,Priority) (pstruPacketlist+Priority/(Priority_High-Priority_Medium))
12
13//Queuing functions
17
18//Scheduling functions
24
25
30
32{
33 char heading[BUFSIZ];
34 sprintf(heading, "Buffer_Occupancy_%s_Interface_%d", DEVICE_NAME(d), DEVICE_INTERFACE_CONFIGID(d, in));
36 "Buffer_Occupancy",
37 heading);
38}
39
40/** This function is to check whether buffer list has any packet or not **/
42{
43 switch (pstruBuffer->nSchedulingType)
44 {
45 case 0:
47 case SCHEDULING_EDF:
48 case SCHEDULING_FIFO:
49 return pstruBuffer->pstruPacketlist ? true : false;
50 break;
52 case SCHEDULING_WFQ:
53 {
54 if (!pstruBuffer->pstruPacketlist) return false;
55
56 PACKET_PRIORITY currPriority = Priority_High;
57
58 do
59 {
60 NetSim_PACKET* pstruTempList = fnGetList(pstruBuffer->pstruPacketlist, currPriority);
61 if (pstruTempList->pstruNextPacket != NULL)
62 return true;
63 currPriority -= Priority_High - Priority_Medium;
64 } while (currPriority > 0);
65 return false;
66 break;
67 }
68 default:
69 return false;
70 break;
71 }
72 return false;
73}
74
75/** This function is to return queuing status based on given algorithm **/
76enum enum_Buffer fn_NetSim_Queuing(NetSim_BUFFER* pstruBuffer, NetSim_PACKET* pstruData)
77{
78 QUEUINGTECHNIQUE Queuing_Technique;
79 int queuing_result;
80 Queuing_Technique = pstruBuffer->queuingTechnique;
81 switch (Queuing_Technique)
82 {
84 queuing_result = fn_NetSim_DropTail(pstruBuffer, pstruData);
85 break;
86 case QUEUING_RED:
87 queuing_result = fn_NetSim_RED(pstruBuffer, pstruData);
88 break;
89 case QUEUING_WRED:
90 queuing_result = fn_NetSim_WRED(pstruBuffer, pstruData);
91 break;
92 default:
93 queuing_result = fn_NetSim_DropTail(pstruBuffer, pstruData);
94 break;
95 }
96
97 if (queuing_result == Buffer_Underflow)
98 return Buffer_Underflow;
99 else
100 return Buffer_Overflow;
101}
102
103/** This function is to add packet to the buffer **/
105{
106 int nBufferFlag;
107 int nType = 1;
108 SCHEDULING_TYPE Scheduling_Technique;
109
110 if (pstruBuffer->isPlotEnable && pstruBuffer->netsimPlotVar == NULL)
111 pstruBuffer->netsimPlotVar = init_buffer_plot(pstruBuffer->deviceId, pstruBuffer->interfaceId);
112
113 nBufferFlag = fn_NetSim_Queuing(pstruBuffer, pstruData);
114 if (nBufferFlag == Buffer_Underflow)
115 {
116 if (pstruBuffer->isPlotEnable)
117 add_plot_data_formatted(pstruBuffer->netsimPlotVar, "%lf,%d,%s,",
119 (UINT)pstruData->pstruNetworkData->dPacketSize,
120 "Enqueue");
121 pstruBuffer->nQueuedPacket++;
122 Scheduling_Technique = pstruBuffer->nSchedulingType;
123 switch (Scheduling_Technique)
124 {
126 fn_NetSim_Priority(pstruBuffer, pstruData, nType, 1);
127 break;
128 case SCHEDULING_FIFO:
129 fn_NetSim_FIFO(pstruBuffer, pstruData, nType, 1);
130 break;
132 fn_NetSim_RoundRobin(pstruBuffer, pstruData, nType, 1);
133 break;
134 case SCHEDULING_WFQ:
135 fn_NetSim_WFQ(pstruBuffer, pstruData, nType, 1);
136 break;
137 case SCHEDULING_EDF:
138 fn_NetSim_EDF(pstruBuffer, pstruData, nType, 1);
139 break;
140 default:
141 fn_NetSim_FIFO(pstruBuffer, pstruData, nType, 1);
142 break;
143 }
144 }
145 else if (nBufferFlag == Buffer_Overflow)
146 {
147 if (pstruBuffer->isPlotEnable)
148 add_plot_data_formatted(pstruBuffer->netsimPlotVar, "%lf,%d,%s,",
150 (UINT)pstruData->pstruNetworkData->dPacketSize,
151 "Drop");
152
153 pstruBuffer->nDroppedPacket++;
158 pstruData = NULL;
159 }
160 else
161 {
162 assert(false);
163 }
164 return 0;
165}
166
167/** This function is to get the packet from the buffer **/
169{
170
171 int nType = 2;
172 int nScheduling_Technique;
173 NetSim_PACKET* pstruData = NULL;
174 if (fn_NetSim_GetBufferStatus(pstruBuffer))
175 {
176 if (nFlag)
177 pstruBuffer->nDequeuedPacket++;
178 nScheduling_Technique = pstruBuffer->nSchedulingType;
179 switch (nScheduling_Technique)
180 {
182 pstruData = fn_NetSim_Priority(pstruBuffer, pstruData, nType, nFlag);
183 break;
184 case SCHEDULING_FIFO:
185 pstruData = fn_NetSim_FIFO(pstruBuffer, pstruData, nType, nFlag);
186 break;
188 pstruData = fn_NetSim_RoundRobin(pstruBuffer, pstruData, nType, nFlag);
189 break;
190 case SCHEDULING_WFQ:
191 pstruData = fn_NetSim_WFQ(pstruBuffer, pstruData, nType, nFlag);
192 break;
193 case SCHEDULING_EDF:
194 pstruData = fn_NetSim_EDF(pstruBuffer, pstruData, nType, nFlag);
195 break;
196 default:
197 pstruData = fn_NetSim_FIFO(pstruBuffer, pstruData, nType, nFlag);
198 break;
199 }
200 }
201
202 if (pstruData == NULL)
203 return NULL;
204
205 if (nFlag &&
206 pstruBuffer->dMaxBufferSize)
207 {
208 double d_NN_DataSize;
209 if (pstruData->pstruNetworkData)
210 d_NN_DataSize = pstruData->pstruNetworkData->dPacketSize;
211 else
212 d_NN_DataSize = pstruData->pstruMacData->dPacketSize;
213 pstruBuffer->dCurrentBufferSize -= (double)((int)d_NN_DataSize);
214 if (pstruBuffer->dCurrentBufferSize < 0)
215 {
216 assert(false);
217 pstruBuffer->dCurrentBufferSize = 0;
218 fnNetSimError("Assert failure in scheduling. Buffer size is negative.\n");
219 }
220 }
221
222 if (pstruBuffer->queuingTechnique == QUEUING_RED && pstruBuffer->dCurrentBufferSize == 0)
223 {
224 ptrQUEUING_RED_VAR queuing_var = pstruBuffer->queuingParam;
225 queuing_var->q_time = pstruEventDetails->dEventTime;
226 }
227
228 if (pstruBuffer->queuingTechnique == QUEUING_WRED && pstruBuffer->dCurrentBufferSize == 0)
229 {
230 ptrQUEUING_WRED_VAR queuing_var = pstruBuffer->queuingParam;
231 queuing_var->q_time = pstruEventDetails->dEventTime;
232 }
233
234 if (pstruBuffer->isPlotEnable && nFlag)
235 add_plot_data_formatted(pstruBuffer->netsimPlotVar, "%lf,%d,%s,",
237 (UINT)pstruData->pstruNetworkData->dPacketSize,
238 "Dequeue");
239 return pstruData;
240}
241
242/** The function will get the array and it will return the Maximum number's position **/
244{
245 unsigned long long int nMax;
246 UINT nLoop;
247 UINT64 nFlag = 0;
248 nMax = nCount[0];
249 for (nLoop = 1; nLoop < 4; nLoop++)
250 {
251 if (nCount[nLoop] >= nMax)
252 {
253 nMax = nCount[nLoop];
254 nFlag = nLoop;
255 }
256 }
257
258 return nFlag + 1;
259}
260
261/** Function for dropping packets **/
262static void fn_NetSim_DropPackets(NetSim_BUFFER* pstruBuffer, NetSim_PACKET* pstruData)
263{
264 pstruBuffer->nDroppedPacket++;
266 pstruData->nReceiverId = pstruData->nTransmitterId;
269 pstruData = NULL;
270}
271
272/**
273If the Current buffer size is greater than the Maximum buffer size --> Buffer Overflow
274Otherwise Buffer underflows.
275*/
277{
278 double d_NN_DataSize = 0;
279 double ldMaximumBufferSize;
280 double ldCurrentBufferSize;
281 NetSim_PACKET* p = pstruData;
282
283 while (p)
284 {
285 if (pstruData->pstruNetworkData)
286 d_NN_DataSize += pstruData->pstruNetworkData->dPacketSize;
287 else
288 d_NN_DataSize += pstruData->pstruMacData->dPacketSize;
289 p = p->pstruNextPacket;
290 }
291 if (!pstruBuffer->dMaxBufferSize)
292 pstruBuffer->dMaxBufferSize = (double)0xFFFFFFFFFFFFFFFF;
293 ldMaximumBufferSize = pstruBuffer->dMaxBufferSize * 1024 * 1024;
294 ldCurrentBufferSize = pstruBuffer->dCurrentBufferSize + d_NN_DataSize;
295 if (ldCurrentBufferSize <= ldMaximumBufferSize)
296 {
297 //buffer underflow
298 pstruBuffer->dCurrentBufferSize = (double)((int)ldCurrentBufferSize);
299 return Buffer_Underflow;
300 }
301 else
302 //buffer overflow
303 return Buffer_Overflow;
304}
305
306/** Queuing - Packets are dropped only when buffer is full **/
308{
309 enum enum_BUFFER checkBuffer = fn_NetSim_CheckBuffer(pstruBuffer, pstruData);
310 if (checkBuffer == Buffer_Underflow)
311 return Buffer_Underflow;
312 else
313 return Buffer_Overflow;
314}
315
316/** Function is used to add packet size to of buffer **/
317static void add_current_size_buffer(NetSim_BUFFER* pstruBuffer, NetSim_PACKET* pstruData)
318{
319 double d_NN_DataSize = 0;
320 double ldCurrentBufferSize;
321 NetSim_PACKET* p = pstruData;
322
323 while (p)
324 {
325 if (pstruData->pstruNetworkData)
326 d_NN_DataSize += pstruData->pstruNetworkData->dPacketSize;
327 else
328 d_NN_DataSize += pstruData->pstruMacData->dPacketSize;
329 p = p->pstruNextPacket;
330 }
331 ldCurrentBufferSize = pstruBuffer->dCurrentBufferSize + d_NN_DataSize;
332 pstruBuffer->dCurrentBufferSize = (double)((int)ldCurrentBufferSize);
333}
334
335/** Function is used to reduce size of buffer(added while checkBuffer) in case of packet drop **/
336static void reduce_current_size_buffer(NetSim_BUFFER* pstruBuffer, NetSim_PACKET* pstruData)
337{
338 double d_NN_DataSize;
339 if (pstruData->pstruNetworkData)
340 d_NN_DataSize = pstruData->pstruNetworkData->dPacketSize;
341 else
342 d_NN_DataSize = pstruData->pstruMacData->dPacketSize;
343 pstruBuffer->dCurrentBufferSize -= (double)((int)d_NN_DataSize);
344 if (pstruBuffer->dCurrentBufferSize < 0)
345 {
346 assert(false);
347 pstruBuffer->dCurrentBufferSize = 0;
348 fnNetSimError("Scheduling--- Buffer size negative. how?????\n");
349 }
350}
351
352/** Helper function for RED Queuing Technique **/
353static enum enum_BUFFER red_algorithm(NetSim_BUFFER* pstruBuffer, NetSim_PACKET* pstruData)
354{
355 ptrQUEUING_RED_VAR queuing_var = pstruBuffer->queuingParam;
356
357 double pb;
358
359 if (queuing_var->min_th <= queuing_var->avg_queue_size &&
360 queuing_var->avg_queue_size < queuing_var->max_th)
361 {
362 queuing_var->count++;
363 pb = queuing_var->max_p * (queuing_var->avg_queue_size - queuing_var->min_th) /
364 (queuing_var->max_th - queuing_var->min_th);
365 if (queuing_var->count > 0 && queuing_var->count > queuing_var->random_value / pb)
366 {
367 queuing_var->count = 0;
368 queuing_var->random_value = NETSIM_RAND_01();
369
370 return Buffer_Overflow;
371 }
372 return Buffer_Underflow;
373 }
374 else if (queuing_var->max_th <= queuing_var->avg_queue_size)
375 {
376 queuing_var->count = -1;
377
378 return Buffer_Overflow;
379 }
380 else
381 {
382 queuing_var->count = -1;
383 return Buffer_Underflow;
384 }
385}
386
387/** Queuing - RED **/
389{
390 enum enum_BUFFER checkBuffer = fn_NetSim_CheckBuffer(pstruBuffer, pstruData);
391 if (checkBuffer == Buffer_Underflow)
392 {
393 reduce_current_size_buffer(pstruBuffer, pstruData);
394 ptrQUEUING_RED_VAR queuing_var = pstruBuffer->queuingParam;
395 double curr_buff_size_in_MB = pstruBuffer->dCurrentBufferSize / 1048576;
396
397 if (curr_buff_size_in_MB == 0)
398 {
399 queuing_var->avg_queue_size = pow((1 - queuing_var->wq), (pstruEventDetails->dEventTime - queuing_var->q_time))
400 * queuing_var->avg_queue_size;
401 }
402 else
403 {
404 queuing_var->avg_queue_size = queuing_var->avg_queue_size +
405 queuing_var->wq * (curr_buff_size_in_MB - queuing_var->avg_queue_size);
406 }
407
408 checkBuffer = red_algorithm(pstruBuffer, pstruData);
409 if (checkBuffer == Buffer_Underflow)
410 add_current_size_buffer(pstruBuffer, pstruData); // Increment current buffer size
411
412 return checkBuffer;
413 }
414 else
415 return Buffer_Overflow;
416}
417
418/** Helper function for WRED Queuing Technique **/
419static enum enum_BUFFER wred_algorithm(NetSim_BUFFER* pstruBuffer, NetSim_PACKET* pstruData,
420 double max_th, double min_th, double max_p, int* count, double* random)
421{
422 ptrQUEUING_WRED_VAR queuing_var = pstruBuffer->queuingParam;
423
424 double pb;
425
426 if (min_th <= queuing_var->avg_queue_size &&
427 queuing_var->avg_queue_size < max_th)
428 {
429 *count = *count + 1;
430 pb = max_p * (queuing_var->avg_queue_size - min_th) /
431 (max_th - min_th);
432 if (*count > 0 && *count > * random / pb)
433 {
434 *count = 0;
435 *random = NETSIM_RAND_01();
436
437 return Buffer_Overflow;
438 }
439 return Buffer_Underflow;
440 }
441 else if (max_th <= queuing_var->avg_queue_size)
442 {
443 *count = -1;
444 return Buffer_Overflow;
445 }
446 else
447 {
448 *count = -1;
449 return Buffer_Underflow;
450 }
451}
452
453/** Queuing - WRED **/
455{
456 enum enum_BUFFER checkBuffer = fn_NetSim_CheckBuffer(pstruBuffer, pstruData);
457 if (checkBuffer == Buffer_Underflow)
458 {
459 reduce_current_size_buffer(pstruBuffer, pstruData);
460 ptrQUEUING_WRED_VAR queuing_var = pstruBuffer->queuingParam;
461 int index;
462 double curr_max_th;
463 double curr_min_th;
464 double curr_max_p;
465 int* curr_count;
466 double* curr_random;
467 double curr_buff_size_in_MB = pstruBuffer->dCurrentBufferSize / 1048576;
468 int priority = pstruData->nPacketPriority;
469
470 if (curr_buff_size_in_MB == 0)
471 {
472 queuing_var->avg_queue_size = pow((1 - queuing_var->wq), (pstruEventDetails->dEventTime - queuing_var->q_time))
473 * queuing_var->avg_queue_size;
474 }
475 else
476 {
477 queuing_var->avg_queue_size = queuing_var->avg_queue_size +
478 queuing_var->wq * (curr_buff_size_in_MB - queuing_var->avg_queue_size);
479 }
480
481 index = (priority / 2) - 1;
482
483 //adding control packets in queue
484 if (index == -1)
485 {
486 checkBuffer = Buffer_Underflow;
487 }
488 else
489 {
490 curr_max_th = *(queuing_var->max_th + index);
491 curr_min_th = *(queuing_var->min_th + index);
492 curr_max_p = *(queuing_var->max_p + index);
493 curr_count = (queuing_var->count + index);
494 curr_random = (queuing_var->random_value + index);
495
496 checkBuffer = wred_algorithm(pstruBuffer, pstruData, curr_max_th, curr_min_th, curr_max_p, curr_count, curr_random);
497 }
498
499 if (checkBuffer == Buffer_Underflow)
500 add_current_size_buffer(pstruBuffer, pstruData); // Increment current buffer size
501
502 return checkBuffer;
503 }
504 else
505 return Buffer_Overflow;
506}
507
508/**
509If the type is ADD, then all the packets will be added in the buffer based on packet priority
510If the type is GET, then the packets to be retrieved based on the priority
511*/
512NetSim_PACKET* fn_NetSim_Priority(NetSim_BUFFER* pstruBuffer, NetSim_PACKET* pstruData, int nType, int nFlag)
513{
514 switch (nType)
515 {
516 case ADD:
517 if (pstruBuffer->pstruPacketlist)
518 {
519 NetSim_PACKET* pstruTmpBufferPacketList;
520 NetSim_PACKET* pstruPrevPacketList;
521
522 pstruTmpBufferPacketList = pstruBuffer->pstruPacketlist;
523 pstruPrevPacketList = pstruBuffer->pstruPacketlist;
524 if (pstruTmpBufferPacketList->nPacketPriority < pstruData->nPacketPriority)
525 {
526 pstruData->pstruNextPacket = pstruTmpBufferPacketList;
527 pstruBuffer->pstruPacketlist = pstruData;
528 return 0;
529 }
530 while (pstruTmpBufferPacketList)
531 {
532 if (pstruTmpBufferPacketList->nPacketPriority < pstruData->nPacketPriority)
533 {
534 pstruData->pstruNextPacket = pstruTmpBufferPacketList;
535 pstruPrevPacketList->pstruNextPacket = pstruData;
536 break;
537 }
538 else if (!pstruTmpBufferPacketList->pstruNextPacket)
539 {
540 pstruTmpBufferPacketList->pstruNextPacket = pstruData;
541 break;
542 }
543 else
544 {
545 pstruPrevPacketList = pstruTmpBufferPacketList;
546 pstruTmpBufferPacketList = pstruTmpBufferPacketList->pstruNextPacket;
547 }
548 }
549
550 }
551 else
552 pstruBuffer->pstruPacketlist = pstruData;
553 break;
554 case GET:
555 {
556 NetSim_PACKET* pstruPacket;
557 pstruPacket = pstruBuffer->pstruPacketlist;
558 if (nFlag)
559 {
560 pstruBuffer->pstruPacketlist = pstruPacket->pstruNextPacket;
561 pstruPacket->pstruNextPacket = NULL;
562 }
563 return pstruPacket;
564 break;
565 }
566 default:
567 printf("\nInvalid Selection in Buffer\n");
568 break;
569 }
570 return NULL;
571
572}
573/**
574If the type is ADD, then all the packets will be added in the buffer based on the arrival
575If the type is GET, then the packets to be retrieved depends on the arrangement in the queue
576*/
577NetSim_PACKET* fn_NetSim_FIFO(NetSim_BUFFER* pstruBuffer, NetSim_PACKET* pstruData, int nType, int nFlag)
578{
579 NetSim_PACKET* p = pstruData;
580 while (p && p->pstruNextPacket)
581 p = p->pstruNextPacket;
582 switch (nType)
583 {
584 case ADD:
585 if (pstruBuffer->pstruPacketlist)
586 {
587 pstruBuffer->last->pstruNextPacket = pstruData;
588 pstruBuffer->last = p;
589 }
590 else
591 {
592 pstruBuffer->pstruPacketlist = pstruData;
593 pstruBuffer->last = p;
594 }
595 break;
596 case GET:
597 {
598 NetSim_PACKET* pstruPacket;
599 pstruPacket = pstruBuffer->pstruPacketlist;
600 if (nFlag)
601 {
602 pstruBuffer->pstruPacketlist = pstruPacket->pstruNextPacket;
603 if (pstruBuffer->pstruPacketlist == NULL)
604 pstruBuffer->last = NULL;
605 pstruPacket->pstruNextPacket = NULL;
606 }
607 return pstruPacket;
608 break;
609 }
610 default:
611 printf("\nInvalid selection in Buffer\n");
612 break;
613 }
614 return 0;
615}
616/**
617If the type is ADD, then all the packets will be added in the buffer based on packet priority in the corresponding list
618If the type is GET, then the packets to be retrieved in the order of one packet from each list(high priority list,Medium,Normal,Low)
619*/
620NetSim_PACKET* fn_NetSim_RoundRobin(NetSim_BUFFER* pstruBuffer, NetSim_PACKET* pstruData, int nType, int nFlag)
621{
622 switch (nType)
623 {
624 case ADD:
625 {
626 NetSim_PACKET* pstruTmpBufferPacketList;
627 NetSim_PACKET* pstruTempTraversePacketList;
628
629 if (pstruBuffer->pstruPacketlist == NULL)
630 {
631 pstruBuffer->pstruPacketlist = fnpAllocateMemory(5, sizeof * pstruData);
632 }
633 pstruTmpBufferPacketList = pstruBuffer->pstruPacketlist;
634 if (pstruData->nPacketPriority)
635 {
636 pstruTempTraversePacketList = fnGetList(pstruTmpBufferPacketList, pstruData->nPacketPriority);
637
638 while (pstruTempTraversePacketList->pstruNextPacket != NULL)
639 pstruTempTraversePacketList = pstruTempTraversePacketList->pstruNextPacket;
640 pstruTempTraversePacketList->pstruNextPacket = pstruData;
641 }
642 else
643 {
644 pstruTempTraversePacketList = fnGetList(pstruTmpBufferPacketList, Priority_Low);
645 while (pstruTempTraversePacketList->pstruNextPacket != NULL)
646 pstruTempTraversePacketList = pstruTempTraversePacketList->pstruNextPacket;
647 pstruTempTraversePacketList->pstruNextPacket = pstruData;
648 }
649 break;
650 }
651 case GET:
652 {
653 NetSim_PACKET* pstruTemp;
654 NetSim_PACKET* pstruTempList;
655 int nFlag1 = 0;
656 PACKET_PRIORITY nPacketPriority;
657 if (pstruBuffer->pstruPacketlist)
658 {
659 nPacketPriority = pstruBuffer->pstruPacketlist->nPacketPriority;
660 Retry:
661 nFlag1++;
662 if (nFlag1 == 5)
663 return NULL;
664 else
665 {
667 if (pstruBuffer->pstruPacketlist->nPacketPriority <= 0)
669
670 pstruTempList = fnGetList(pstruBuffer->pstruPacketlist, pstruBuffer->pstruPacketlist->nPacketPriority);
671 if (pstruTempList->pstruNextPacket != NULL)
672 {
673 pstruTemp = pstruTempList->pstruNextPacket;
674 if (nFlag)
675 {
676 pstruTempList->pstruNextPacket = pstruTemp->pstruNextPacket;
677 pstruTemp->pstruNextPacket = NULL;
678 }
679 else
680 pstruBuffer->pstruPacketlist->nPacketPriority = nPacketPriority;
681 return pstruTemp;
682 }
683 else
684 goto Retry;
685 }
686 }
687 else
688 return NULL;
689 }
690 default:
691 printf("\nInvalid Selection in Buffer\n");
692 break;
693 }
694 return 0;
695}
696
697/**
698If the type is ADD, then all the packets will be added in the buffer based on packet priority in the corresponding list
699If the type is GET, then the packets to be retrieved in the order of maximum weight priority list(High,Medium,Normal,Low)
700*/
701NetSim_PACKET* fn_NetSim_WFQ(NetSim_BUFFER* pstruBuffer, NetSim_PACKET* pstruData, int nType, int nFlag)
702{
703 switch (nType)
704 {
705 case ADD:
706 {
707 NetSim_PACKET* pstruTmpBufferPacketList;
708 NetSim_PACKET* pstruTempTraversePacketList;
709
710 if (pstruBuffer->pstruPacketlist == NULL)
711 {
712 pstruBuffer->pstruPacketlist = fnpAllocateMemory(5, sizeof * pstruData);
713 }
714 pstruTmpBufferPacketList = pstruBuffer->pstruPacketlist;
715 if (pstruData->nPacketPriority)
716 {
717 pstruTempTraversePacketList = fnGetList(pstruTmpBufferPacketList, pstruData->nPacketPriority);
718
719 pstruTempTraversePacketList->nPacketId++;
720
721 while (pstruTempTraversePacketList->pstruNextPacket != NULL)
722 pstruTempTraversePacketList = pstruTempTraversePacketList->pstruNextPacket;
723 pstruTempTraversePacketList->pstruNextPacket = pstruData;
724 }
725 else
726 {
727 pstruTempTraversePacketList = fnGetList(pstruTmpBufferPacketList, Priority_Low);
728
729 pstruTempTraversePacketList->nPacketId++;
730
731 while (pstruTempTraversePacketList->pstruNextPacket != NULL)
732 pstruTempTraversePacketList = pstruTempTraversePacketList->pstruNextPacket;
733 pstruTempTraversePacketList->pstruNextPacket = pstruData;
734 }
735
736 break;
737 }
738 case GET:
739 {
740 UINT64 nCount[4], nPosition;
741 NetSim_PACKET* pstruTempList;
742 NetSim_PACKET* pstruTemp;
743 NetSim_PACKET* pstruHighPriorityList;
744 NetSim_PACKET* pstruMediumPriorityList;
745 NetSim_PACKET* pstruNormalPriorityList;
746 NetSim_PACKET* pstruLowPriorityList;
747
748 pstruLowPriorityList = fnGetList(pstruBuffer->pstruPacketlist, Priority_Low);
749 nCount[0] = pstruLowPriorityList->nPacketId * 1;
750
751 pstruNormalPriorityList = fnGetList(pstruBuffer->pstruPacketlist, Priority_Normal);
752 nCount[1] = pstruNormalPriorityList->nPacketId * 2;
753
754 pstruMediumPriorityList = fnGetList(pstruBuffer->pstruPacketlist, Priority_Medium);
755 nCount[2] = pstruMediumPriorityList->nPacketId * 3;
756
757 pstruHighPriorityList = fnGetList(pstruBuffer->pstruPacketlist, Priority_High);
758 nCount[3] = pstruHighPriorityList->nPacketId * 4;
759
760 nPosition = fn_NetSim_GetPosition_MaximumNumber(nCount);
761
762 pstruTempList = pstruBuffer->pstruPacketlist + nPosition;
763
764 if (pstruTempList && pstruTempList->pstruNextPacket)
765 {
766 pstruTempList->nPacketId--;
767 pstruTemp = pstruTempList->pstruNextPacket;
768 if (nFlag)
769 {
770 pstruTempList->pstruNextPacket = pstruTemp->pstruNextPacket;
771 pstruTemp->pstruNextPacket = NULL;
772 }
773 else
774 pstruTempList->nPacketId++;
775 return pstruTemp;
776 }
777 else
778 return NULL;
779 }
780 default:
781 printf("\nInvalid Selection in Buffer\n");
782 break;
783 }
784 return 0;
785}
786
787/** Helper function for EDF Scheduling Technique **/
789{
790 ptrSCHEDULING_EDF_VAR scheduling_var = pstruBuffer->schedulingParam;
791
792 NetSim_PACKET* pstruPacket_prev;
793 NetSim_PACKET* pstruPacket_itr;
794 NetSim_PACKET* pstruPacket_drop;
795 int index;
796 double curr_max_latency;
797 double curr_deadline;
798
799 pstruPacket_itr = pstruBuffer->pstruPacketlist;
800 pstruPacket_prev = pstruBuffer->pstruPacketlist;
801
802 while (pstruPacket_itr)
803 {
804 index = pstruPacket_itr->nQOS - 1;
805 if (index != -1)
806 {
807 curr_max_latency = *(scheduling_var->max_latency + index) * 1000;
808 curr_deadline = curr_max_latency - (pstruEventDetails->dEventTime -
809 pstruPacket_itr->dEventTime);
810 if (curr_deadline < 0)
811 {
812 //drop packet from buffer
813 pstruPacket_drop = pstruPacket_itr;
814 if (pstruBuffer->pstruPacketlist == pstruPacket_itr)
815 {
816 pstruPacket_itr = pstruPacket_itr->pstruNextPacket;
817 pstruPacket_prev = pstruPacket_itr;
818 pstruBuffer->pstruPacketlist = pstruPacket_itr;
819 if (pstruPacket_itr == NULL)
820 pstruBuffer->last = NULL;
821 }
822 else
823 {
824 pstruPacket_itr = pstruPacket_itr->pstruNextPacket;
825 pstruPacket_prev->pstruNextPacket = pstruPacket_itr;
826 if (pstruPacket_itr == NULL)
827 pstruBuffer->last = pstruPacket_prev;
828 }
829 fn_NetSim_DropPackets(pstruBuffer, pstruPacket_drop);
830 continue;
831 }
832 }
833 pstruPacket_prev = pstruPacket_itr;
834 pstruPacket_itr = pstruPacket_itr->pstruNextPacket;
835 }
836}
837
838/** Helper function for EDF Scheduling Technique **/
840{
841 ptrSCHEDULING_EDF_VAR scheduling_var = pstruBuffer->schedulingParam;
842
843 NetSim_PACKET* pstruPacket_itr;
844 NetSim_PACKET* pstruPacket = NULL;
845 int index;
846 double curr_max_latency;
847 double curr_deadline;
848 double earliest_deadline = (double)0xFFFFFFFFFFFFFFFF;
849
850 pstruPacket_itr = pstruBuffer->pstruPacketlist;
851 while (pstruPacket_itr)
852 {
853 index = pstruPacket_itr->nQOS - 1;
854 if (index == -1)
855 return pstruPacket_itr;
856
857 curr_max_latency = *(scheduling_var->max_latency + index) * 1000;
858 curr_deadline = curr_max_latency - (pstruEventDetails->dEventTime -
859 pstruPacket_itr->dEventTime);
860 if (curr_deadline < earliest_deadline)
861 {
862 pstruPacket = pstruPacket_itr;
863 earliest_deadline = curr_deadline;
864 }
865 pstruPacket_itr = pstruPacket_itr->pstruNextPacket;
866 }
867 return pstruPacket;
868}
869
870/**
871If the type is ADD, then all the packets will be added in the buffer based on arrival
872If the type is GET, then the expired packets are dropped from buffer and earliest deadline packet is served from the buffer
873*/
875 int nType, int nFlag)
876{
877 ptrSCHEDULING_EDF_VAR scheduling_var = pstruBuffer->schedulingParam;
878 NetSim_PACKET* p = pstruData;
879 while (p && p->pstruNextPacket)
880 p = p->pstruNextPacket;
881
882 switch (nType)
883 {
884 case ADD:
885 if (pstruBuffer->pstruPacketlist)
886 {
887 pstruBuffer->last->pstruNextPacket = pstruData;
888 pstruBuffer->last = p;
889 }
890 else
891 {
892 pstruBuffer->pstruPacketlist = pstruData;
893 pstruBuffer->last = p;
894 }
895 break;
896 case GET:
897 {
898 NetSim_PACKET* pstruPacket;
900 pstruPacket = edf_algorithm_get_earliest_deadline_packet(pstruBuffer);
901
902 if (nFlag && pstruPacket != NULL)
903 {
904 NetSim_PACKET* pstruPacket_itr = pstruBuffer->pstruPacketlist;
905
906 if (pstruPacket_itr == pstruPacket)
907 {
908 pstruBuffer->pstruPacketlist = pstruPacket->pstruNextPacket;
909 if (pstruBuffer->pstruPacketlist == NULL)
910 pstruBuffer->last = NULL;
911 }
912 else
913 {
914 while (pstruPacket_itr->pstruNextPacket != pstruPacket)
915 pstruPacket_itr = pstruPacket_itr->pstruNextPacket;
916 pstruPacket_itr->pstruNextPacket = pstruPacket->pstruNextPacket;
917 if (pstruPacket_itr->pstruNextPacket == NULL)
918 pstruBuffer->last = pstruPacket_itr;
919 }
920 pstruPacket->pstruNextPacket = NULL;
921 }
922 return pstruPacket;
923 break;
924 }
925 default:
926 printf("\nInvalid selection in Buffer\n");
927 break;
928 }
929 return 0;
930}
unsigned int NETSIM_ID
Definition: Animation.h:45
#define UINT64
Definition: Linux.h:37
#define UINT
Definition: Linux.h:38
#define _declspec(dllexport)
This function is used to trigger the update.
Definition: Linux.h:41
#define fnNetSimError(x,...)
Definition: Linux.h:56
#define fnpAllocateMemory(count, size)
Definition: Memory.h:34
void add_plot_data_formatted(PNETSIMPLOT g, char *format,...)
PNETSIMPLOT fn_NetSim_Install_Metrics_Plot(PLOT_TYPE plotType, char *menuName, char *heading,...)
@ Plot_Buffer
Definition: NetSim_Plot.h:25
enum_BUFFER
Definition: Packet.h:119
@ Buffer_Underflow
Definition: Packet.h:120
@ Buffer_Overflow
Definition: Packet.h:121
@ Priority_Normal
Definition: Packet.h:80
@ Priority_High
Definition: Packet.h:82
@ Priority_Low
Definition: Packet.h:79
@ Priority_Medium
Definition: Packet.h:81
@ PacketStatus_Buffer_Dropped
Definition: Packet.h:104
static void add_current_size_buffer(NetSim_BUFFER *pstruBuffer, NetSim_PACKET *pstruData)
Definition: Scheduling.c:317
NetSim_PACKET * fn_NetSim_GetPacketFromBuffer(NetSim_BUFFER *pstruBuffer, int nFlag)
Definition: Scheduling.c:168
static void * init_buffer_plot(NETSIM_ID d, NETSIM_ID in)
Definition: Scheduling.c:31
enum enum_BUFFER fn_NetSim_DropTail(NetSim_BUFFER *, NetSim_PACKET *)
Definition: Scheduling.c:307
#define fnGetList(pstruPacketlist, Priority)
Definition: Scheduling.c:11
bool fn_NetSim_GetBufferStatus(NetSim_BUFFER *)
Definition: Scheduling.c:41
static void edf_algorithm_drop_expired_packets(NetSim_BUFFER *pstruBuffer)
Definition: Scheduling.c:788
NetSim_PACKET * fn_NetSim_Priority(NetSim_BUFFER *, NetSim_PACKET *, int, int)
Definition: Scheduling.c:512
UINT64 fn_NetSim_GetPosition_MaximumNumber(UINT64 *nCount)
Definition: Scheduling.c:243
static void reduce_current_size_buffer(NetSim_BUFFER *pstruBuffer, NetSim_PACKET *pstruData)
Definition: Scheduling.c:336
enum enum_BUFFER fn_NetSim_WRED(NetSim_BUFFER *, NetSim_PACKET *)
Definition: Scheduling.c:454
enum enum_BUFFER fn_NetSim_CheckBuffer(NetSim_BUFFER *, NetSim_PACKET *)
Definition: Scheduling.c:276
enum_Buffer_Manipulation_Type
Definition: Scheduling.c:7
@ GET
Definition: Scheduling.c:9
@ ADD
Definition: Scheduling.c:8
enum enum_Buffer fn_NetSim_Queuing(NetSim_BUFFER *pstruBuffer, NetSim_PACKET *pstruData)
Definition: Scheduling.c:76
NetSim_PACKET * fn_NetSim_EDF(NetSim_BUFFER *, NetSim_PACKET *, int, int)
Definition: Scheduling.c:874
static NetSim_PACKET * edf_algorithm_get_earliest_deadline_packet(NetSim_BUFFER *pstruBuffer)
Definition: Scheduling.c:839
NetSim_PACKET * fn_NetSim_FIFO(NetSim_BUFFER *, NetSim_PACKET *, int, int)
Definition: Scheduling.c:577
enum enum_BUFFER fn_NetSim_RED(NetSim_BUFFER *, NetSim_PACKET *)
Definition: Scheduling.c:388
static enum enum_BUFFER red_algorithm(NetSim_BUFFER *pstruBuffer, NetSim_PACKET *pstruData)
Definition: Scheduling.c:353
static void fn_NetSim_DropPackets(NetSim_BUFFER *, NetSim_PACKET *)
Definition: Scheduling.c:262
static enum enum_BUFFER wred_algorithm(NetSim_BUFFER *pstruBuffer, NetSim_PACKET *pstruData, double max_th, double min_th, double max_p, int *count, double *random)
Definition: Scheduling.c:419
NetSim_PACKET * fn_NetSim_RoundRobin(NetSim_BUFFER *, NetSim_PACKET *, int, int)
Definition: Scheduling.c:620
NetSim_PACKET * fn_NetSim_WFQ(NetSim_BUFFER *, NetSim_PACKET *, int, int)
Definition: Scheduling.c:701
int fn_NetSim_Packet_AddPacketToBuffer(NetSim_BUFFER *pstruBuffer, NetSim_PACKET *pstruData)
Definition: Scheduling.c:104
enum enum_QueuingTechnique QUEUINGTECHNIQUE
#define DEVICE_NAME(DeviceId)
Definition: Stack.h:774
@ SCHEDULING_ROUNDROBIN
Definition: Stack.h:347
@ SCHEDULING_EDF
Definition: Stack.h:349
@ SCHEDULING_PRIORITY
Definition: Stack.h:346
@ SCHEDULING_WFQ
Definition: Stack.h:348
@ SCHEDULING_FIFO
Definition: Stack.h:345
#define DEVICE_INTERFACE_CONFIGID(DeviceId, InterfaceId)
Definition: Stack.h:781
@ QUEUING_DROPTAIL
Definition: Stack.h:356
@ QUEUING_RED
Definition: Stack.h:357
@ QUEUING_WRED
Definition: Stack.h:358
EXPORTED struct stru_NetSim_EventDetails * pstruEventDetails
Definition: Stack.h:837
#define NETSIM_RAND_01()
Definition: Stack.h:860
enum enum_SchedulingType SCHEDULING_TYPE
Definition: main.h:143
#define fn_NetSim_Packet_FreePacket(pstruPacket)
Definition: main.h:177
#define fn_NetSim_WritePacketTrace(pstruPacket)
Definition: main.h:188
enum enum_PacketPriority PACKET_PRIORITY
Definition: main.h:126
unsigned int nDroppedPacket
Definition: Stack.h:584
SCHEDULING_TYPE nSchedulingType
Definition: Stack.h:574
struct stru_NetSim_Packet * last
Definition: Stack.h:586
unsigned int nQueuedPacket
Definition: Stack.h:582
NETSIM_ID interfaceId
Definition: Stack.h:569
QUEUINGTECHNIQUE queuingTechnique
Definition: Stack.h:575
struct stru_NetSim_Packet * pstruPacketlist
Definition: Stack.h:585
unsigned int nDequeuedPacket
Definition: Stack.h:583
NETSIM_ID nDeviceId
Definition: Stack.h:750
long long int nPacketId
Definition: Packet.h:256
PACKET_STATUS nPacketStatus
Definition: Packet.h:272
struct stru_NetSim_Packet_NetworkLayer * pstruNetworkData
Definition: Packet.h:275
double dEventTime
Definition: Packet.h:262
NETSIM_ID nReceiverId
Definition: Packet.h:266
struct stru_NetSim_Packet * pstruNextPacket
Definition: Packet.h:278
NETSIM_ID nTransmitterId
Definition: Packet.h:265
QUALITY_OF_SERVICE nQOS
Definition: Packet.h:261
PACKET_PRIORITY nPacketPriority
Definition: Packet.h:260
struct stru_NetSim_Packet_MACLayer * pstruMacData
Definition: Packet.h:276
double avg_queue_size
Definition: Scheduling.h:35
double random_value
Definition: Scheduling.h:37
double * max_th
Definition: Scheduling.h:45
double * max_p
Definition: Scheduling.h:46
double * min_th
Definition: Scheduling.h:44
double avg_queue_size
Definition: Scheduling.h:47
double * random_value
Definition: Scheduling.h:49
double * max_latency
Definition: Scheduling.h:56