uploaded src files

This commit is contained in:
Abhishek Sagar
2016-12-02 18:52:54 +05:30
committed by GitHub
parent d78559a014
commit d38fa11385
9 changed files with 1043 additions and 0 deletions

275
WheelTimer/LinkedListApi.c Normal file
View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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