📄 fsm.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 + -