X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/af0b5e9494ca8988c8dd7d3874c3c7a400a63172..d6fc96fb24bb0006584d44bee70df5f67b37f5fb:/src/simix/smx_smurf_private.h diff --git a/src/simix/smx_smurf_private.h b/src/simix/smx_smurf_private.h index 07385e95dd..61b606c635 100644 --- a/src/simix/smx_smurf_private.h +++ b/src/simix/smx_smurf_private.h @@ -9,8 +9,14 @@ /********************************* Simcalls *********************************/ -/* we want to build the e_smx_simcall_t enumeration and the table of the - * corresponding strings automatically, using macros */ +/* we want to build the e_smx_simcall_t enumeration, the table of the + * corresponding simcalls string names, and the simcall handlers table + * automatically, using macros. + * To add a new simcall follow the following syntax: + * + * SIMCALL_ENUM_ELEMENT(, ) + * + * */ #define SIMCALL_LIST1 \ SIMCALL_ENUM_ELEMENT(SIMCALL_NONE),\ @@ -45,11 +51,16 @@ SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_GET_NAME),\ SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_IS_SUSPENDED),\ SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_GET_PROPERTIES),\ SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_SLEEP),\ +SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_ON_EXIT),\ +SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_AUTO_RESTART_SET),\ +SIMCALL_ENUM_ELEMENT(SIMCALL_PROCESS_RESTART),\ SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_CREATE),\ SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_DESTROY),\ SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_GEY_BY_NAME),\ SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_COMM_COUNT_BY_HOST),\ SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_GET_HEAD),\ +SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_SET_RECV),\ +SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_GET_RECV),\ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_SEND),\ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_ISEND),\ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_RECV),\ @@ -60,6 +71,7 @@ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_WAITANY),\ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_WAIT),\ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_TEST),\ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_TESTANY),\ +SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_IPROBE),\ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_GET_REMAINS),\ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_GET_STATE),\ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_GET_SRC_DATA),\ @@ -88,31 +100,45 @@ SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_READ),\ SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_WRITE),\ SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_OPEN),\ SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_CLOSE),\ -SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_STAT) - +SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_STAT), \ +SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_UNLINK),\ +SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_LS),\ +SIMCALL_ENUM_ELEMENT(SIMCALL_ASR_GET_PROPERTIES), \ +/* ****************************************************************************************** */ \ +/* TUTORIAL: New API */ \ +/* ****************************************************************************************** */ \ +SIMCALL_ENUM_ELEMENT(SIMCALL_NEW_API_INIT) /* SIMCALL_COMM_IS_LATENCY_BOUNDED and SIMCALL_SET_CATEGORY make things complicated * because they are not always present */ #ifdef HAVE_LATENCY_BOUND_TRACKING #define SIMCALL_LIST2 \ -,SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_IS_LATENCY_BOUNDED) +,SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_IS_LATENCY_BOUNDED, SIMIX_comm_is_latency_bounded) #else #define SIMCALL_LIST2 #endif #ifdef HAVE_TRACING #define SIMCALL_LIST3 \ -,SIMCALL_ENUM_ELEMENT(SIMCALL_SET_CATEGORY) +,SIMCALL_ENUM_ELEMENT(SIMCALL_SET_CATEGORY, SIMIX_set_category) #else #define SIMCALL_LIST3 #endif +#ifdef HAVE_MC +#define SIMCALL_LIST4 \ + ,SIMCALL_ENUM_ELEMENT(SIMCALL_MC_SNAPSHOT) \ + ,SIMCALL_ENUM_ELEMENT(SIMCALL_MC_COMPARE_SNAPSHOTS) +#else +#define SIMCALL_LIST4 +#endif + /* SIMCALL_LIST is the final macro to use */ -#define SIMCALL_LIST SIMCALL_LIST1 SIMCALL_LIST2 SIMCALL_LIST3 +#define SIMCALL_LIST SIMCALL_LIST1 SIMCALL_LIST2 SIMCALL_LIST3 SIMCALL_LIST4 /* you can redefine the following macro differently to generate something else * with the list of enumeration values (e.g. a table of strings or a table of function pointers) */ -#define SIMCALL_ENUM_ELEMENT(x) x +#define SIMCALL_ENUM_ELEMENT(x, y) x /** * \brief All possible simcalls. @@ -127,6 +153,8 @@ SIMCALL_LIST typedef struct s_smx_simcall { e_smx_simcall_t call; smx_process_t issuer; + union u_smx_scalar *args; + //FIXME: union u_smx_scalar retval; union { @@ -214,7 +242,9 @@ typedef struct s_smx_simcall { struct { smx_action_t execution; + struct s_smx_simcall *simcall; e_smx_state_t result; + } host_execution_wait; struct { @@ -223,9 +253,11 @@ typedef struct s_smx_simcall { xbt_main_func_t code; void *data; const char *hostname; + double kill_time; int argc; char **argv; xbt_dict_t properties; + int auto_restart; } process_create; struct { @@ -288,6 +320,22 @@ typedef struct s_smx_simcall { e_smx_state_t result; } process_sleep; + struct { + smx_process_t process; + int_f_pvoid_t fun; + void *data; + } process_on_exit; + + struct { + smx_process_t process; + int auto_restart; + } process_auto_restart; + + struct { + smx_process_t process; + smx_process_t result; + } process_restart; + struct { const char *name; smx_rdv_t result; @@ -313,13 +361,23 @@ typedef struct s_smx_simcall { smx_action_t result; } rdv_get_head; + struct { + smx_rdv_t rdv; + smx_process_t receiver; + } rdv_set_rcv_proc; + + struct { + smx_rdv_t rdv; + smx_process_t result; + } rdv_get_rcv_proc; + struct { smx_rdv_t rdv; double task_size; double rate; void *src_buff; size_t src_buff_size; - int (*match_fun)(void *, void *); + int (*match_fun)(void *, void *, smx_action_t); void *data; double timeout; } comm_send; @@ -330,7 +388,7 @@ typedef struct s_smx_simcall { double rate; void *src_buff; size_t src_buff_size; - int (*match_fun)(void *, void *); + int (*match_fun)(void *, void *, smx_action_t); void (*clean_fun)(void *); void *data; int detached; @@ -341,7 +399,7 @@ typedef struct s_smx_simcall { smx_rdv_t rdv; void *dst_buff; size_t *dst_buff_size; - int (*match_fun)(void *, void *); + int (*match_fun)(void *, void *, smx_action_t); void *data; double timeout; } comm_recv; @@ -350,11 +408,20 @@ typedef struct s_smx_simcall { smx_rdv_t rdv; void *dst_buff; size_t *dst_buff_size; - int (*match_fun)(void *, void *); - void *data; + int (*match_fun)(void *, void *, smx_action_t); + void *data; smx_action_t result; } comm_irecv; + struct { + smx_rdv_t rdv; + int src; + int tag; + int (*match_fun)(void *, void *, smx_action_t); + void *data; + smx_action_t result; + } comm_iprobe; + struct { smx_action_t comm; } comm_destroy; @@ -508,16 +575,14 @@ typedef struct s_smx_simcall { } sem_get_capacity; struct { - const char* storage; void *ptr; size_t size; size_t nmemb; smx_file_t stream; - size_t result; + double result; } file_read; struct { - const char* storage; const void *ptr; size_t size; size_t nmemb; @@ -526,26 +591,58 @@ typedef struct s_smx_simcall { } file_write; struct { - const char* storage; + const char* mount; const char* path; const char* mode; smx_file_t result; } file_open; struct { - const char* storage; smx_file_t fp; int result; } file_close; struct { - const char* storage; - int fd; - //Next should be struct stat* buf - void* buf; + smx_file_t fd; + s_file_stat_t buf; int result; } file_stat; + struct { + smx_file_t fd; + int result; + } file_unlink; + + struct { + const char *mount; + const char *path; + xbt_dict_t result; + } file_ls; + + struct { + const char* name; + xbt_dict_t result; + } asr_get_properties; + + struct{ + void *s; + } mc_snapshot; + + struct{ + void *snapshot1; + void *snapshot2; + int result; + } mc_compare_snapshots; + + /* ****************************************************************************************** */ + /* TUTORIAL: New API */ + /* ****************************************************************************************** */ + struct { + const char* param1; + double param2; + int result; + } new_api; + }; } s_smx_simcall_t, *smx_simcall_t; @@ -558,5 +655,100 @@ void SIMIX_simcall_post(smx_action_t); smx_simcall_t SIMIX_simcall_mine(void); const char *SIMIX_simcall_name(e_smx_simcall_t kind); +/*************************** New simcall interface ****************************/ + +/* Pack all possible scalar types in an union */ +union u_smx_scalar { + char c; + const char* cc; + short s; + int i; + long l; + unsigned char uc; + unsigned short us; + unsigned int ui; + unsigned long ul; + float f; + double d; + void* p; +}; + +#define SIMIX_pack_args(...) (u_smx_scalar_t[]){MAP(INIT_FIELD, __VA_ARGS__)} + + +/* + * Define scalar type wrappers to ease the use of simcalls. + * These are used to wrap the arguments in SIMIX_simcall macro. + */ +#define CHAR(x) (c,x) +#define STRING(x) (cc,x) +#define SHORT(x) (s,x) +#define INT(x) (i,x) +#define LONG(x) (l,x) +#define UCHAR(x) (uc,x) +#define USHORT(x) (us,x) +#define UINT(x) (ui,x) +#define ULONG(x) (ul,x) +#define FLOAT(x) (f,x) +#define DOUBLE(x) (d,x) +#define PTR(x) (p,x) + +/* + * Some macro machinery to get a MAP over the arguments of a variadic macro. + * It uses a FOLD to apply a macro to every argument, and because there is + * no recursion in the C preprocessor we must create a new macro for every + * depth of FOLD's recursion. + */ + +/* FOLD macro */ +#define FE_1(WHAT, X) WHAT(X) +#define FE_2(WHAT, X, ...) WHAT(X), FE_1(WHAT, __VA_ARGS__) +#define FE_3(WHAT, X, ...) WHAT(X), FE_2(WHAT, __VA_ARGS__) +#define FE_4(WHAT, X, ...) WHAT(X), FE_3(WHAT, __VA_ARGS__) +#define FE_5(WHAT, X, ...) WHAT(X), FE_4(WHAT, __VA_ARGS__) +/* NOTE: add as many FE_n as needed (maximum number of simcall arguments )*/ + +/* Make a MAP macro usgin FOLD (will apply 'action' to the arguments. + * GET_MACRO is a smart hack that counts the number of arguments passed to + * the variadic macro, and it is used to invoke the right FOLD depth. + */ +#define GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME +#define MAP(action,...) \ + GET_MACRO(__VA_ARGS__,FE_5,FE_4,FE_3,FE_2,FE_1) (action, __VA_ARGS__) + + +/* Generate code to initialize the field 'x' with value 'y' of an structure or union */ +#define INIT_FIELD_(x,y) {.x = y} +#define INIT_FIELD(t) INIT_FIELD_ t + +/* Project the second element of a tuple */ +#define SECOND_(x, y) y +#define SECOND(t) SECOND_ t + +/* + * \brief Simcall invocation macro + * It calls a dummy function that uses the format attribute to ensure typesafety (see + * gcc format attribute), then it invokes the real simcall function packing the + * user provided arguments in an array. + * \param id a simcall id (from the simcall enumeration ids) + * + */ +#define SIMIX_simcall(id, ...) \ + SIMIX_simcall_typecheck(simcall_types[id], MAP(SECOND, __VA_ARGS__)); \ + __SIMIX_simcall(id, (u_smx_scalar_t[]){MAP(INIT_FIELD, __VA_ARGS__)}) + +void __SIMIX_simcall(e_smx_simcall_t simcall_id, u_smx_scalar_t *args); + +/* + * \biref Dummy variadic function used to typecheck the arguments of a simcall + * \param fmt A format string following printf style + */ +void SIMIX_simcall_typecheck(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); + +typedef smx_action_t (*simcall_handler_t)(u_smx_scalar_t *); + +extern const char *simcall_types[]; +extern simcall_handler_t simcall_table[]; + #endif