Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 21

DEPARTMENT OF INFORMATION SCIENCE AND

ENGINEERING

Memory Management in Linux Kernal

DAA-UNIX EL COMPONENT

Under the guidance of

Swetha S and Bk Srinivas

Assistant professors

Dept. of ISE
RV College of Engineering
GROUP MEMBERS:

Name USN

Omkar Kabbur 1RV20IS028

Chetna Kumari 1RV20IS066

ACKNOWLEDGEMENT

The completion of this report could not have been possible without the assistance and
guidance of our professors, BK Srinivas and Swetha S. We cannot express enough
thanks for his continued support and supervision throughout this undertaking.

We would also like to express our deep sense of gratitude towards our HOD, Dr B.M
Sagar, and Principal, Dr K N Subramanya for giving us this opportunity and for their
guidance in the completion of our report. Lastly, we would also like to thank all the
faculty members for their constant encouragement and cooperation.

Dept of ISE, RVCE 2020-21 2


Contents
Serial number TITLE PAGE no:

1 ABSTRACT 4

2 INTRODUCTION 4

3 METHODOLOGY 5

4 IMPLEMENTATION 7

5 OUTPUT 19

6 CONCLUSION 21

Dept of ISE, RVCE 2020-21 3


ABSTRACT:

If there are a large number of scheduled tasks in a system, and each of the large number
of scheduled tasks uses its own scheduler to manage the life cycle of the task, it is
wasteful of cpu resources and inefficient. The time wheel is a scheduling model that
makes efficient use of thread resources for batch scheduling. It binds a large number of
scheduled tasks to a single scheduler and uses this scheduler to manage, trigger and
runnable all tasks. This allows for efficient management of various delayed tasks,
periodic tasks, notification tasks, etc.

INTRODUCTION:

Timers are important for:

Failure recovery, rate-based flow control, scheduling algorithms, controlling packet


lifetime in networks

Timer is a relatively early implementation that allows for fixed-period tasks, as well as
deferred tasks; Timer starts an asynchronous thread to execute a task when it is due, and
the task can be scheduled only once, or repeated several times periodically.
Timers have very many scenarios, which you should encounter frequently in your
normal work, such as generating monthly statistical reports, financial reconciliation,
membership points settlement, email push, etc., are all scenarios of timer usage.
Timers generally have three forms of performance: execution at a fixed period,
execution after a certain delay, and execution at a specified time.

The essence of a timer is to design a data structure that can store and schedule a
collection of tasks, and the closer the deadline, the higher the priority of the task. So
how does a timer know if a task is due or not? A timer needs to be polled to check if
a task is due every other time slice.

Dept of ISE, RVCE 2020-21 4


METHODOLOGY:

If there are a large number of scheduled tasks in a system, and each of the large number
of scheduled tasks uses its own scheduler to manage the life cycle of the task, it is
wasteful of CPU resources and inefficient. The time wheel is a scheduling model that
makes efficient use of thread resources for batch scheduling. It binds a large number of
scheduled tasks to a single scheduler and uses this scheduler to manage, trigger and
runnable all tasks. This allows for efficient management of various delayed tasks,
periodic tasks, notification tasks, etc.

So the internal structure of a timer typically requires a task queue and an asynchronous
polling thread, and can provide three basic operations.
 Schedule adds a task to the task collection.
 Cancel cancels a task.
 Run executes a task that is due.

Dept of ISE, RVCE 2020-21 5


A HELLO packet is a special data packet (message) that is sent out periodically
from a router to establish and confirm network adjacency relationships to other
routers in the Open Shortest Path First (OSPF) communications protocol. On
networks capable of broadcast or multicast transmission, a HELLO packet can
be sent from one router to all other routers simultaneously to discover
neighboring routes.
OSPF networks are made up of many interconnected routers. These routers are
connected on their interfaces. The HELLO packet is the method for routers to
announce to each other that they share an interface.

Dept of ISE, RVCE 2020-21 6


IMPLEMENTATION:

Main Application Code: -


//linkedlistapi.c
#include <stdlib.h>
#include <memory.h>
#include "LinkedListApi.h"
#include <assert.h>
#include<stdio.h>

ll_t* init_singly_ll(){
return calloc(1, sizeof(ll_t));
}

singly_ll_node_t* singly_ll_init_node(void* data){


singly_ll_node_t* node = calloc(1, sizeof(singly_ll_node_t));
node->data = data;
return node;
}

int
singly_ll_add_node(ll_t* ll, singly_ll_node_t *node){
if(!ll) return -1;
if(!node) return -1;
if(!GET_HEAD_SINGLY_LL(ll)){
GET_HEAD_SINGLY_LL(ll) = node;
INC_NODE_COUNT_SINGLY_LL(ll);
return 0;
}

node->next = GET_HEAD_SINGLY_LL(ll);
GET_HEAD_SINGLY_LL(ll) = node;
INC_NODE_COUNT_SINGLY_LL(ll);
return 0;
}

int
singly_ll_add_node_by_val(ll_t *ll, void* data){

Dept of ISE, RVCE 2020-21 7


singly_ll_node_t* node = singly_ll_init_node(data);
return singly_ll_add_node(ll, node);
}

int
singly_ll_delete_node(ll_t *ll, singly_ll_node_t *node){
if(!ll) return -1;
if(!GET_HEAD_SINGLY_LL(ll) || !node) return 0;
singly_ll_node_t *trav = NULL;
/*if node is not the last node*/
if(node->next){
singly_ll_node_t *temp = NULL;
node->data = node->next->data;
temp = node->next;
node->next = node->next->next;
free(temp);
DEC_NODE_COUNT_SINGLY_LL(ll);
return 0;
}

/* if node is the only node in LL*/


if(ll->node_count == 1 && GET_HEAD_SINGLY_LL(ll) == node){
free(node);
GET_HEAD_SINGLY_LL(ll) = NULL;
DEC_NODE_COUNT_SINGLY_LL(ll);
return 0;
}

/*if node is the last node of the LL*/


trav = GET_HEAD_SINGLY_LL(ll);
while(trav->next != node){
trav = trav->next;
continue;
}

trav->next = NULL;
free(node);
DEC_NODE_COUNT_SINGLY_LL(ll);
return 0;
}

Dept of ISE, RVCE 2020-21 8


int
singly_ll_remove_node(ll_t *ll, singly_ll_node_t *node){
if(!ll || !GET_HEAD_SINGLY_LL(ll)) return 0;
if(!node){
printf("%s(%d) : Error : node is NULL\n", __FUNCTION__, __LINE__);
return -1;
}
int i = 0;
singly_ll_node_t *head = GET_HEAD_SINGLY_LL(ll), *prev = NULL;

if(head == node){
GET_HEAD_SINGLY_LL(ll) = GET_NEXT_NODE_SINGLY_LL(head);
DEC_NODE_COUNT_SINGLY_LL(ll);
node->next = NULL;
return 0;
}

prev = head;
head = GET_NEXT_NODE_SINGLY_LL(head);
for(i =1; i < GET_NODE_COUNT_SINGLY_LL(ll); i++){
if(head != node){
prev = head;
head = GET_NEXT_NODE_SINGLY_LL(head);
continue;
}

prev->next = GET_NEXT_NODE_SINGLY_LL(head);
GET_NEXT_NODE_SINGLY_LL(head) = NULL;
DEC_NODE_COUNT_SINGLY_LL(ll);
node->next = NULL;
return 0;
}
printf("%s(%d) : Error : node not found\n", __FUNCTION__, __LINE__);
return -1;
}

unsigned int

Dept of ISE, RVCE 2020-21 9


singly_ll_delete_node_by_value(ll_t *ll, void *data, int size){
if(!ll || !GET_HEAD_SINGLY_LL(ll)) return 0;
unsigned int curren_node_count = GET_NODE_COUNT_SINGLY_LL(ll);
singly_ll_node_t* trav = GET_HEAD_SINGLY_LL(ll);
while(trav != NULL){
if(memcmp(trav->data, data, size) == 0){
singly_ll_delete_node(ll, trav);
return curren_node_count - GET_NODE_COUNT_SINGLY_LL(ll);
}
trav = trav->next;
}
return curren_node_count - GET_NODE_COUNT_SINGLY_LL(ll);
}

unsigned int
singly_ll_remove_node_by_value(ll_t *ll, void *data, int size){
if(!ll || !GET_HEAD_SINGLY_LL(ll)) return 0;
unsigned int curren_node_count = GET_NODE_COUNT_SINGLY_LL(ll);
singly_ll_node_t* trav = GET_HEAD_SINGLY_LL(ll);
while(trav != NULL){
if(memcmp(trav->data, data, size) == 0){
singly_ll_remove_node(ll, trav);
return curren_node_count - GET_NODE_COUNT_SINGLY_LL(ll);
}
trav = trav->next;
}
return curren_node_count - GET_NODE_COUNT_SINGLY_LL(ll);
}

singly_ll_node_t*
singly_ll_get_node_by_data_ptr(ll_t *ll, void *data){
if(!ll || !GET_HEAD_SINGLY_LL(ll)) return NULL;
int i = 0;
singly_ll_node_t *head = GET_HEAD_SINGLY_LL(ll);

for(; i < GET_NODE_COUNT_SINGLY_LL(ll); i++){


if(head->data == data)
return head;
head = GET_NEXT_NODE_SINGLY_LL(head);

Dept of ISE, RVCE 2020-21 10


}
return NULL;
}

void print_singly_LL(ll_t *ll){


if(!ll) {
printf("Invalid Linked List\n");
return;
}
if(is_singly_ll_empty(ll)){
printf("Empty Linked List\n");
return;
}

singly_ll_node_t* trav = GET_HEAD_SINGLY_LL(ll);


unsigned int i = 0;
printf("node count = %d\n", GET_NODE_COUNT_SINGLY_LL(ll));
while(trav){
printf("%d. Data = %p, node = %p\n", i, trav->data, trav);
i++;
trav = trav->next;
}
}

bool_t
is_singly_ll_empty(ll_t *ll){
if(!ll) assert(0);
if(ll->node_count == 0)
return LL_TRUE;
return LL_FALSE;
}

void
reverse_singly_ll(ll_t *ll){
if(!ll) assert(0) ;
if(is_singly_ll_empty(ll)) return;
if(GET_NODE_COUNT_SINGLY_LL(ll) == 1) return;
singly_ll_node_t *p1 = GET_HEAD_SINGLY_LL(ll),
*p2 = ll->head->next, *p3 = NULL;

Dept of ISE, RVCE 2020-21 11


p1->next = NULL;
do{
p3 = p2->next;
p2->next = p1;
p1 = p2;
p2 = p3;
}while(p3);
ll->head = p1;
return;
}

void
delete_singly_ll(ll_t *ll){
if(!ll) return;

if(is_singly_ll_empty(ll)){
return;
}

singly_ll_node_t *head = GET_HEAD_SINGLY_LL(ll),


*next = GET_NEXT_NODE_SINGLY_LL(head);

do{
free(head);
head = next;
if(next)
next = GET_NEXT_NODE_SINGLY_LL(next);

} while(head);

ll->node_count = 0;
ll->head = NULL;
}

#if 0
int
main(int argc, char **argv){

Dept of ISE, RVCE 2020-21 12


ll_t* list = init_singly_ll();
int n1 = 1;
singly_ll_add_node_by_val(list, &n1);
#if 1
int n2 =2;
singly_ll_add_node_by_val(list, &n2);
int n3 =3;
singly_ll_add_node_by_val(list, &n3);
int n4 =4;
singly_ll_add_node_by_val(list, &n4);
int n5 =5;
singly_ll_add_node_by_val(list, &n5);
int n6 =6;
singly_ll_add_node_by_val(list, &n6);
int n7 =7;
singly_ll_add_node_by_val(list, &n7);
int n8 = 8;
singly_ll_add_node_by_val(list, &n8);
int n9 = 9;
singly_ll_add_node_by_val(list, &n9);
int n10 = 10;
singly_ll_add_node_by_val(list, &n10);
#endif
print_singly_LL(list);

#if 1
int n = 5;
unsigned int num_nodes_removed = singly_ll_remove_node_by_value(list, &n, sizeof(int));
printf("number of noded removed = %d\n", num_nodes_removed);
print_singly_LL(list);
#endif
n = 1;
singly_ll_remove_node_by_value(list, &n, sizeof(int));
//reverse_singly_ll(list);
print_singly_LL(list);

return 0;

}
#endif

Dept of ISE, RVCE 2020-21 13


//
}

//main.c
#include <stdio.h>
#include <memory.h>
#include "WheelTimer.h"
//main.c

#define WHEEL_SIZE 60
#define WHEEL_TIMER_CLOCK_TIC_INTERVAL 1 // sec

wheel_timer_t *wt;

void
generate_general_query(int vlan){
static int count = 0;
printf("%s() : Query no : %d : general query is generated for vlan %d\n", __FUNCTION__, count++, vlan);
}

void wrapper_generate_general_query(void *arg, int arg_size){

int vlan = *(int *)arg;


generate_general_query(vlan);
}

void
generate_pim_hello(int vlan){
static int count = 0;
printf("%s() : Query no : %d : pim_hello is generated for vlan %d\n", __FUNCTION__, count++, vlan);
}

void
wrapper_generate_pim_hello(void *arg, int arg_size){
int vlan = *(int *)arg;
generate_pim_hello(vlan);
}

void

Dept of ISE, RVCE 2020-21 14


generate_ospf_hello(int vlan){
static int count = 0;
printf("%s() : Query no : %d : ospf_hello is generated for vlan %d\n", __FUNCTION__, count++, vlan);
}

void wrapper_generate_ospf_hello(void *arg, int arg_size){

int vlan = *(int *)arg;


generate_ospf_hello(vlan);
}

void
main_menu(wheel_timer_t *wt){
wheel_timer_elem_t *gq_wt_elem = NULL,
*pim_hello_wt_elem = NULL,
*ospf_hello_wt_elem = NULL;

do{
printf("\nMain Menu\n");
printf("*************\n");
printf("1. dump Wheel Timer\n");
printf("2. Register General Query Event\n");
printf("3. Register Pim Hello Event\n");
printf("4. Register Ospf Hello Event\n");
printf("5. Reset Wheel Timer\n");
printf("6. de-Register General Query Event\n");
printf("7. de-Register Pim Hello Event\n");
printf("8. de-Register Ospf Hello Event\n");
printf("9. Exit\n");
printf("10. Reschedule general query\n");
printf("11. Reschedule pim hello\n");
printf("12. Reschedule ospf hello\n");

int choice;
scanf("%d", &choice);
switch(choice){
case 10:
{
int new_time_interval = 0;
printf("Enter new time interval : ");

Dept of ISE, RVCE 2020-21 15


scanf("%d", &new_time_interval);
wt_elem_reschedule(wt, gq_wt_elem, new_time_interval);
}
break;
case 11:
{
int new_time_interval = 0;
printf("Enter new time interval : ");
scanf("%d", &new_time_interval);
wt_elem_reschedule(wt, pim_hello_wt_elem, new_time_interval);
}
break;
case 12:
{
int new_time_interval = 0;
printf("Enter new time interval : ");
scanf("%d", &new_time_interval);
wt_elem_reschedule(wt, ospf_hello_wt_elem, new_time_interval);
}

break;
case 6:
de_register_app_event(wt, gq_wt_elem);
gq_wt_elem = NULL;
break;
case 7:
de_register_app_event(wt, pim_hello_wt_elem);
break;
case 8:
de_register_app_event(wt, ospf_hello_wt_elem);
break;
case 1:
print_wheel_timer(wt);
break;
case 2:
{
int vlan_no;
printf("Enter vlan no : ");
scanf("%d", &vlan_no);
char is_recursive;
printf("Is Recirsive (1/0) ? ");

Dept of ISE, RVCE 2020-21 16


scanf("%d", (int *)&is_recursive);
int time_interval;
printf("time_interval ? ");
scanf("%d", &time_interval);
gq_wt_elem = register_app_event(wt, wrapper_generate_general_query,
(void *)&vlan_no, sizeof(vlan_no), time_interval, is_recursive);

}
break;
case 3:
{
int vlan_no;
printf("Enter vlan no : ");
scanf("%d", &vlan_no);
char is_recursive;
printf("Is Recirsive (1/0) ? ");
scanf("%d", (int *)&is_recursive);
int time_interval;
printf("time_interval ? ");
scanf("%d", &time_interval);
pim_hello_wt_elem = register_app_event(wt, wrapper_generate_pim_hello,
(void *)&vlan_no, sizeof(vlan_no), time_interval, is_recursive);

}
break;
case 4:
{
int vlan_no;
printf("Enter vlan no : ");
scanf("%d", &vlan_no);
char is_recursive;
printf("Is Recirsive (1/0) ? ");

scanf("%d", (int *)&is_recursive);


int time_interval;
printf("time_interval ? ");
scanf("%d", &time_interval);
ospf_hello_wt_elem = register_app_event(wt, wrapper_generate_ospf_hello,
(void *)&vlan_no, sizeof(vlan_no), time_interval, is_recursive);

Dept of ISE, RVCE 2020-21 17


}
break;

case 5:
reset_wheel_timer(wt);
break;
case 9:
exit(0);
default:
break;

}
}
while(1);
}

int
main(int argc, char **argv){

wt = init_wheel_timer(WHEEL_SIZE, WHEEL_TIMER_CLOCK_TIC_INTERVAL);
start_wheel_timer(wt);

/* WT thread is in DETACHED MODE, so below call is useless*/


//pthread_join(wt->wheel_thread->pthread_handle, &ret_val);

main_menu(wt);
return 0;
}

OUTPUT:

Dept of ISE, RVCE 2020-21 18


Dept of ISE, RVCE 2020-21 19
Dept of ISE, RVCE 2020-21 20
CONCLUSION:
The performance of timer algorithms is crucial to many network protocol
implementations that use timers for failure recovery and rate control. Conventional
algorithms to implement an Operating System timer module take O(n) time to start or
maintain a timer, where n is the number of outstanding timers: this is expensive for
large n. This paper shows that by using a circular buffer or timing wheel, it takes
O(1) time to start, stop, and maintain timers within the range of the wheel.
Readme FILE:
https://github.com/OmkarKabbur/wheeltime/blob/main/readme
GitHub link:
https://github.com/OmkarKabbur/WHEELTIME.git

Dept of ISE, RVCE 2020-21 21

You might also like