📄 timer_queue.c
字号:
} else { // Set the timer to the actual seconds / microseconds from now //This is a fix for an error that occurs on ARM Linux Kernels because they do 64bits differently //Thanks to S. Peter Li for coming up with this fix! numerator = ( tv - currtime ); remainder = do_div( numerator, 1000 ); delay_time.tv_sec = numerator; delay_time.tv_usec = remainder * 1000; } } if (!timer_pending(&aodv_timer)) { aodv_timer.function=&timer_queue_signal; aodv_timer.expires=jiffies + tvtojiffies(&delay_time); add_timer(&aodv_timer); } else { mod_timer(&aodv_timer,jiffies + tvtojiffies(&delay_time)); } /* lock Read */ timer_read_unlock(); // Set the timer (in real time) return;}/**************************************************** timer_queue_signal----------------------------------------------------Gets called when the system alarm goes off. Thefunction then pulls the first queued event andacts on it****************************************************/void timer_queue_signal(){ struct timer_queue_entry *tmp_entry; u_int64_t currtime; // Get the first due entry in the queue / currtime = getcurrtime(); tmp_entry = find_first_timer_queue_entry_due(currtime); // While there is still events that has timed out while (tmp_entry != NULL) { switch (tmp_entry->flags) { case EVENT_RREQ: timer_rreq(tmp_entry); break; case EVENT_HELLO: hello_resend(tmp_entry); break; case EVENT_CLEANUP: timer_cleanup(); break; case EVENT_NEIGHBOR: timer_neighbor(tmp_entry); break; default: break; } // Dequeue the entry so that it will not happened again // delete_timer_queue_entry(tmp_entry); kfree(tmp_entry); // Get new time and check for more timedout entrys currtime = getcurrtime(); tmp_entry = find_first_timer_queue_entry_due(currtime); } update_timer_queue();}/**************************************************** insert_timer_queue_entry----------------------------------------------------Insert an event into the queue. Also allocatesenough room for the data and copies that too****************************************************/int insert_timer_queue_entry(u_int64_t msec,void *data,int size,u_int32_t id,u_int16_t retries,u_int8_t ttl,unsigned char flags){ struct timer_queue_entry *prev_entry; struct timer_queue_entry *tmp_entry; struct timer_queue_entry *new_entry; // get memory if ((new_entry = kmalloc(sizeof(struct timer_queue_entry), GFP_ATOMIC)) == NULL) { printk(KERN_WARNING "AODV: Error allocating timer!\n"); return -ENOMEM; } // copy data new_entry->tv = msec; new_entry->id = id; new_entry->flags = flags; new_entry->retries=retries; new_entry->ttl=ttl; new_entry->size=size; new_entry->data=data; prev_entry=NULL; /* lock Write */ timer_write_lock(); tmp_entry=timer_queue; while (tmp_entry!=NULL && new_entry->tv > tmp_entry ->tv) { prev_entry=tmp_entry; tmp_entry=tmp_entry->next; } if (timer_queue==tmp_entry) { new_entry->next=timer_queue; timer_queue=new_entry; } else { if (tmp_entry==NULL) // If at the end of the List { new_entry->next=NULL; prev_entry->next=new_entry; } else // Inserting in to the middle of the list somewhere { new_entry->next=prev_entry->next; prev_entry->next=new_entry; } } /* unlock Write */ timer_write_unlock(); // Update the timer to reflect the new situation // update_timer_queue(); return 0;}/**************************************************** find_first_timer_queue_entry----------------------------------------------------Returns the first entry in the timer queue****************************************************/struct timer_queue_entry *find_first_timer_queue_entry(){ return timer_queue;}/**************************************************** find_first_timer_queue_entry_of_id----------------------------------------------------Returns the first timer queue entry with a matchingID****************************************************/struct timer_queue_entry * find_first_timer_queue_entry_of_id(u_int32_t id){ struct timer_queue_entry *tmp_entry; /* lock Read */ timer_read_lock(); tmp_entry=timer_queue; while (tmp_entry != NULL && tmp_entry->id != id) tmp_entry=tmp_entry->next; /* unlock Read */ timer_read_unlock(); return tmp_entry;}/**************************************************** find_first_timer_queue_entry_of_id_and_flag----------------------------------------------------Returns the first timer queue entry with a matchingID and flag****************************************************/struct timer_queue_entry * find_first_timer_queue_entry_of_id_and_flag(u_int32_t id, unsigned char flags){ struct timer_queue_entry *tmp_entry; /* lock Read */ timer_read_lock(); tmp_entry=timer_queue; while (tmp_entry != NULL && tmp_entry->id != id && tmp_entry->flags!=flags) tmp_entry=tmp_entry->next; /* unlock Read */ timer_read_unlock(); return tmp_entry;}/**************************************************** delete_timer_queue_entry_of_id----------------------------------------------------Deletes the first entry with a matching id****************************************************/void delete_timer_queue_entry_of_id(u_int32_t id, unsigned char flags){ struct timer_queue_entry *tmp_entry; struct timer_queue_entry *prev_entry; struct timer_queue_entry *dead_entry; int deleted=0; /* lock Write */ timer_write_lock(); tmp_entry=timer_queue; prev_entry=NULL; while (tmp_entry != NULL) { if (tmp_entry->id == id && tmp_entry->flags == flags) { if (prev_entry==NULL) timer_queue=tmp_entry->next; else prev_entry->next=tmp_entry->next; dead_entry=tmp_entry; tmp_entry=tmp_entry->next; kfree(dead_entry->data); kfree(dead_entry); deleted=1; } else { prev_entry=tmp_entry; tmp_entry=tmp_entry->next; } } // if (!deleted) // printk(KERN_WARNING "Faild to delete %s - %d\n",inet_ntoa(id),flags); /* unlock Write */ timer_write_unlock(); update_timer_queue();}/**************************************************** delete_timer_queue_entry----------------------------------------------------Deletes the entry from the timer queue. Youhave to do this so the linked list is not broken****************************************************/int delete_timer_queue_entry(struct timer_queue_entry *dead_entry){ struct timer_queue_entry *tmp_entry; struct timer_queue_entry *prev_entry; /* Is first element */ /* lock Write */ timer_write_lock(); tmp_entry=timer_queue; prev_entry=NULL; while (tmp_entry!=NULL && tmp_entry!=dead_entry) { prev_entry=tmp_entry; tmp_entry=tmp_entry->next; } if (tmp_entry==NULL) { printk(KERN_WARNING "AODV: Could not find Timer Queue Entry to delete!\n"); timer_write_unlock(); return 1; } if (prev_entry==NULL) timer_queue=tmp_entry->next; else prev_entry->next=tmp_entry->next; //kfree(tmp_entry->data); kfree(tmp_entry); //update_timer_queue(); /* unlock Write */ timer_write_unlock(); return 0;}/**************************************************** remove_first_timer_queue_entry----------------------------------------------------Removes the first timer queue entry****************************************************/void remove_first_timer_queue_entry(){ struct timer_queue_entry *dead_entry; /* lock Write */ timer_write_lock(); if (timer_queue!=NULL) { dead_entry=timer_queue; timer_queue=timer_queue->next; kfree(dead_entry); } /* unlock Write */ timer_write_unlock();}/**************************************************** find_first_timer_queue_entry_due----------------------------------------------------Returns the first entry in the queue that has a timethat is lower than the argument ie. the first elementif the argument is greater than its tv value.****************************************************/struct timer_queue_entry *find_first_timer_queue_entry_due(u_int64_t tv){ struct timer_queue_entry *tmp_entry; /* lock Read */ timer_read_lock(); if (timer_queue != NULL) { /* If pqe's time is in teh interval */ if ((timer_queue->tv) < tv) { tmp_entry=timer_queue; timer_queue=timer_queue->next; return tmp_entry; } } /* unlock read */ timer_read_unlock(); return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -