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

📄 fsm.c

📁 该文件是rt_linux
💻 C
字号:
/** * $Id: fsm.c,v 1.3 2001/06/18 16:49:19 felfert Exp $ * * A generic FSM based on fsm used in isdn4linux * */#include "fsm.h"#include <linux/version.h>#include <linux/config.h>#include <linux/module.h>fsm_instance *init_fsm(char *name, const char **state_names, const char **event_names, int nr_states,		int nr_events, const fsm_node *tmpl, int tmpl_len, int order){	int i;	fsm_instance *this;	fsm_function_t *m;	fsm *f;	this = (fsm_instance *)kmalloc(sizeof(fsm_instance), order);	if (this == NULL) {		printk(KERN_WARNING			"fsm(%s): init_fsm: Couldn't alloc instance\n", name);		return NULL;	}	memset(this, 0, sizeof(fsm_instance));	strncpy(this->name, name, sizeof(this->name));	f = (fsm *)kmalloc(sizeof(fsm), order);	if (f == NULL) {		printk(KERN_WARNING			"fsm(%s): init_fsm: Couldn't alloc fsm\n", name);		kfree_fsm(this);		return NULL;	}	memset(f, 0, sizeof(fsm));	f->nr_events = nr_events;	f->nr_states = nr_states;	f->event_names = event_names;	f->state_names = state_names;	this->f = f;	m = (fsm_function_t *)kmalloc(			sizeof(fsm_function_t) * nr_states * nr_events, order);	if (m == NULL) {		printk(KERN_WARNING			"fsm(%s): init_fsm: Couldn't alloc jumptable\n", name);		kfree_fsm(this);		return NULL;	}	memset(m, 0, sizeof(fsm_function_t) * f->nr_states * f->nr_events);	f->jumpmatrix = m;	for (i = 0; i < tmpl_len; i++) {		if ((tmpl[i].cond_state >= nr_states) ||		    (tmpl[i].cond_event >= nr_events)   ) {			printk(KERN_ERR				"fsm(%s): init_fsm: Bad template l=%d st(%ld/%ld) ev(%ld/%ld)\n",				name, i, (long)tmpl[i].cond_state, (long)f->nr_states,				(long)tmpl[i].cond_event, (long)f->nr_events);			kfree_fsm(this);			return NULL;		} else			m[nr_states * tmpl[i].cond_event + tmpl[i].cond_state] =				tmpl[i].function;	}	return this;}voidkfree_fsm(fsm_instance *this){	if (this) {		if (this->f) {			if (this->f->jumpmatrix)				kfree(this->f->jumpmatrix);			kfree(this->f);		}		kfree(this);	} else		printk(KERN_WARNING			"fsm: kfree_fsm called with NULL argument\n");}#if FSM_DEBUG_HISTORYvoidfsm_print_history(fsm_instance *fi){	int idx = 0;	int i;	if (fi->history_size >= FSM_HISTORY_SIZE)		idx = fi->history_index;	printk(KERN_DEBUG "fsm(%s): History:\n", fi->name);	for (i = 0; i < fi->history_size; i++) {		int e = fi->history[idx].event;		int s = fi->history[idx++].state;		idx %= FSM_HISTORY_SIZE;		if (e == -1)			printk(KERN_DEBUG "  S=%s\n",			       fi->f->state_names[s]);		else			printk(KERN_DEBUG "  S=%s E=%s\n",			       fi->f->state_names[s],			       fi->f->event_names[e]);	}	fi->history_size = fi->history_index = 0;}voidfsm_record_history(fsm_instance *fi, int state, int event){	fi->history[fi->history_index].state = state;	fi->history[fi->history_index++].event = event;	fi->history_index %= FSM_HISTORY_SIZE;	if (fi->history_size < FSM_HISTORY_SIZE)		fi->history_size++;}#endifconst char *fsm_getstate_str(fsm_instance *fi){	int st = atomic_read(&fi->state);	if (st >= fi->f->nr_states)		return "Invalid";	return fi->f->state_names[st];}static voidfsm_expire_timer(fsm_timer *this){#if FSM_TIMER_DEBUG	printk(KERN_DEBUG "fsm(%s): Timer %p expired\n",	       this->fi->name, this);#endif	fsm_event(this->fi, this->expire_event, this->event_arg);}voidfsm_settimer(fsm_instance *fi, fsm_timer *this){	this->fi = fi;	this->tl.function = (void *)fsm_expire_timer;	this->tl.data = (long)this;#if FSM_TIMER_DEBUG	printk(KERN_DEBUG "fsm(%s): Create timer %p\n", fi->name,	       this);#endif	init_timer(&this->tl);}voidfsm_deltimer(fsm_timer *this){#if FSM_TIMER_DEBUG	printk(KERN_DEBUG "fsm(%s): Delete timer %p\n", this->fi->name,		this);#endif	del_timer(&this->tl);}intfsm_addtimer(fsm_timer *this, int millisec, int event, void *arg){#if FSM_TIMER_DEBUG	printk(KERN_DEBUG "fsm(%s): Add timer %p %dms\n",	       this->fi->name, this, millisec);#endif#if LINUX_VERSION_CODE >= 0x020300	if (this->tl.list.next || this->tl.list.prev) {		printk(KERN_WARNING "fsm(%s): timer already active!\n",			this->fi->name);		return -1;	}#else	if (this->tl.next || this->tl.prev) {		printk(KERN_WARNING "fsm(%s): timer already active!\n",			this->fi->name);		return -1;	}#endif	init_timer(&this->tl);	this->tl.function = (void *)fsm_expire_timer;	this->tl.data = (long)this;	this->expire_event = event;	this->event_arg = arg;	this->tl.expires = jiffies + (millisec * HZ) / 1000;	add_timer(&this->tl);	return 0;}voidfsm_modtimer(fsm_timer *this, int millisec, int event, void *arg){#if FSM_TIMER_DEBUG	printk(KERN_DEBUG "fsm(%s): Restart timer %p %dms\n",		this->fi->name, this, millisec);#endif#if LINUX_VERSION_CODE >= 0x020300	if (this->tl.list.next || this->tl.list.prev)		del_timer(&this->tl);#else	if (this->tl.next || this->tl.prev)		del_timer(&this->tl);#endif	init_timer(&this->tl);	this->tl.function = (void *)fsm_expire_timer;	this->tl.data = (long)this;	this->expire_event = event;	this->event_arg = arg;	this->tl.expires = jiffies + (millisec * HZ) / 1000;	add_timer(&this->tl);}EXPORT_SYMBOL(init_fsm);EXPORT_SYMBOL(kfree_fsm);EXPORT_SYMBOL(fsm_settimer);EXPORT_SYMBOL(fsm_deltimer);EXPORT_SYMBOL(fsm_addtimer);EXPORT_SYMBOL(fsm_modtimer);EXPORT_SYMBOL(fsm_getstate_str);#if FSM_DEBUG_HISTORYEXPORT_SYMBOL(fsm_print_history);EXPORT_SYMBOL(fsm_record_history);#endif

⌨️ 快捷键说明

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