spot/iface/nips/nips_vm/state.h
Guillaume Sadegh bc5f13bb4e NIPS VM added to the SPOT distribution.
2008-05-29  Guillaume SADEGH  <sadegh@lrde.epita.fr>

	* iface/nips/nips.cc, iface/nips/nips.hh, iface/nips/common.cc,
	iface/nips/common.hh, iface/nips/Makefile.am: TGBA implementation
	with the NIPS library.
	* iface/nips/emptiness_check.cc: Emptiness check on a Promela
	interface.
	* iface/nips/dottynips.cc: Dot printer on the NIPS interface.
	* iface/nips/compile.sh: Add. Wrapper around nips compiler to
	compile Promela to NIPS bytecode.
	* iface/nips/nips_vm,iface/nips/nips_vm/bytecode.h,
	iface/nips/nips_vm/ChangeLog, iface/nips/nips_vm/COPYING,
	iface/nips/nips_vm/hashtab.c, iface/nips/nips_vm/hashtab.h,
	iface/nips/nips_vm/INSTALL, iface/nips/nips_vm/instr.c,
	iface/nips/nips_vm/instr.h, iface/nips/nips_vm/instr_step.c,
	iface/nips/nips_vm/instr_step.h,
	iface/nips/nips_vm/instr_tools.c,
	iface/nips/nips_vm/instr_tools.h,
	iface/nips/nips_vm/instr_wrap.c,
	iface/nips/nips_vm/instr_wrap.h,
	iface/nips/nips_vm/interactive.c,
	iface/nips/nips_vm/interactive.h, iface/nips/nips_vm/main.c,
	iface/nips/nips_vm/Makefile, iface/nips/nips_vm/Makefile.am,
	iface/nips/nips_vm/nips_asm_help.pl,
	iface/nips/nips_vm/nips_asm_instr.pl,
	iface/nips/nips_vm/nips_asm.pl,
	iface/nips/nips_vm/nips_disasm.pl, iface/nips/nips_vm/nipsvm.c,
	iface/nips/nips_vm/nipsvm.h, iface/nips/nips_vm/README,
	iface/nips/nips_vm/rt_err.c, iface/nips/nips_vm/rt_err.h,
	iface/nips/nips_vm/search.c, iface/nips/nips_vm/search.h,
	iface/nips/nips_vm/split.c, iface/nips/nips_vm/split.h,
	iface/nips/nips_vm/state.c, iface/nips/nips_vm/state.h,
	iface/nips/nips_vm/state_inline.h,
	iface/nips/nips_vm/state_parts.c,
	iface/nips/nips_vm/state_parts.h, iface/nips/nips_vm/timeval.h,
	iface/nips/nips_vm/tools.h: NIPS VM added to the SPOT
	distribution.
	* configure.ac, iface/Makefile.am: Build system updated for the
	NIPS front-end.
2008-05-30 13:22:00 +02:00

274 lines
11 KiB
C

/* NIPS VM - New Implementation of Promela Semantics Virtual Machine
* Copyright (C) 2005: Stefan Schuermans <stefan@schuermans.info>
* Michael Weber <michaelw@i2.informatik.rwth-aachen.de>
* Lehrstuhl fuer Informatik II, RWTH Aachen
* Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
*/
#ifndef INC_state
#define INC_state
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "tools.h"
// types for process and channel identifiers
typedef uint8_t t_pid;
#define PID_MAX ((t_pid)-1)
#define PID_OK( pid ) ((pid) > 0)
#define h2be_pid( x ) (x)
#define be2h_pid( x ) (x)
typedef uint16_t t_chid; // channel-id = <pid of creating process> <1 byte to make channel-id unique>
#define CHID_MAX ((t_chid)-1)
#define CHID_OK( chid ) ((chid) > 0)
#define h2be_chid( x ) h2be_16( x )
#define be2h_chid( x ) be2h_16( x )
// type for program counter
typedef uint32_t t_pc;
#define PC_MAX ((t_pc)-1)
#define h2be_pc( x ) h2be_32( x )
#define be2h_pc( x ) be2h_32( x )
// type of flag register
typedef uint32_t t_flag_reg;
#define FLAG_REG_FLAG_CNT 32
// type for internal values (type for data stack and normal registers)
typedef int32_t t_val;
typedef uint32_t t_u_val;
// unaligned version of internal value
// - realized as structure to be able to use PACKED
typedef struct { t_val val; } PACKED ua_t_val;
// process
typedef struct t_process_header
{
t_pid pid; // process identifier (never 0)
uint8_t flags; // flags (contain execution mode)
uint8_t lvar_sz; // size of local variables in bytes
t_pc pc; // program counter
} PACKED st_process_header;
// after header follows (if ! (flags & process_flags_active)):
// variables (lvar_sz bytes, multi-byte values in big-endian format),
// process flags
#define PROCESS_FLAGS_MODE 0x03 // execution modes
#define PROCESS_FLAGS_MODE_NORMAL 0x00
#define PROCESS_FLAGS_MODE_ATOMIC 0x01
#define PROCESS_FLAGS_MODE_INVISIBLE 0x02
#define PROCESS_FLAGS_MODE_TERMINATED 0x03
#define PROCESS_FLAGS_MONITOR_ACCEPT 0x10 // if monitor process is in accepting state (only valid for monitor process)
#define PROCESS_FLAGS_ACTIVE 0x80 // if process is currently active (i.e. executing)
// active process
typedef struct t_process_active_header
{
st_process_header proc; // normal process header (with flags & process_flags_active)
t_val registers[8]; // virtual machine registers (host byte order)
t_flag_reg flag_reg; // flag register (host byte order)
uint8_t stack_cur; // current size of stack in entries
uint8_t stack_max; // maximum size of stack in entries
} PACKED st_process_active_header;
// after header follows:
// variables (proc.lvar_sz bytes, multi-byte values in big-endian format),
// stack (stack_max ints in host byte order),
// channel
typedef struct t_channel_header
{
t_chid chid; // channel identifier (never 0)
uint8_t max_len; // maximum number of messages in channel (if 0, real max_len is 1)
uint8_t cur_len; // current number of messages in channel
uint8_t msg_len; // length of a single message in bytes
uint8_t type_len; // number of entries of flat type
} PACKED st_channel_header;
// after header follows:
// flat type of message (type_len bytes),
// - bytes contain number of bits the entries use
// (use -value+1 for negative values,
// round up to 8, 16 or 32 and divide by 8 to get number of bytes)
// messages (max( 1, max_len ) * msg_len bytes)
// (multi-byte values in big-endian format)
// global state
#define PROC_CNT_MAX 255 // maximum number of processes (must fit into uint8_t, see below)
#define CHAN_CNT_MAX 255 // maximum number of channels (must fit into uint8_t, see below)
typedef struct t_global_state_header
{
uint16_t gvar_sz; // size of global variables in bytes (big endian format)
uint8_t proc_cnt; // number of process currently active
t_pid excl_pid; // pid of the process executed exclusively or 0 if none
t_pid monitor_pid; // pid of the monitor process or 0 if none
uint8_t chan_cnt; // number of channels currently existing
} PACKED st_global_state_header;
// after header follows:
// variables (gvar_sz bytes, multi-byte values in big-endian format),
// processes (proc_cnt times a process),
// channels (chan_cnt times a channel)
typedef st_global_state_header nipsvm_state_t;
// inline functions as "extern inline" for optimized compilation
#define STATE_INLINE extern inline
#include "state_inline.h"
#undef STATE_INLINE
// size of initial state
#define NIPSVM_INITIAL_STATE_SIZE (sizeof( st_global_state_header ) \
+ sizeof( st_process_header ))
static const size_t global_state_initial_size = NIPSVM_INITIAL_STATE_SIZE;
// generate initial state
// *pp_buf points to memory area of length *p_len to use for new state
// NULL is returned in case of error
extern st_global_state_header * global_state_initial( char **pp_buf, unsigned long *p_buf_len );
// get a copy of global state
// *pp_buf points to memory area of length *p_len to use for new state
// NULL is returned in case of error
extern st_global_state_header * global_state_copy( st_global_state_header *p_glob,
char **pp_buf, unsigned long *p_buf_len );
// get copy of global state with resized global variables
// *pp_buf points to memory area of length *p_len to use for new state
// NULL is returned in case of error
extern st_global_state_header * global_state_copy_gvar_sz( st_global_state_header *p_glob,
uint16_t gvar_sz,
char **pp_buf, unsigned long *p_buf_len );
// get copy of global state with resized local variables
// *pp_buf points to memory area of length *p_len to use for new state
// NULL is returned in case of error
extern st_global_state_header * global_state_copy_lvar_sz( st_global_state_header *p_glob,
st_process_header *p_proc, uint8_t lvar_sz,
char **pp_buf, unsigned long *p_buf_len );
// get copy of global state with selected process activated
// *pp_buf points to memory area of length *p_len to use for new state
// *pp_proc is filled with the pointer to the activated process
// NULL is returned in case of error
extern st_global_state_header * global_state_copy_activate( st_global_state_header *p_glob, st_process_header *p_proc,
uint8_t stack_max, t_flag_reg flag_reg,
char **pp_buf, unsigned long *p_buf_len,
st_process_active_header **pp_proc );
// get copy of global state with an additional process
// *pp_buf points to memory area of length *p_len to use for new state
// *pp_proc is filled with the pointer to the new process
// NULL is returned in case of error
extern st_global_state_header * global_state_copy_new_process( st_global_state_header *p_glob,
t_pid new_pid, uint8_t lvar_sz,
char **pp_buf, unsigned long *p_buf_len,
st_process_header **pp_proc );
// get copy of global state with an additional channel
// *pp_buf points to memory area of length *p_len to use for new state
// the new channel is inserted at the right place according to its channel id
// *pp_chan is filled with the pointer to the new process
// NULL is returned in case of error
extern st_global_state_header * global_state_copy_new_channel( st_global_state_header *p_glob,
t_chid new_chid, uint8_t max_len, uint8_t type_len, uint8_t msg_len,
char **pp_buf, unsigned long *p_buf_len,
st_channel_header **pp_chan );
// deactivate selected process in global state
extern void global_state_deactivate( st_global_state_header *p_glob, st_process_active_header *p_proc );
// remove selected process in global state
extern void global_state_remove( st_global_state_header *p_glob, st_process_header *p_proc );
// count enabled processes (i.e. processes that are not yet terminated)
// returns number of processes
extern unsigned int global_state_count_enabled_processes( st_global_state_header *p_glob );
// get enabled processes (i.e. processes that may be activated)
// returns number of processes or (unsigned int)-1 if there are too many enabled processes
extern unsigned int global_state_get_enabled_processes( st_global_state_header *p_glob, st_process_header **p_procs, unsigned int proc_max );
/* DEPRECATED */ extern int global_state_monitor_accepting( st_global_state_header *p_glob );
/* DEPRECATED */ extern int global_state_monitor_terminated( st_global_state_header *p_glob );
/* DEPRECATED */ extern int global_state_monitor_acc_or_term( st_global_state_header *p_glob );
// TIP: the following 3 functions can be called with ( ..., NULL, 0 )
// to obtain the needed buffer size
// (add 1 to return value for the terminating 0 character)
// output a process to a string
// - possibly to output in graphviz dot format
// - puts up to size charactes into *p_buf (including temintaing 0 character)
// - returns number of characters needed (e.g. size or more if string is truncated)
extern unsigned int process_to_str( st_process_header *p_proc, int dot_fmt, char *p_buf, unsigned int size );
// output a channel to a string
// - possibly to output in graphviz dot format
// - puts up to size charactes into *p_buf (including temintaing 0 character)
// - returns number of characters needed (e.g. size or more if string is truncated)
extern unsigned int channel_to_str( st_channel_header *p_chan, int dot_fmt, char *p_buf, unsigned int size );
// output a global state to a string
// - possibly to output in graphviz dot format
// - puts up to size charactes into *p_buf (including temintaing 0 character)
// - returns number of characters needed (e.g. size or more if string is truncated)
extern unsigned int global_state_to_str( st_global_state_header *p_glob, int dot_fmt, char *p_buf, unsigned int size );
// print a process to a stream
// - possibly to output in graphviz dot format
extern void process_print_ex( FILE *out, st_process_header *p_proc, int dot_fmt );
// print a channel to a stream
// - possibly to output in graphviz dot format
extern void channel_print_ex( FILE *out, st_channel_header *p_chan, int dot_fmt );
// print a global state to a stream
// - possibly to output in graphviz dot format
extern void global_state_print_ex( FILE *out, st_global_state_header *p_glob, int dot_fmt );
// print a process to stdout
extern void process_print( st_process_header *p_proc );
// print a channel to stdout
extern void channel_print( st_channel_header *p_chan );
// print a global state to stdout
extern void global_state_print( st_global_state_header *p_glob );
#ifdef __cplusplus
} // extern "C"
#endif
#endif // #ifndef INC_state