mirror of
https://github.com/Hizenberg469/WheelTimer.git
synced 2026-04-19 18:52:22 +03:00
uploaded src files
This commit is contained in:
275
WheelTimer/LinkedListApi.c
Normal file
275
WheelTimer/LinkedListApi.c
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include "LinkedListApi.h"
|
||||||
|
#include <assert.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){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
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){
|
||||||
|
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
|
||||||
39
WheelTimer/LinkedListApi.h
Normal file
39
WheelTimer/LinkedListApi.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef __LINKEDLIST__
|
||||||
|
#define __LINKEDLIST__
|
||||||
|
|
||||||
|
|
||||||
|
#define GET_HEAD_SINGLY_LL(ll) (ll->head)
|
||||||
|
#define INC_NODE_COUNT_SINGLY_LL(ll) (ll->node_count++)
|
||||||
|
#define DEC_NODE_COUNT_SINGLY_LL(ll) (ll->node_count--)
|
||||||
|
#define GET_NODE_COUNT_SINGLY_LL(ll) (ll->node_count)
|
||||||
|
#define GET_NEXT_NODE_SINGLY_LL(node) (node->next)
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
LL_FALSE,
|
||||||
|
LL_TRUE
|
||||||
|
} bool_t;
|
||||||
|
|
||||||
|
typedef struct LL_Node{
|
||||||
|
void *data;
|
||||||
|
struct LL_Node *next;
|
||||||
|
} singly_ll_node_t;
|
||||||
|
|
||||||
|
typedef struct LL{
|
||||||
|
unsigned int node_count;
|
||||||
|
singly_ll_node_t *head;
|
||||||
|
} ll_t;
|
||||||
|
|
||||||
|
ll_t* init_singly_ll();
|
||||||
|
singly_ll_node_t* singly_ll_init_node(void* data);
|
||||||
|
int singly_ll_add_node(ll_t *ll, singly_ll_node_t *node);
|
||||||
|
int singly_ll_add_node_by_val(ll_t *ll, void* data);
|
||||||
|
int singly_ll_remove_node(ll_t *ll, singly_ll_node_t *node);
|
||||||
|
unsigned int singly_ll_remove_node_by_value(ll_t *ll, void* data, int size);
|
||||||
|
bool_t is_singly_ll_empty(ll_t *ll);
|
||||||
|
void print_singly_LL(ll_t *ll);
|
||||||
|
void reverse_singly_ll(ll_t *ll);
|
||||||
|
void delete_singly_ll(ll_t *ll);
|
||||||
|
int singly_ll_delete_node(ll_t *ll, singly_ll_node_t *node);
|
||||||
|
unsigned int singly_ll_delete_node_by_value(ll_t *ll, void *data, int size);
|
||||||
|
singly_ll_node_t *singly_ll_get_node_by_data_ptr(ll_t *ll, void *data);
|
||||||
|
#endif
|
||||||
14
WheelTimer/Makefile
Normal file
14
WheelTimer/Makefile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
LIBS=-lpthread
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS=-Wall -g
|
||||||
|
INCLUDES=-I .
|
||||||
|
SRC=WheelTimer.o threadApi.o main.o LinkedListApi.o
|
||||||
|
TARGET:exe
|
||||||
|
%.o:%.c
|
||||||
|
${CC} ${CFLAGS} -c ${INCLUDES} $<
|
||||||
|
exe:$(SRC)
|
||||||
|
${CC} ${CFLAGS} $(SRC) -o exe $(LIBS)
|
||||||
|
clean:
|
||||||
|
rm *.o
|
||||||
|
rm exe
|
||||||
|
|
||||||
190
WheelTimer/WheelTimer.c
Normal file
190
WheelTimer/WheelTimer.c
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
#include "WheelTimer.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "LinkedListApi.h"
|
||||||
|
|
||||||
|
#define TH_JOINABLE 1
|
||||||
|
#define TH_DETACHED 0
|
||||||
|
|
||||||
|
extern blocked_pool_t gl_blocked_th_pool;
|
||||||
|
|
||||||
|
wheel_timer_t*
|
||||||
|
init_wheel_timer(int wheel_size, int clock_tic_interval){
|
||||||
|
wheel_timer_t *wt = calloc(1, sizeof(wheel_timer_t) +
|
||||||
|
wheel_size*sizeof(ll_t *));
|
||||||
|
|
||||||
|
wt->clock_tic_interval = clock_tic_interval;
|
||||||
|
wt->wheel_size = wheel_size;
|
||||||
|
|
||||||
|
pthread_mutex_init(&wt->wheel_timer_mutex, NULL);
|
||||||
|
wt->wheel_thread = calloc(1, sizeof(_pthread_t));
|
||||||
|
pthread_init(wt->wheel_thread, 0, TH_DETACHED);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for(; i < wheel_size; i++)
|
||||||
|
wt->slots[i] = init_singly_ll();
|
||||||
|
|
||||||
|
return wt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void*
|
||||||
|
wheel_fn(void *arg){
|
||||||
|
|
||||||
|
wheel_timer_t *wt = (wheel_timer_t *)arg;
|
||||||
|
wheel_timer_elem_t *wt_elem = NULL;
|
||||||
|
int absolute_slot_no = 0, i =0;
|
||||||
|
ll_t *slot_list = NULL;
|
||||||
|
singly_ll_node_t *head = NULL, *next_node = NULL;
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
wt->current_clock_tic++;
|
||||||
|
wt->current_clock_tic = (wt->current_clock_tic % wt->wheel_size);
|
||||||
|
if(wt->current_clock_tic == 0)
|
||||||
|
wt->current_cycle_no++;
|
||||||
|
|
||||||
|
sleep(wt->clock_tic_interval);
|
||||||
|
tentative_wait(wt->wheel_thread, &wt->wheel_timer_mutex);
|
||||||
|
|
||||||
|
slot_list = wt->slots[wt->current_clock_tic];
|
||||||
|
head = GET_HEAD_SINGLY_LL(slot_list);
|
||||||
|
int node_count = GET_NODE_COUNT_SINGLY_LL(slot_list);
|
||||||
|
absolute_slot_no = GET_WT_CURRENT_ABS_SLOT_NO(wt);
|
||||||
|
printf("Wheel Timer Time = %d : ", absolute_slot_no * wt->clock_tic_interval);
|
||||||
|
if(!node_count)
|
||||||
|
printf("\n");
|
||||||
|
for(i = 0; i < node_count; i++){
|
||||||
|
next_node = GET_NEXT_NODE_SINGLY_LL(head);
|
||||||
|
wt_elem = (wheel_timer_elem_t *)head->data;
|
||||||
|
if(wt->current_cycle_no == wt_elem->execute_cycle_no){
|
||||||
|
wt_elem->app_callback(wt_elem->arg, wt_elem->arg_size);
|
||||||
|
if(wt_elem->is_recurrence){
|
||||||
|
/*relocate*/
|
||||||
|
int next_abs_slot_no = absolute_slot_no + (wt_elem->time_interval/wt->clock_tic_interval);
|
||||||
|
int next_cycle_no = next_abs_slot_no / wt->wheel_size;
|
||||||
|
int next_slot_no = next_abs_slot_no % wt->wheel_size;
|
||||||
|
wt_elem->execute_cycle_no = next_cycle_no;
|
||||||
|
if(next_slot_no == wt->current_clock_tic){
|
||||||
|
head = next_node;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
singly_ll_remove_node(slot_list, head);
|
||||||
|
singly_ll_add_node(wt->slots[next_slot_no], head);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
free_wheel_timer_element((wheel_timer_elem_t *)head->data);
|
||||||
|
singly_ll_delete_node(slot_list, head);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
head = next_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
register_app_event(wheel_timer_t *wt,
|
||||||
|
app_call_back call_back,
|
||||||
|
void *arg,
|
||||||
|
int arg_size,
|
||||||
|
int time_interval,
|
||||||
|
char is_recursive){
|
||||||
|
|
||||||
|
if(!wt || !call_back) return ;
|
||||||
|
wheel_timer_elem_t *wt_elem = calloc(1, sizeof(wheel_timer_elem_t));
|
||||||
|
|
||||||
|
wt_elem->time_interval = time_interval;
|
||||||
|
wt_elem->app_callback = call_back;
|
||||||
|
wt_elem->arg = calloc(1, arg_size);
|
||||||
|
memcpy(wt_elem->arg, arg, arg_size);
|
||||||
|
wt_elem->arg_size = arg_size;
|
||||||
|
wt_elem->is_recurrence = is_recursive;
|
||||||
|
|
||||||
|
/*Stop the Wheel timer Thread here*/
|
||||||
|
pause_wheel_timer(wt);
|
||||||
|
|
||||||
|
int wt_absolute_slot = GET_WT_CURRENT_ABS_SLOT_NO(wt);
|
||||||
|
int registration_next_abs_slot = wt_absolute_slot + (wt_elem->time_interval/wt->clock_tic_interval);
|
||||||
|
int cycle_no = registration_next_abs_slot / wt->wheel_size;
|
||||||
|
int slot_no = registration_next_abs_slot % wt->wheel_size;
|
||||||
|
wt_elem->execute_cycle_no = cycle_no;
|
||||||
|
singly_ll_add_node_by_val(wt->slots[slot_no], wt_elem);
|
||||||
|
//printf("Wheel Timer snapshot on New Registration\n");
|
||||||
|
//print_wheel_timer(wt);
|
||||||
|
|
||||||
|
resume_wheel_timer(wt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
free_wheel_timer_element(wheel_timer_elem_t *wt_elem){
|
||||||
|
free(wt_elem->arg);
|
||||||
|
free(wt_elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
print_wheel_timer(wheel_timer_t *wt){
|
||||||
|
int i = 0, j = 0;
|
||||||
|
ll_t* slot_list = NULL;
|
||||||
|
wheel_timer_elem_t *wt_elem = NULL;
|
||||||
|
singly_ll_node_t *head = NULL;
|
||||||
|
|
||||||
|
printf("Printing Wheel Timer DS\n");
|
||||||
|
printf("wt->current_clock_tic = %d\n", wt->current_clock_tic);
|
||||||
|
printf("wt->clock_tic_interval = %d\n", wt->clock_tic_interval);
|
||||||
|
printf("wt->wheel_size = %d\n", wt->wheel_size);
|
||||||
|
printf("wt->current_cycle_no = %d\n", wt->current_cycle_no);
|
||||||
|
printf("wt->wheel_thread = %p\n", wt->wheel_thread);
|
||||||
|
printf("printing slots : \n");
|
||||||
|
|
||||||
|
for(; i < wt->wheel_size; i++){
|
||||||
|
slot_list = wt->slots[i];
|
||||||
|
printf(" slot_list[%d] : count : %d\n", i, GET_NODE_COUNT_SINGLY_LL(slot_list));
|
||||||
|
head = GET_HEAD_SINGLY_LL(slot_list);
|
||||||
|
for(j = 0 ; j < GET_NODE_COUNT_SINGLY_LL(slot_list); j++){
|
||||||
|
wt_elem = (wheel_timer_elem_t *)head->data;
|
||||||
|
if(!wt_elem){
|
||||||
|
printf(" NULL\n");
|
||||||
|
head = GET_NEXT_NODE_SINGLY_LL(head);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf(" wt_elem->time_interval = %d\n", wt_elem->time_interval);
|
||||||
|
printf(" wt_elem->execute_cycle_no = %d\n", wt_elem->execute_cycle_no);
|
||||||
|
printf(" wt_elem->app_callback = %p\n", wt_elem->app_callback);
|
||||||
|
printf(" wt_elem->arg = %p\n", wt_elem->arg);
|
||||||
|
printf(" wt_elem->is_recurrence = %d\n", wt_elem->is_recurrence);
|
||||||
|
head = GET_NEXT_NODE_SINGLY_LL(head);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
start_wheel_timer(wheel_timer_t *wt){
|
||||||
|
|
||||||
|
_pthread_t *thread = wt->wheel_thread;
|
||||||
|
if (pthread_create(&thread->pthread_handle, &thread->attr, wheel_fn, (void*)wt))
|
||||||
|
{
|
||||||
|
printf("Wheel Timer Thread initialization failed, exiting ... \n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
reset_wheel_timer(wheel_timer_t *wt){
|
||||||
|
wt->current_clock_tic = 0;
|
||||||
|
wt->current_cycle_no = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pause_wheel_timer(wheel_timer_t *wt){
|
||||||
|
send_wait_order(wt->wheel_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
resume_wheel_timer(wheel_timer_t *wt){
|
||||||
|
signal_t(wt->wheel_thread);
|
||||||
|
}
|
||||||
72
WheelTimer/WheelTimer.h
Normal file
72
WheelTimer/WheelTimer.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#ifndef __WHEEL_TIMER__
|
||||||
|
#define __WHEEL_TIMER__
|
||||||
|
#include "threadApi.h"
|
||||||
|
|
||||||
|
typedef struct _wheel_timer_elem_t wheel_timer_elem_t;
|
||||||
|
typedef void (*app_call_back)(void *arg, int sizeof_arg);
|
||||||
|
typedef struct LL ll_t;
|
||||||
|
|
||||||
|
struct _wheel_timer_elem_t{
|
||||||
|
int time_interval;
|
||||||
|
int execute_cycle_no;
|
||||||
|
app_call_back app_callback;
|
||||||
|
void *arg;
|
||||||
|
int arg_size;
|
||||||
|
char is_recurrence;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _wheel_timer_t {
|
||||||
|
int current_clock_tic;
|
||||||
|
int clock_tic_interval;
|
||||||
|
int wheel_size;
|
||||||
|
int current_cycle_no;
|
||||||
|
_pthread_t *wheel_thread;
|
||||||
|
pthread_mutex_t wheel_timer_mutex;
|
||||||
|
ll_t *slots[0];
|
||||||
|
} wheel_timer_t;
|
||||||
|
|
||||||
|
wheel_timer_t*
|
||||||
|
init_wheel_timer(int wheel_size, int clock_tic_interval);
|
||||||
|
|
||||||
|
#define GET_WT_CURRENT_ABS_SLOT_NO(wt) ((wt->current_cycle_no * wt->wheel_size) + wt->current_clock_tic)
|
||||||
|
|
||||||
|
void
|
||||||
|
cleanup_wheel_timer(wheel_timer_t *wt);
|
||||||
|
|
||||||
|
void
|
||||||
|
register_app_event(wheel_timer_t *wt,
|
||||||
|
app_call_back call_back,
|
||||||
|
void *arg,
|
||||||
|
int arg_size,
|
||||||
|
int time_interval,
|
||||||
|
char is_recursive);
|
||||||
|
|
||||||
|
int
|
||||||
|
unregister_app_event(wheel_timer_t *wt,
|
||||||
|
app_call_back call_back,
|
||||||
|
int time_interval);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
free_wheel_timer_element(wheel_timer_elem_t *wt_elem);
|
||||||
|
|
||||||
|
void
|
||||||
|
print_wheel_timer(wheel_timer_t *wt);
|
||||||
|
|
||||||
|
void
|
||||||
|
start_wheel_timer(wheel_timer_t *wt);
|
||||||
|
|
||||||
|
void
|
||||||
|
pause_wheel_timer(wheel_timer_t *wt);
|
||||||
|
|
||||||
|
void
|
||||||
|
cancel_wheel_timer(wheel_timer_t *wt);
|
||||||
|
|
||||||
|
void
|
||||||
|
reset_wheel_timer(wheel_timer_t *wt);
|
||||||
|
|
||||||
|
void
|
||||||
|
resume_wheel_timer(wheel_timer_t *wt);
|
||||||
|
|
||||||
|
#endif
|
||||||
143
WheelTimer/main.c
Normal file
143
WheelTimer/main.c
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
#include "WheelTimer.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_NUMBER_APP_THREADS 1
|
||||||
|
#define WHEEL_SIZE 15
|
||||||
|
#define WHEEL_TIMER_CLOCK_TIC_INTERVAL 1 // sec
|
||||||
|
|
||||||
|
/*Import Library global Variables*/
|
||||||
|
extern blocked_pool_t gl_blocked_th_pool;
|
||||||
|
|
||||||
|
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
|
||||||
|
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){
|
||||||
|
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. Exit\n");
|
||||||
|
int choice;
|
||||||
|
scanf("%d", &choice);
|
||||||
|
switch(choice){
|
||||||
|
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) ? ");
|
||||||
|
scanf("%d", (int *)&is_recursive);
|
||||||
|
int time_interval;
|
||||||
|
printf("time_interval ? ");
|
||||||
|
scanf("%d", &time_interval);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
register_app_event(wt, wrapper_generate_ospf_hello,
|
||||||
|
(void *)&vlan_no, sizeof(vlan_no), time_interval, is_recursive);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
reset_wheel_timer(wt);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
exit(0);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv){
|
||||||
|
|
||||||
|
init_blocked_pool(&gl_blocked_th_pool, MAX_NUMBER_APP_THREADS);
|
||||||
|
wheel_timer_t *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;
|
||||||
|
}
|
||||||
|
|
||||||
7
WheelTimer/readme
Normal file
7
WheelTimer/readme
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
This is the simple demostration of WheelTimer in C
|
||||||
|
|
||||||
|
you should have gcc compiler installed to compile the project.
|
||||||
|
|
||||||
|
run 'make' to compile the project
|
||||||
|
|
||||||
|
run ./exe to launch the application
|
||||||
216
WheelTimer/threadApi.c
Normal file
216
WheelTimer/threadApi.c
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
#include "threadApi.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
blocked_pool_t gl_blocked_th_pool;
|
||||||
|
|
||||||
|
|
||||||
|
_pthread_t*
|
||||||
|
get_blocked_thread_from_pool(blocked_pool_t *block_pool){
|
||||||
|
int i ;
|
||||||
|
for (i = block_pool->pool_size -1; i >=0; i--){
|
||||||
|
if(block_pool->blocked_thread_collection[i])
|
||||||
|
return block_pool->blocked_thread_collection[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dump_block_pool(blocked_pool_t *block_pool){
|
||||||
|
printf("pool size = %d\n", block_pool->pool_size);
|
||||||
|
unsigned int i = 0;
|
||||||
|
for(;i < block_pool->pool_size; i++){
|
||||||
|
if(block_pool->blocked_thread_collection[i]){
|
||||||
|
printf("pool[%d] = %d\n", i, block_pool->blocked_thread_collection[i]->selfid);
|
||||||
|
dump_thread_DS(block_pool->blocked_thread_collection[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("block_pool->blocked_thread_collection[%d] = NULL\n", i );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
is_thread_in_block_pool(unsigned int thid, blocked_pool_t *block_pool){
|
||||||
|
int i ;
|
||||||
|
for (i = 0; i < block_pool->pool_size; i++)
|
||||||
|
{
|
||||||
|
if(block_pool->blocked_thread_collection[i] &&
|
||||||
|
block_pool->blocked_thread_collection[i]->selfid == thid){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
is_thread_in_block_pool_mutex(unsigned int thid, blocked_pool_t *block_pool){
|
||||||
|
int i ;
|
||||||
|
pthread_mutex_lock(&(block_pool->pool_mutex));
|
||||||
|
for (i = 0; i < block_pool->pool_size; i++)
|
||||||
|
{
|
||||||
|
if(block_pool->blocked_thread_collection[i] &&
|
||||||
|
block_pool->blocked_thread_collection[i]->selfid == thid){
|
||||||
|
pthread_mutex_unlock(&(block_pool->pool_mutex));
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&(block_pool->pool_mutex));
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_blocked_pool(blocked_pool_t *block_pool, unsigned int pool_size){
|
||||||
|
int i = 0;
|
||||||
|
block_pool->pool_size = pool_size;
|
||||||
|
for (i = 0; i < pool_size; i++)
|
||||||
|
block_pool->blocked_thread_collection[i] = NULL;
|
||||||
|
pthread_mutex_init(&(block_pool->pool_mutex), NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_empty_slot_from_pool(blocked_pool_t *block_pool){
|
||||||
|
int i;
|
||||||
|
for(i = block_pool->pool_size -1; i >=0; i--){
|
||||||
|
if(block_pool->blocked_thread_collection[i] == NULL)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
get_empty_slot_from_pool_mutex(blocked_pool_t *block_pool){
|
||||||
|
int i;
|
||||||
|
pthread_mutex_lock(&(block_pool->pool_mutex));
|
||||||
|
for(i = block_pool->pool_size -1; i >=0; i--){
|
||||||
|
if(block_pool->blocked_thread_collection[i] == NULL)
|
||||||
|
pthread_mutex_unlock(&(block_pool->pool_mutex));
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&(block_pool->pool_mutex));
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
remove_thread_from_pool(blocked_pool_t *block_pool, _pthread_t *thread){
|
||||||
|
int loc = -1;
|
||||||
|
if(thread->selfid > (block_pool->pool_size - 1)) return FAILURE;
|
||||||
|
pthread_mutex_lock(&(block_pool->pool_mutex));
|
||||||
|
if((loc = is_thread_in_block_pool(thread->selfid, block_pool)) > -1)
|
||||||
|
{
|
||||||
|
block_pool->blocked_thread_collection[loc] = NULL;
|
||||||
|
printf("thread %d is removed from gl_blocked_th_pool\n", thread->selfid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("thread %d already does not exist in gl_blocked_th_pool\n", thread->selfid);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&(block_pool->pool_mutex));
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dump_thread_DS(_pthread_t *thread)
|
||||||
|
{
|
||||||
|
printf("===================================\n");
|
||||||
|
printf("selfid = %d\n", thread->selfid);
|
||||||
|
printf("pthread_handle = %ld\n", thread->pthread_handle);
|
||||||
|
printf("isWaiting = %d\n", thread->isWaiting);
|
||||||
|
printf("resume_thread_id = %d\n", thread->resume_thread_id);
|
||||||
|
printf("attr = 0x%x\n", (unsigned int )&(thread->attr));
|
||||||
|
printf("cond = 0x%x\n", (unsigned int )&(thread->cond));
|
||||||
|
printf("===================================\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_pool_add(blocked_pool_t *block_pool, _pthread_t *thread)
|
||||||
|
{
|
||||||
|
int loc = -1;
|
||||||
|
if(thread->selfid > block_pool->pool_size -1) return -1;
|
||||||
|
loc = get_empty_slot_from_pool(block_pool);
|
||||||
|
if(loc > -1){
|
||||||
|
block_pool->blocked_thread_collection[loc] = thread;
|
||||||
|
printf("thread %d is added to gl_blocked_th_pool at index %d\n", thread->selfid, loc);
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
printf("gl_blocked_th_pool is full, thread %d cannot be added\n", thread->selfid);
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
add_thread_to_pool(blocked_pool_t *block_pool , _pthread_t *thread)
|
||||||
|
{
|
||||||
|
if (!block_pool) return -1;
|
||||||
|
int rc = SUCCESS;
|
||||||
|
pthread_mutex_lock(&block_pool->pool_mutex);
|
||||||
|
|
||||||
|
if(is_thread_in_block_pool(thread->selfid, block_pool) < 0)
|
||||||
|
{
|
||||||
|
rc = _pool_add(block_pool, thread);
|
||||||
|
pthread_mutex_unlock(&block_pool->pool_mutex);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Thread %d is already in blocked pool\n", thread->selfid);
|
||||||
|
pthread_mutex_unlock(&block_pool->pool_mutex);
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pthread_init(_pthread_t *_pthread, unsigned int tid, unsigned int JOINABLE)
|
||||||
|
{
|
||||||
|
_pthread->selfid = tid;
|
||||||
|
pthread_attr_init(&_pthread->attr);
|
||||||
|
JOINABLE ? pthread_attr_setdetachstate(&_pthread->attr, PTHREAD_CREATE_JOINABLE):
|
||||||
|
pthread_attr_setdetachstate(&_pthread->attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
pthread_cond_init(&_pthread->cond, NULL);
|
||||||
|
_pthread->isWaiting = FALSE;
|
||||||
|
_pthread->resume_thread_id = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup_pthread(_pthread_t *thread)
|
||||||
|
{
|
||||||
|
pthread_attr_destroy(&(thread->attr));
|
||||||
|
pthread_cond_destroy(&(thread->cond));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wait_t (_pthread_t *thread_to_block, pthread_mutex_t *mutex, unsigned int line_no){
|
||||||
|
pthread_mutex_lock(mutex);
|
||||||
|
thread_to_block->isWaiting = TRUE;
|
||||||
|
if(pthread_cond_wait (&(thread_to_block->cond), mutex)){
|
||||||
|
printf("pthread_cond_wait failed, thread id = %d, line_no = %d", thread_to_block->selfid, line_no);
|
||||||
|
thread_to_block->isWaiting = FALSE;
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
signal_t (_pthread_t *signalled_thread){
|
||||||
|
remove_thread_from_pool(&gl_blocked_th_pool, signalled_thread);
|
||||||
|
if(pthread_cond_signal(&(signalled_thread->cond))){
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
signalled_thread->isWaiting = FALSE;
|
||||||
|
signalled_thread->resume_thread_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tentative_wait(_pthread_t *thread, pthread_mutex_t *mutex){
|
||||||
|
if(is_thread_in_block_pool_mutex(0, &gl_blocked_th_pool) > -1)
|
||||||
|
wait_t(thread, mutex, __LINE__);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
send_wait_order(_pthread_t *thread){
|
||||||
|
add_thread_to_pool(&gl_blocked_th_pool, thread);
|
||||||
|
}
|
||||||
87
WheelTimer/threadApi.h
Normal file
87
WheelTimer/threadApi.h
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#ifndef __PTHREAD__
|
||||||
|
#define __PTHREAD__
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SUCCESS
|
||||||
|
#define SUCCESS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FAILURE
|
||||||
|
#define FAILURE -1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_POOL_SIZE 100
|
||||||
|
|
||||||
|
typedef struct _pthread_t_{
|
||||||
|
pthread_t pthread_handle;
|
||||||
|
unsigned int selfid;
|
||||||
|
char isWaiting;
|
||||||
|
unsigned int resume_thread_id;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_cond_t cond;
|
||||||
|
} _pthread_t;
|
||||||
|
|
||||||
|
typedef struct _pool_blocked_threads_{
|
||||||
|
unsigned int pool_size;
|
||||||
|
_pthread_t* blocked_thread_collection[MAX_POOL_SIZE];
|
||||||
|
pthread_mutex_t pool_mutex;
|
||||||
|
} blocked_pool_t;
|
||||||
|
|
||||||
|
void
|
||||||
|
dump_block_pool(blocked_pool_t *block_pool);
|
||||||
|
|
||||||
|
int
|
||||||
|
is_thread_in_block_pool(unsigned int thid, blocked_pool_t *block_pool);
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
is_thread_in_block_pool_mutex(unsigned int thid, blocked_pool_t *block_pool);
|
||||||
|
|
||||||
|
void
|
||||||
|
init_blocked_pool(blocked_pool_t *block_pool, unsigned int pool_size);
|
||||||
|
|
||||||
|
int
|
||||||
|
get_empty_slot_from_pool(blocked_pool_t *block_pool);
|
||||||
|
|
||||||
|
int
|
||||||
|
get_empty_slot_from_pool_mutex(blocked_pool_t *block_pool);
|
||||||
|
|
||||||
|
_pthread_t*
|
||||||
|
get_blocked_thread_from_pool(blocked_pool_t *block_pool);
|
||||||
|
|
||||||
|
int
|
||||||
|
remove_thread_from_pool(blocked_pool_t *block_pool , _pthread_t *thread);
|
||||||
|
|
||||||
|
int
|
||||||
|
add_thread_to_pool(blocked_pool_t *block_pool, _pthread_t *thread);
|
||||||
|
|
||||||
|
void
|
||||||
|
send_wait_order(_pthread_t *thread);
|
||||||
|
|
||||||
|
void
|
||||||
|
dump_thread_DS(_pthread_t *thread);
|
||||||
|
|
||||||
|
void
|
||||||
|
wait_t (_pthread_t *thread_to_block, pthread_mutex_t *mutex, unsigned int line_no);
|
||||||
|
|
||||||
|
void
|
||||||
|
signal_t (_pthread_t *signalled_thread);
|
||||||
|
|
||||||
|
void
|
||||||
|
pthread_init(_pthread_t *_pthread, unsigned int tid, unsigned int JOINABLE);
|
||||||
|
|
||||||
|
void
|
||||||
|
cleanup_pthread(_pthread_t *thread);
|
||||||
|
|
||||||
|
void tentative_wait(_pthread_t *thread, pthread_mutex_t *mutex);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user