⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wxtimer.c

📁 wimax BS simulation code,implemented under linux.
💻 C
字号:
/* * This piece of code is totally free. If any pitfalls found,  * please feel free to contact me at jetmotor@21cn.com * THANKS A LOT! */#include <string.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include "que.h"#include "wxtimer.h"#define NR_WXTIMER_MAX		16static wxtimer_t * insert_timer(struct rb_root *root, wxtimer_t *new);static void rb_erase(struct rb_root *root, struct rb_node *node);static void rb_insert_color(struct rb_root *root, struct rb_node *node);static void rb_erase_color(struct rb_root *root, struct rb_node *node, struct rb_node *parent);static struct rb_node * rb_first(struct rb_root *root);static struct rb_node * rb_last(struct rb_root *root);static struct rb_node * rb_next(struct rb_node *node);static struct rb_node * rb_prev(struct rb_node *node);static void rb_link_node(struct rb_node *node, struct rb_node *parent, struct rb_node **rb_link);static void rb_rotate_left(struct rb_node *node, struct rb_root *root);static void rb_rotate_right(struct rb_node * node, struct rb_root * root);pool_t g_wxtmpool;uint32_t jiffies = 0;struct wxtimer_tree_s g_wxtmtree;int32_t wxtimer_init(){	pthread_mutex_init(&g_wxtmtree.mutex, NULL);	g_wxtmtree.rb_root.rb_node = g_wxtmtree.rb_first = NULL;	g_wxtmtree.nr = 0;	return 0;}int32_t wxtmpool_init(){	wxtimer_t *tm;	int32_t i;	pool_init(&g_wxtmpool);	for ( i = 0; i < NR_WXTIMER_MAX; i++ ) {		if ( (tm = (wxtimer_t *)malloc(sizeof(wxtimer_t))) == NULL )			return -1;		list_add_tail(&tm->link, &g_wxtmpool.link);		g_wxtmpool.count++;	}	return 0;}void * do_task_timer(void *arg){	struct rb_node *n;	for ( ; ; ) {		usleep(20000);///20000us		pthread_mutex_lock(&g_wxtmtree.mutex);		jiffies++;		n = g_wxtmtree.rb_first;		while ( n ) {			wxtimer_t *tm;			tm = rb_entry(n, wxtimer_t, rb_link);			if ( jiffies != tm->future )				break;			if ( tm->action )				tm->action(tm->arga, tm->argb);			rb_erase(&g_wxtmtree.rb_root, n);/*删除n 节点*/			n->rb_parent = n->rb_left = n->rb_right = NULL;			g_wxtmtree.nr--;			if ( tm->type == WXTIMER_PERIODIC ) {				tm->timestamp	= jiffies;		/*jiffies 是当前值,tm->count  是定时计数值												*tm->future 则是当前值加上计数值*/				tm->future	= jiffies + tm->count;								insert_timer(&g_wxtmtree.rb_root, tm);				rb_insert_color(&g_wxtmtree.rb_root, n);				g_wxtmtree.rb_first = rb_first(&g_wxtmtree.rb_root);				g_wxtmtree.nr++;			}			else {				put_timer(tm);			}			n = rb_first(&g_wxtmtree.rb_root);		}		g_wxtmtree.rb_first = n;//here n = NULL		pthread_mutex_unlock(&g_wxtmtree.mutex);	}	return NULL;}wxtimer_t * get_timer(uint8_t type, uint32_t count, uint32_t arga, void *argb, void (*action)(uint32_t arga, void *argb)){	wxtimer_t *tm;	pthread_mutex_lock(&g_wxtmpool.mutex);		if ( g_wxtmpool.count == 0 )	        tm = NULL;	else {		tm = list_entry(g_wxtmpool.link.next, wxtimer_t, link);                list_del(g_wxtmpool.link.next);		g_wxtmpool.count--;				memset(&tm->rb_link, 0, sizeof(tm->rb_link));		tm->type	= type;		tm->count	= count;		tm->arga	= arga;		tm->argb	= argb;		tm->action	= action;	}	pthread_mutex_unlock(&g_wxtmpool.mutex);	return tm;}int32_t start_timer(wxtimer_t *timer){	timer->timestamp = jiffies;	timer->future = jiffies + timer->count;	pthread_mutex_lock(&g_wxtmtree.mutex);		insert_timer(&g_wxtmtree.rb_root, timer);	rb_insert_color(&g_wxtmtree.rb_root, &timer->rb_link);	g_wxtmtree.rb_first = rb_first(&g_wxtmtree.rb_root);	g_wxtmtree.nr++;	pthread_mutex_unlock(&g_wxtmtree.mutex);	return 0;}int32_t cancel_timer(wxtimer_t *timer){	pthread_mutex_lock(&g_wxtmtree.mutex);	if ( timer->rb_link.rb_parent == NULL 	     && timer->rb_link.rb_left == NULL && timer->rb_link.rb_right == NULL )		goto out;		rb_erase(&g_wxtmtree.rb_root, &timer->rb_link);	g_wxtmtree.nr--; out:	pthread_mutex_unlock(&g_wxtmtree.mutex);	return 0;}int32_t put_timer(wxtimer_t *timer){	pthread_mutex_lock(&g_wxtmpool.mutex);		list_add_tail(&timer->link, &g_wxtmpool.link);	g_wxtmpool.count++;	pthread_mutex_unlock(&g_wxtmpool.mutex);	return 0;}static wxtimer_t * insert_timer(struct rb_root *root, wxtimer_t *new){	struct rb_node **p = &root->rb_node;	struct rb_node *parent = NULL;	wxtimer_t *tm;	while ( *p ) {		parent = *p;		tm = rb_entry(parent, wxtimer_t, rb_link);		if ( tm->timestamp <= new->timestamp ) {			if ( tm->timestamp <= tm->future && new->timestamp <= new->future )				p = tm->future <= new->future ? &(*p)->rb_right : &(*p)->rb_left;			else if ( tm->timestamp <= tm->future && new->timestamp > new->future )				p = &(*p)->rb_right;			else if ( tm->timestamp > tm->future && new->timestamp <= new->future )				p = &(*p)->rb_left;			else if ( tm->timestamp > tm->future && new->timestamp > new->future )				p = tm->future <= new->future ? &(*p)->rb_right : &(*p)->rb_left;		}		else {			if ( tm->timestamp <= tm->future && new->timestamp <= new->future )				p = &(*p)->rb_right;			else if ( tm->timestamp <= tm->future && new->timestamp > new->future )				p = &(*p)->rb_right;			else if ( tm->timestamp > tm->future && new->timestamp <= new->future )				p = tm->future <= new->future ? &(*p)->rb_right : &(*p)->rb_left;			else if ( tm->timestamp > tm->future && new->timestamp > new->future )				p = &(*p)->rb_right;		}	}	rb_link_node(&new->rb_link, parent, p);		return tm;}static void rb_erase(struct rb_root *root, struct rb_node *node){	struct rb_node *child, *parent;	int color;	if ( !node->rb_left )		child = node->rb_right;	else if ( !node->rb_right )		child = node->rb_left;	else {		struct rb_node * old = node, * left;		node = node->rb_right;		while ( (left = node->rb_left) )			node = left;		child = node->rb_right;		parent = node->rb_parent;		color = node->rb_color;		if ( child )			child->rb_parent = parent;		if ( parent ) {			if ( parent->rb_left == node )				parent->rb_left = child;			else				parent->rb_right = child;		}		else			root->rb_node = child;		if ( node->rb_parent == old )			parent = node;		node->rb_parent = old->rb_parent;		node->rb_color = old->rb_color;		node->rb_right = old->rb_right;		node->rb_left = old->rb_left;		if ( old->rb_parent ) {			if (old->rb_parent->rb_left == old)				old->rb_parent->rb_left = node;			else				old->rb_parent->rb_right = node;		} else			root->rb_node = node;		old->rb_left->rb_parent = node;		if ( old->rb_right )			old->rb_right->rb_parent = node;		goto color;	}	parent = node->rb_parent;	color = node->rb_color;	if ( child )		child->rb_parent = parent;	if ( parent ) {		if ( parent->rb_left == node )			parent->rb_left = child;		else			parent->rb_right = child;	}	else		root->rb_node = child; color:	if ( color == RB_BLACK )		rb_erase_color(root, child, parent);}static void rb_insert_color(struct rb_root *root, struct rb_node *node){	struct rb_node *parent, *gparent;	while ( (parent = node->rb_parent) && parent->rb_color == RB_RED ) {		gparent = parent->rb_parent;		if ( parent == gparent->rb_left ) {			{				register struct rb_node *uncle = gparent->rb_right;				if (uncle && uncle->rb_color == RB_RED)	{					uncle->rb_color = RB_BLACK;					parent->rb_color = RB_BLACK;					gparent->rb_color = RB_RED;					node = gparent;					continue;				}			}			if ( parent->rb_right == node ) {				register struct rb_node *tmp;				rb_rotate_left(parent, root);				tmp = parent;				parent = node;				node = tmp;			}			parent->rb_color = RB_BLACK;			gparent->rb_color = RB_RED;			rb_rotate_right(gparent, root);		} else {			{				register struct rb_node *uncle = gparent->rb_left;				if ( uncle && uncle->rb_color == RB_RED ) {					uncle->rb_color = RB_BLACK;					parent->rb_color = RB_BLACK;					gparent->rb_color = RB_RED;					node = gparent;					continue;				}			}			if ( parent->rb_left == node ) {				register struct rb_node *tmp;				rb_rotate_right(parent, root);				tmp = parent;				parent = node;				node = tmp;			}			parent->rb_color = RB_BLACK;			gparent->rb_color = RB_RED;			rb_rotate_left(gparent, root);		}	}	root->rb_node->rb_color = RB_BLACK;}static void rb_erase_color(struct rb_root *root, struct rb_node *node, struct rb_node *parent){	struct rb_node *other;	while ( (!node || node->rb_color == RB_BLACK) && node != root->rb_node ) {		if ( parent->rb_left == node ) {			other = parent->rb_right;			if ( other->rb_color == RB_RED ) {				other->rb_color = RB_BLACK;				parent->rb_color = RB_RED;				rb_rotate_left(parent, root);				other = parent->rb_right;			}			if ( (!other->rb_left || other->rb_left->rb_color == RB_BLACK)			    && (!other->rb_right || other->rb_right->rb_color == RB_BLACK) ) {				other->rb_color = RB_RED;				node = parent;				parent = node->rb_parent;			}			else {				if ( !other->rb_right || other->rb_right->rb_color == RB_BLACK ) {					register struct rb_node *o_left;					if ( (o_left = other->rb_left) )						o_left->rb_color = RB_BLACK;					other->rb_color = RB_RED;					rb_rotate_right(other, root);					other = parent->rb_right;				}				other->rb_color = parent->rb_color;				parent->rb_color = RB_BLACK;				if ( other->rb_right )					other->rb_right->rb_color = RB_BLACK;				rb_rotate_left(parent, root);				node = root->rb_node;				break;			}		}		else {			other = parent->rb_left;			if ( other->rb_color == RB_RED ) {				other->rb_color = RB_BLACK;				parent->rb_color = RB_RED;				rb_rotate_right(parent, root);				other = parent->rb_left;			}			if ( (!other->rb_left || other->rb_left->rb_color == RB_BLACK)			    && (!other->rb_right || other->rb_right->rb_color == RB_BLACK) ) {				other->rb_color = RB_RED;				node = parent;				parent = node->rb_parent;			}			else {				if ( !other->rb_left || other->rb_left->rb_color == RB_BLACK ) {					register struct rb_node *o_right;					if ( (o_right = other->rb_right) )						o_right->rb_color = RB_BLACK;					other->rb_color = RB_RED;					rb_rotate_left(other, root);					other = parent->rb_left;				}				other->rb_color = parent->rb_color;				parent->rb_color = RB_BLACK;				if ( other->rb_left )					other->rb_left->rb_color = RB_BLACK;				rb_rotate_right(parent, root);				node = root->rb_node;				break;			}		}	}	if ( node )		node->rb_color = RB_BLACK;}static struct rb_node * rb_first(struct rb_root *root){	struct rb_node *n;	if ( (n = root->rb_node) == NULL )		return NULL;	while ( n->rb_left )		n = n->rb_left;	return n;}static struct rb_node * rb_last(struct rb_root *root){	struct rb_node *n;		        if ( (n = root->rb_node) == NULL )                return NULL;	        while ( n->rb_right )                n = n->rb_right;        return n;}static struct rb_node * rb_next(struct rb_node *node){	/* If we have a right-hand child, go down and then left as far	 * as we can.	 */	if ( node->rb_right ) {                node = node->rb_right;                while ( node->rb_left )                        node = node->rb_left;                return node;        }        /* No right-hand children.  Everything down and left is	 * smaller than us, so any 'next' node must be in the general         * direction of our parent. Go up the tree; any time the	 * ancestor is a right-hand child of its parent, keep going         * up. First time it's a left-hand child of its parent, said         * parent is our 'next' node.	 */        while ( node->rb_parent && node == node->rb_parent->rb_right )                node = node->rb_parent;        return node->rb_parent;}static struct rb_node * rb_prev(struct rb_node *node){        /* If we have a left-hand child, go down and then right as far	 * as we can.	 */        if ( node->rb_left ) {                node = node->rb_left;                while ( node->rb_right )                        node = node->rb_right;                return node;        }        /* No left-hand children. Go up till we find an ancestor which         * is a right-hand child of its parent.	 */        while ( node->rb_parent && node == node->rb_parent->rb_left )                node = node->rb_parent;        return node->rb_parent;}static void rb_link_node(struct rb_node *node, struct rb_node *parent, struct rb_node **rb_link){	node->rb_parent = parent;	node->rb_color = RB_RED;	node->rb_left = node->rb_right = NULL;	*rb_link = node;}static void rb_rotate_left(struct rb_node *node, struct rb_root *root){	struct rb_node *right = node->rb_right;	if ( (node->rb_right = right->rb_left) )		right->rb_left->rb_parent = node;	right->rb_left = node;		if ( (right->rb_parent = node->rb_parent) ) {		if ( node == node->rb_parent->rb_left )			node->rb_parent->rb_left = right;		else			node->rb_parent->rb_right = right;	}	else		root->rb_node = right;	node->rb_parent = right;}static void rb_rotate_right(struct rb_node *node, struct rb_root *root){	struct rb_node *left = node->rb_left;		if ( (node->rb_left = left->rb_right) )		left->rb_right->rb_parent = node;	left->rb_right = node;		if ( (left->rb_parent = node->rb_parent) ) {		if ( node == node->rb_parent->rb_right )			node->rb_parent->rb_right = left;		else			node->rb_parent->rb_left = left;	}	else		root->rb_node = left;	node->rb_parent = left;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -