From: Paul Bédaride Date: Wed, 30 Oct 2013 14:26:47 +0000 (+0100) Subject: Merge commit '045db1657e870c721be490b411868f4181a12ced' into surf++ X-Git-Tag: v3_11_beta~297^2~2 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/d0ffc37686edcc803601f76ab51fdfed5fc2f241 Merge commit '045db1657e870c721be490b411868f4181a12ced' into surf++ Conflicts: buildtools/Cmake/DefinePackages.cmake src/include/surf/datatypes.h src/include/surf/surf.h src/simgrid/sg_config.c src/simix/smx_io.c src/simix/smx_smurf_private.h src/surf/cpu_cas01.c src/surf/cpu_ti.c src/surf/network.c src/surf/network_constant.c src/surf/network_gtnets.c src/surf/new_model.c src/surf/storage.c src/surf/storage_private.h src/surf/surf.c src/surf/surf_action.c src/surf/surf_model.c src/surf/surf_routing.cpp src/surf/surf_routing_cluster.c src/surf/surf_routing_floyd.cpp src/surf/surf_routing_full.cpp src/surf/surf_routing_none.c src/surf/surf_routing_vivaldi.c src/surf/workstation.c src/surf/workstation_ptask_L07.c --- d0ffc37686edcc803601f76ab51fdfed5fc2f241 diff --cc buildtools/Cmake/DefinePackages.cmake index d279c1ad48,8629c550ad..cdef08eeee --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@@ -49,13 -46,9 +49,12 @@@ set(EXTRA_DIS src/surf/gtnets/gtnets_simulator.h src/surf/gtnets/gtnets_topology.h src/surf/maxmin_private.h - #src/surf/network_gtnets_private.h - src/surf/network_gtnets_private.h + src/surf/network_gtnets.hpp src/surf/network_ns3_private.h src/surf/network_private.h + src/surf/network.hpp + src/surf/network_smpi.hpp + src/surf/network_constant.hpp src/surf/ns3/my-point-to-point-helper.h src/surf/ns3/ns3_interface.h src/surf/ns3/ns3_simulator.h diff --cc src/include/simgrid/sg_config.h index 7bc098f44a,e4142a9e1a..3d01e63d01 --- a/src/include/simgrid/sg_config.h +++ b/src/include/simgrid/sg_config.h @@@ -3,12 -9,9 +9,14 @@@ /*******************************************/ /*** Config Globals **************************/ /*******************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + XBT_PUBLIC_DATA(xbt_cfg_t) _sg_cfg_set; + XBT_PUBLIC_DATA(int) _sg_cfg_init_status; + XBT_PUBLIC_DATA(int) _sg_cfg_exit_asap; XBT_PUBLIC(int) sg_cfg_get_int(const char* name); XBT_PUBLIC(double) sg_cfg_get_double(const char* name); XBT_PUBLIC(char*) sg_cfg_get_string(const char* name); diff --cc src/include/surf/datatypes.h index 5ef74f07c9,31375cd6b1..3dd00e0fc5 --- a/src/include/surf/datatypes.h +++ b/src/include/surf/datatypes.h @@@ -21,8 -21,9 +21,9 @@@ * An action is some working amount on a model. * It is represented as a cost, a priority, a duration and a state. */ -typedef struct surf_action *surf_action_t; -typedef struct surf_file *surf_file_t; +//FIXME:typedef struct surf_action *surf_action_t; +//FIXME:typedef struct surf_file *surf_file_t; + typedef struct surf_storage *surf_storage_t; typedef struct surf_stat *surf_stat_t; typedef struct lmm_element *lmm_element_t; diff --cc src/include/surf/surf.h index e1a727f75a,0f0694a186..be433973e6 --- a/src/include/surf/surf.h +++ b/src/include/surf/surf.h @@@ -42,75 -43,6 +42,78 @@@ typedef enum SURF_NETWORK_ELEMENT_AS /* AS type */ } e_surf_network_element_type_t; +#ifdef __cplusplus +class Model; +class CpuModel; +class WorkstationModel; +class NetworkCm02Model; ++class StorageModel; +class Resource; +class ResourceLmm; +class WorkstationCLM03; +class NetworkCm02Link; +class Cpu; +class Action; +class ActionLmm; +class StorageActionLmm; +class As; +class RoutingEdge; +class RoutingPlatf; +#else +typedef struct Model Model; +typedef struct CpuModel CpuModel; +typedef struct WorkstationModel WorkstationModel; +typedef struct NetworkCm02Model NetworkCm02Model; ++typedef struct StorageModel StorageModel; +typedef struct Resource Resource; +typedef struct ResourceLmm ResourceLmm; +typedef struct WorkstationCLM03 WorkstationCLM03; +typedef struct NetworkCm02Link NetworkCm02Link; +typedef struct Cpu Cpu; +typedef struct Action Action; +typedef struct ActionLmm ActionLmm; +typedef struct StorageActionLmm StorageActionLmm; +typedef struct As As; +typedef struct RoutingEdge RoutingEdge; +typedef struct RoutingPlatf RoutingPlatf; +#endif + +/** \ingroup SURF_models + * \brief Model datatype + * + * Generic data structure for a model. The workstations, + * the CPUs and the network links are examples of models. + */ +typedef Model *surf_model_t; +typedef CpuModel *surf_cpu_model_t; +typedef WorkstationModel *surf_workstation_model_t; +typedef NetworkCm02Model *surf_network_model_t; ++typedef StorageModel *surf_storage_model_t; + +typedef xbt_dictelm_t surf_resource_t; +typedef Resource *surf_cpp_resource_t; +typedef WorkstationCLM03 *surf_workstation_CLM03_t; +typedef NetworkCm02Link *surf_network_link_t; +typedef Cpu *surf_cpu_t; + +/** \ingroup SURF_actions + * \brief Action structure + * + * Never create s_surf_action_t by yourself ! The actions are created + * on the fly when you call execute or communicate on a model. + * + * \see e_surf_action_state_t + */ +typedef Action *surf_action_t; +typedef ActionLmm *surf_action_lmm_t; +typedef StorageActionLmm *surf_storage_action_lmm_t; + +typedef As *AS_t; +typedef RoutingEdge *routing_edge_t; +typedef RoutingPlatf *routing_platf_t; + +typedef struct surf_file *surf_file_t; + XBT_PUBLIC(e_surf_network_element_type_t) routing_get_network_element_type(const char* name); @@@ -281,14 -299,70 +302,14 @@@ typedef struct surf_workstation_model_e } s_surf_model_extension_workstation_t; - - -/** \ingroup SURF_models - * \brief Model datatype - * - * Generic data structure for a model. The workstations, - * the CPUs and the network links are examples of models. - */ -typedef struct surf_model { - const char *name; /**< Name of this model */ - s_surf_action_state_t states; /**< Any living action on this model */ - - e_surf_action_state_t(*action_state_get) (surf_action_t action); - /**< Return the state of an action */ - void (*action_state_set) (surf_action_t action, - e_surf_action_state_t state); - /**< Change an action state*/ - - double (*action_get_start_time) (surf_action_t action); /**< Return the start time of an action */ - double (*action_get_finish_time) (surf_action_t action); /**< Return the finish time of an action */ - int (*action_unref) (surf_action_t action); /**< Specify that we don't use that action anymore. Returns true if the action was destroyed and false if someone still has references on it. */ - void (*action_cancel) (surf_action_t action); /**< Cancel a running action */ - void (*action_recycle) (surf_action_t action); /**< Recycle an action */ - void (*action_data_set) (surf_action_t action, void *data); /**< Set the user data of an action */ - void (*suspend) (surf_action_t action); /**< Suspend an action */ - void (*resume) (surf_action_t action); /**< Resume a suspended action */ - int (*is_suspended) (surf_action_t action); /**< Return whether an action is suspended */ - void (*set_max_duration) (surf_action_t action, double duration); /**< Set the max duration of an action*/ - void (*set_priority) (surf_action_t action, double priority); /**< Set the priority of an action */ -#ifdef HAVE_TRACING - void (*set_category) (surf_action_t action, const char *category); /**< Set the category of an action */ -#endif - double (*get_remains) (surf_action_t action); /**< Get the remains of an action */ -#ifdef HAVE_LATENCY_BOUND_TRACKING - int (*get_latency_limited) (surf_action_t action); /**< Return 1 if action is limited by latency, 0 otherwise */ -#endif - - void (*gap_remove) (surf_action_lmm_t action); - - surf_model_private_t model_private; - - union extension { - s_surf_model_extension_cpu_t cpu; - s_surf_model_extension_network_t network; - s_surf_model_extension_storage_t storage; - s_surf_model_extension_workstation_t workstation; - /*******************************************/ - /* TUTORIAL: New model */ - s_surf_model_extension_new_model_t new_model; - /*******************************************/ - } extension; -} s_surf_model_t; - -surf_model_t surf_model_init(void); -void surf_model_exit(surf_model_t model); - static inline void *surf_cpu_resource_priv(const void *host) { - return xbt_lib_get_level((void *)host, SURF_CPU_LEVEL); + return xbt_lib_get_level((xbt_dictelm_t)host, SURF_CPU_LEVEL); } static inline void *surf_workstation_resource_priv(const void *host){ - return xbt_lib_get_level((void *)host, SURF_WKS_LEVEL); + return (void*)xbt_lib_get_level((xbt_dictelm_t)host, SURF_WKS_LEVEL); } - static inline void *surf_storage_resource_priv(const void *host){ - return (void*)xbt_lib_get_level((xbt_dictelm_t)host, SURF_STORAGE_LEVEL); + static inline void *surf_storage_resource_priv(const void *storage){ - return xbt_lib_get_level((void *)storage, SURF_STORAGE_LEVEL); ++ return (void*)xbt_lib_get_level((xbt_dictelm_t)storage, SURF_STORAGE_LEVEL); } static inline void *surf_cpu_resource_by_name(const char *name) { @@@ -301,65 -375,29 +322,76 @@@ static inline void *surf_storage_resour return xbt_lib_get_elm_or_null(storage_lib, name); } -typedef struct surf_resource { - surf_model_t model; - char *name; - xbt_dict_t properties; - void_f_pvoid_t free_f; -} s_surf_resource_t, *surf_resource_t; - -/** - * Resource which have a metric handled by a maxmin system - */ -typedef struct { - double scale; - double peak; - tmgr_trace_event_t event; -} s_surf_metric_t; - -typedef struct surf_resource_lmm { - s_surf_resource_t generic_resource; - lmm_constraint_t constraint; - e_surf_resource_state_t state_current; - tmgr_trace_event_t state_event; - s_surf_metric_t power; -} s_surf_resource_lmm_t, *surf_resource_lmm_t; +#ifdef __cplusplus +extern "C" { +#endif +char *surf_routing_edge_name(sg_routing_edge_t edge); +void *surf_as_cluster_get_backbone(AS_t as); +void surf_as_cluster_set_backbone(AS_t as, void* backbone); +const char *surf_model_name(surf_model_t model); +xbt_swag_t surf_model_done_action_set(surf_model_t model); +xbt_swag_t surf_model_failed_action_set(surf_model_t model); +xbt_swag_t surf_model_ready_action_set(surf_model_t model); +xbt_swag_t surf_model_running_action_set(surf_model_t model); +surf_action_t surf_workstation_model_execute_parallel_task(surf_workstation_model_t model, + int workstation_nb, + void **workstation_list, + double *computation_amount, + double *communication_amount, + double rate); +surf_action_t surf_workstation_model_communicate(surf_workstation_model_t model, surf_resource_t src, surf_resource_t dst, double size, double rate); +xbt_dynar_t surf_workstation_model_get_route(surf_workstation_model_t model, surf_resource_t src, surf_resource_t dst); +surf_action_t surf_network_model_communicate(surf_network_model_t model, sg_routing_edge_t src, sg_routing_edge_t dst, double size, double rate); +const char *surf_resource_name(surf_cpp_resource_t resource); +xbt_dict_t surf_resource_get_properties(surf_cpp_resource_t resource); +e_surf_resource_state_t surf_resource_get_state(surf_cpp_resource_t resource); +double surf_workstation_get_speed(surf_resource_t resource, double load); +double surf_workstation_get_available_speed(surf_resource_t resource); +int surf_workstation_get_core(surf_resource_t resource); +surf_action_t surf_workstation_execute(surf_resource_t resource, double size); +surf_action_t surf_workstation_sleep(surf_resource_t resource, double duration); +surf_action_t surf_workstation_open(surf_resource_t workstation, const char* mount, const char* path); +surf_action_t surf_workstation_close(surf_resource_t workstation, surf_file_t fd); ++surf_action_t surf_workstation_read(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size); ++surf_action_t surf_workstation_write(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size); ++xbt_dynar_t surf_workstation_get_info(surf_resource_t resource, surf_file_t fd); ++sg_storage_size_t surf_workstation_get_free_size(surf_resource_t resource, const char* name); ++sg_storage_size_t surf_workstation_get_used_size(surf_resource_t resource, const char* name); +surf_action_t surf_cpu_execute(surf_resource_t cpu, double size); +surf_action_t surf_cpu_sleep(surf_resource_t cpu, double duration); ++double surf_workstation_get_current_power_peak(surf_resource_t host); ++double surf_workstation_get_power_peak_at(surf_resource_t host, int pstate_index); ++int surf_workstation_get_nb_pstates(surf_resource_t host); ++void surf_workstation_set_power_peak_at(surf_resource_t host, int pstate_index); ++double surf_workstation_get_consumed_energy(surf_resource_t host); ++xbt_dict_t surf_workstation_get_storage_list(surf_resource_t workstation); +int surf_workstation_unlink(surf_resource_t workstation, surf_file_t fd); +surf_action_t surf_workstation_ls(surf_resource_t workstation, const char* mount, const char *path); +size_t surf_workstation_get_size(surf_resource_t workstation, surf_file_t fd); - surf_action_t surf_workstation_read(surf_resource_t resource, void *ptr, size_t size, surf_file_t fd); - surf_action_t surf_workstation_write(surf_resource_t resource, const void *ptr, size_t size, surf_file_t fd); +int surf_network_link_is_shared(surf_cpp_resource_t link); +double surf_network_link_get_bandwidth(surf_cpp_resource_t link); +double surf_network_link_get_latency(surf_cpp_resource_t link); ++xbt_dict_t surf_storage_get_content(surf_resource_t resource); ++sg_storage_size_t surf_storage_get_size(surf_resource_t resource); +void *surf_action_get_data(surf_action_t action); +void surf_action_set_data(surf_action_t action, void *data); +void surf_action_unref(surf_action_t action); +double surf_action_get_start_time(surf_action_t action); +double surf_action_get_finish_time(surf_action_t action); +double surf_action_get_remains(surf_action_t action); +void surf_action_suspend(surf_action_t action); +void surf_action_resume(surf_action_t action); +void surf_action_cancel(surf_action_t action); +void surf_action_set_priority(surf_action_t action, double priority); +void surf_action_set_category(surf_action_t action, const char *category); +e_surf_action_state_t surf_action_get_state(surf_action_t action); +int surf_action_get_cost(surf_action_t action); +surf_file_t surf_storage_action_get_file(surf_action_t action); +xbt_dict_t surf_storage_action_get_ls_dict(surf_action_t action); + +#ifdef __cplusplus +} +#endif /**************************************/ /* Implementations of model object */ @@@ -550,6 -588,8 +582,8 @@@ XBT_PUBLIC(void) surf_storage_model_ini */ XBT_PUBLIC_DATA(s_surf_model_description_t) surf_storage_model_description[]; -XBT_PUBLIC_DATA(surf_model_t) surf_storage_model; ++XBT_PUBLIC_DATA(surf_storage_model_t) surf_storage_model; + /** \ingroup SURF_models * \brief The workstation model * diff --cc src/include/surf/surf_resource.h index e9c78c0c9f,963fdffd89..fdc1eb64bb --- a/src/include/surf/surf_resource.h +++ b/src/include/surf/surf_resource.h @@@ -9,10 -9,10 +9,10 @@@ #ifndef SURF_RESOURCE_H #define SURF_RESOURCE_H -static XBT_INLINE +/*FIXME:DELETEstatic XBT_INLINE surf_resource_t surf_resource_new(size_t childsize, surf_model_t model, const char *name, - xbt_dict_t props) + xbt_dict_t props, void_f_pvoid_t free_f) { surf_resource_t res = xbt_malloc0(childsize); res->model = model; diff --cc src/instr/instr_private.h index d853fbaeb6,21baa8f795..d758703695 --- a/src/instr/instr_private.h +++ b/src/instr/instr_private.h @@@ -102,12 -102,8 +102,12 @@@ extern xbt_dict_t user_vm_variables extern xbt_dict_t user_link_variables; extern double TRACE_last_timestamp_to_dump; +#ifdef __cplusplus +extern "C" { +#endif + /* instr_paje_header.c */ - void TRACE_header(int basic); + void TRACE_header(int basic, int size); /* from paje.c */ void TRACE_paje_start(void); diff --cc src/simdag/sd_workstation.c index d73d59e93f,14a0c70f53..f868b59432 --- a/src/simdag/sd_workstation.c +++ b/src/simdag/sd_workstation.c @@@ -445,6 -475,16 +470,16 @@@ void SD_workstation_set_access_mode(SD_ } } + /** + * \brief Return the list of mounted storages on a workstation. + * + * \param workstation a workstation + * \return a dynar containing all mounted storages on the workstation + */ + xbt_dict_t SD_workstation_get_storage_list(SD_workstation_t workstation){ - return surf_workstation_model->extension.workstation.get_storage_list(workstation); ++ return surf_workstation_get_storage_list(workstation); + } + /* Returns whether a task can start now on a workstation*/ /* int __SD_workstation_can_start(SD_workstation_t workstation, SD_task_t task) { diff --cc src/simgrid/sg_config.c index 56c1120c25,5b8a40610f..e2a11b9004 --- a/src/simgrid/sg_config.c +++ b/src/simgrid/sg_config.c @@@ -435,11 -443,26 +443,10 @@@ void sg_config_init(int *argc, char **a surf_storage_model_description[i].name); sprintf(p, ".\n (use 'help' as a value to see the long description of each model)"); - default_value = xbt_strdup("default"); - xbt_cfg_register(&_sg_cfg_set, "storage/model", description, xbt_cfgelm_string, - &default_value, 1, 1, &_sg_cfg_cb__storage_mode, - NULL); + xbt_cfg_register(&_sg_cfg_set, "storage/model", description, + xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL); + xbt_cfg_setdefault_string(_sg_cfg_set, "storage/model", "default"); - /* ********************************************************************* */ - /* TUTORIAL: New model */ - sprintf(description, - "The model to use for the New model. Possible values: "); - p = description; - while (*(++p) != '\0'); - for (i = 0; surf_new_model_description[i].name; i++) - p += sprintf(p, "%s%s", (i == 0 ? "" : ", "), - surf_new_model_description[i].name); - sprintf(p, - ".\n (use 'help' as a value to see the long description of each model)"); - xbt_cfg_register(&_sg_cfg_set, "new_model/model", description, - xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL); - xbt_cfg_setdefault_string(_sg_cfg_set, "new_model/model", "default"); - /* ********************************************************************* */ - sprintf(description, "The model to use for the network. Possible values: "); p = description; diff --cc src/simix/smx_global.c index 1754afcff7,48127cbcf4..4a6c7acac7 --- a/src/simix/smx_global.c +++ b/src/simix/smx_global.c @@@ -317,17 -324,26 +324,27 @@@ void SIMIX_run(void ((void (*)(void*))timer->func)(timer->args); xbt_free(timer); } + /* Wake up all processes waiting for a Surf action to finish */ xbt_dynar_foreach(model_list, iter, model) { - set = model->states.failed_action_set; + set = surf_model_failed_action_set(model); while ((action = xbt_swag_extract(set))) - SIMIX_simcall_post((smx_action_t) action->data); - set = model->states.done_action_set; + SIMIX_simcall_post((smx_action_t) surf_action_get_data(action)); + set = surf_model_done_action_set(model); while ((action = xbt_swag_extract(set))) - SIMIX_simcall_post((smx_action_t) action->data); + SIMIX_simcall_post((smx_action_t) surf_action_get_data(action)); } + /* Autorestart all process */ + if(host_that_restart) { + char *hostname = NULL; + xbt_dynar_foreach(host_that_restart,iter,hostname) { + XBT_INFO("Restart processes on host: %s",hostname); + SIMIX_host_autorestart(SIMIX_host_get_by_name(hostname)); + } + xbt_dynar_reset(host_that_restart); + } + /* Clean processes to destroy */ SIMIX_process_empty_trash(); diff --cc src/simix/smx_host.c index 436bc8aec9,2480bbdcf2..df02f0f8be --- a/src/simix/smx_host.c +++ b/src/simix/smx_host.c @@@ -152,9 -154,20 +152,19 @@@ int SIMIX_pre_host_get_core(smx_simcall int SIMIX_host_get_core(smx_host_t host){ xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)"); - return surf_workstation_model->extension.workstation. - get_core(host); + return surf_workstation_get_core(host); } + xbt_swag_t SIMIX_pre_host_get_process_list(smx_simcall_t simcall, smx_host_t host){ + return SIMIX_host_get_process_list(host); + } + + xbt_swag_t SIMIX_host_get_process_list(smx_host_t host){ + xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)"); + smx_host_priv_t host_priv = SIMIX_host_priv(host); + + return host_priv->process_list; + } double SIMIX_pre_host_get_available_speed(smx_simcall_t simcall, smx_host_t host){ @@@ -163,9 -176,59 +173,53 @@@ double SIMIX_host_get_available_speed(smx_host_t host){ xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)"); - return surf_workstation_model->extension.workstation. - get_available_speed(host); + return surf_workstation_get_available_speed(host); } + double SIMIX_pre_host_get_current_power_peak(smx_simcall_t simcall, smx_host_t host){ + return SIMIX_host_get_current_power_peak(host); + } + double SIMIX_host_get_current_power_peak(smx_host_t host) { + xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)"); - return surf_workstation_model->extension.workstation. - get_current_power_peak(host); ++ return surf_workstation_get_current_power_peak(host); + } + + double SIMIX_pre_host_get_power_peak_at(smx_simcall_t simcall, smx_host_t host, int pstate_index){ + return SIMIX_host_get_power_peak_at(host, pstate_index); + } + double SIMIX_host_get_power_peak_at(smx_host_t host, int pstate_index) { + xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)"); + - return surf_workstation_model->extension.workstation. - get_power_peak_at(host, pstate_index); ++ return surf_workstation_get_power_peak_at(host, pstate_index); + } + + int SIMIX_pre_host_get_nb_pstates(smx_simcall_t simcall, smx_host_t host){ + return SIMIX_host_get_nb_pstates(host); + } + int SIMIX_host_get_nb_pstates(smx_host_t host) { + xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)"); + - return surf_workstation_model->extension.workstation. - get_nb_pstates(host); ++ return surf_workstation_get_nb_pstates(host); + } + + + void SIMIX_pre_host_set_power_peak_at(smx_simcall_t simcall, smx_host_t host, int pstate_index){ + SIMIX_host_set_power_peak_at(host, pstate_index); + } + void SIMIX_host_set_power_peak_at(smx_host_t host, int pstate_index) { + xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)"); + - surf_workstation_model->extension.workstation. - set_power_peak_at(host, pstate_index); ++ surf_workstation_set_power_peak_at(host, pstate_index); + } + + double SIMIX_pre_host_get_consumed_energy(smx_simcall_t simcall, smx_host_t host){ + return SIMIX_host_get_consumed_energy(host); + } + double SIMIX_host_get_consumed_energy(smx_host_t host) { + xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)"); - return surf_workstation_model->extension.workstation. - get_consumed_energy(host); ++ return surf_workstation_get_consumed_energy(host); + } + int SIMIX_pre_host_get_state(smx_simcall_t simcall, smx_host_t host){ return SIMIX_host_get_state(host); } @@@ -557,3 -635,11 +623,11 @@@ void SIMIX_set_category(smx_action_t ac } #endif + xbt_dict_t SIMIX_pre_host_get_storage_list(smx_simcall_t simcall, smx_host_t host){ + return SIMIX_host_get_storage_list(host); + } + xbt_dict_t SIMIX_host_get_storage_list(smx_host_t host){ + xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)"); + - return surf_workstation_model->extension.workstation.get_storage_list(host); ++ return surf_workstation_get_storage_list(host); + } diff --cc src/simix/smx_io.c index 971ccf61d2,07a354ca90..f177592824 --- a/src/simix/smx_io.c +++ b/src/simix/smx_io.c @@@ -5,7 -5,7 +5,7 @@@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "smx_private.h" --#include "surf/storage_private.h" ++//#include "surf/storage_private.h" #include "xbt/sysdep.h" #include "xbt/log.h" #include "xbt/dict.h" @@@ -44,9 -98,10 +97,9 @@@ smx_action_t SIMIX_file_read(smx_proces #endif action->io.host = host; - action->io.surf_io = surf_workstation_read(host, ptr, size, fd->surf_file); - action->io.surf_io = - surf_workstation_model->extension.workstation.read(host, fd->surf_file, size); ++ action->io.surf_io = surf_workstation_read(host, fd->surf_file, size); - surf_workstation_model->action_data_set(action->io.surf_io, action); + surf_action_set_data(action->io.surf_io, action); XBT_DEBUG("Create io action %p", action); return action; @@@ -81,9 -135,10 +132,9 @@@ smx_action_t SIMIX_file_write(smx_proce #endif action->io.host = host; - action->io.surf_io = surf_workstation_write(host, ptr, size, fd->surf_file); - action->io.surf_io = - surf_workstation_model->extension.workstation.write(host, fd->surf_file, size); ++ action->io.surf_io = surf_workstation_write(host, fd->surf_file, size); - surf_workstation_model->action_data_set(action->io.surf_io, action); + surf_action_set_data(action->io.surf_io, action); XBT_DEBUG("Create io action %p", action); return action; @@@ -177,8 -236,8 +228,8 @@@ int SIMIX_file_unlink(smx_process_t pro sg_host_name(host)); } - if (surf_workstation_model->extension.workstation.unlink(host, fd->surf_file)){ + if (surf_workstation_unlink(host, fd->surf_file)){ - fd->surf_file = NULL; + xbt_free(fd); return 1; } else return 0; @@@ -222,12 -281,97 +273,95 @@@ sg_storage_size_t SIMIX_pre_file_get_si return SIMIX_file_get_size(simcall->issuer, fd); } - size_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd) + sg_storage_size_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd) { smx_host_t host = process->smx_host; - return surf_workstation_model->extension.workstation.get_size(host, - fd->surf_file); + return surf_workstation_get_size(host, fd->surf_file); } + xbt_dynar_t SIMIX_pre_file_get_info(smx_simcall_t simcall, smx_file_t fd) + { + return SIMIX_file_get_info(simcall->issuer, fd); + } + + xbt_dynar_t SIMIX_file_get_info(smx_process_t process, smx_file_t fd) + { + smx_host_t host = process->smx_host; - return surf_workstation_model->extension.workstation.get_info(host, - fd->surf_file); ++ return surf_workstation_get_info(host, fd->surf_file); + } + + sg_storage_size_t SIMIX_pre_storage_get_free_size(smx_simcall_t simcall, const char* name) + { + return SIMIX_storage_get_free_size(simcall->issuer, name); + } + + sg_storage_size_t SIMIX_storage_get_free_size(smx_process_t process, const char* name) + { + smx_host_t host = process->smx_host; - return surf_workstation_model->extension.workstation.get_free_size(host,name); ++ return surf_workstation_get_free_size(host, name); + } + + sg_storage_size_t SIMIX_pre_storage_get_used_size(smx_simcall_t simcall, const char* name) + { + return SIMIX_storage_get_used_size(simcall->issuer, name); + } + + sg_storage_size_t SIMIX_storage_get_used_size(smx_process_t process, const char* name) + { + smx_host_t host = process->smx_host; - return surf_workstation_model->extension.workstation.get_used_size(host,name); ++ return surf_workstation_get_used_size(host, name); + } + + xbt_dict_t SIMIX_pre_storage_get_properties(smx_simcall_t simcall, smx_storage_t storage){ + return SIMIX_storage_get_properties(storage); + } + xbt_dict_t SIMIX_storage_get_properties(smx_storage_t storage){ + xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)"); - return surf_storage_model->extension.storage.get_properties(storage); ++ return surf_resource_get_properties(surf_workstation_resource_priv(storage)); + } + + const char* SIMIX_pre_storage_get_name(smx_simcall_t simcall, smx_storage_t storage){ + return SIMIX_storage_get_name(storage); + } + + const char* SIMIX_storage_get_name(smx_storage_t storage){ + xbt_assert((storage != NULL), "Invalid parameters"); + return sg_storage_name(storage); + } + + void SIMIX_pre_storage_set_data(smx_simcall_t simcall, smx_storage_t storage, void *data) { + SIMIX_storage_set_data(storage, data); + } + void SIMIX_storage_set_data(smx_storage_t storage, void *data){ + xbt_assert((storage != NULL), "Invalid parameters"); + xbt_assert((SIMIX_storage_priv(storage)->data == NULL), "Data already set"); + + SIMIX_storage_priv(storage)->data = data; + } + + void* SIMIX_pre_storage_get_data(smx_simcall_t simcall,smx_storage_t storage){ + return SIMIX_storage_get_data(storage); + } + + void* SIMIX_storage_get_data(smx_storage_t storage){ + xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)"); + + return SIMIX_storage_priv(storage)->data; + } + + xbt_dict_t SIMIX_pre_storage_get_content(smx_simcall_t simcall, smx_storage_t storage){ + return SIMIX_storage_get_content(storage); + } + + xbt_dict_t SIMIX_storage_get_content(smx_storage_t storage){ + xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)"); - return surf_storage_model->extension.storage.get_content(storage); ++ return surf_storage_get_content(storage); + } + + sg_storage_size_t SIMIX_storage_get_size(smx_storage_t storage){ + xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)"); - return surf_storage_model->extension.storage.get_size(storage); ++ return surf_storage_get_size(storage); + } void SIMIX_post_io(smx_action_t action) { diff --cc src/simix/smx_smurf_private.h index 104a78e73a,1e191f71e4..bb33f4d164 --- a/src/simix/smx_smurf_private.h +++ b/src/simix/smx_smurf_private.h @@@ -273,95 -259,109 +273,109 @@@ /* the list of simcalls definitions */ #define SIMCALL_LIST1(ACTION, sep) \ -ACTION(SIMCALL_HOST_GET_BY_NAME, host_get_by_name, WITH_ANSWER, TSPEC(result, smx_host_t), TSTRING(name)) sep \ -ACTION(SIMCALL_HOST_GET_NAME, host_get_name, WITH_ANSWER, TSTRING(result), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_GET_PROPERTIES, host_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_GET_CORE, host_get_core, WITH_ANSWER, TINT(result), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_GET_PROCESS_LIST, host_get_process_list, WITH_ANSWER, TSPEC(result, xbt_swag_t), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_GET_SPEED, host_get_speed, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_GET_AVAILABLE_SPEED, host_get_available_speed, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_GET_STATE, host_get_state, WITH_ANSWER, TINT(result), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_GET_DATA, host_get_data, WITH_ANSWER, TPTR(result), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_SET_DATA, host_set_data, WITH_ANSWER, TVOID(result), TSPEC(host, smx_host_t), TPTR(data)) sep \ -ACTION(SIMCALL_HOST_GET_CURRENT_POWER_PEAK, host_get_current_power_peak, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_GET_POWER_PEAK_AT, host_get_power_peak_at, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t), TINT(pstate_index)) sep \ -ACTION(SIMCALL_HOST_GET_NB_PSTATES, host_get_nb_pstates, WITH_ANSWER, TINT(result), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_SET_POWER_PEAK_AT, host_set_power_peak_at, WITH_ANSWER, TVOID(result), TSPEC(host, smx_host_t), TINT(pstate_index)) sep \ -ACTION(SIMCALL_HOST_GET_CONSUMED_ENERGY, host_get_consumed_energy, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_HOST_EXECUTE, host_execute, WITH_ANSWER, TSPEC(result, smx_action_t), TSTRING(name), TSPEC(host, smx_host_t), TDOUBLE(computation_amount), TDOUBLE(priority)) sep \ -ACTION(SIMCALL_HOST_PARALLEL_EXECUTE, host_parallel_execute, WITH_ANSWER, TSPEC(result, smx_action_t), TSTRING(name), TINT(host_nb), TSPEC(host_list, smx_host_t*), TSPEC(computation_amount, double*), TSPEC(communication_amount, double*), TDOUBLE(amount), TDOUBLE(rate)) sep \ -ACTION(SIMCALL_HOST_EXECUTION_DESTROY, host_execution_destroy, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t)) sep \ -ACTION(SIMCALL_HOST_EXECUTION_CANCEL, host_execution_cancel, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t)) sep \ -ACTION(SIMCALL_HOST_EXECUTION_GET_REMAINS, host_execution_get_remains, WITH_ANSWER, TDOUBLE(result), TSPEC(execution, smx_action_t)) sep \ -ACTION(SIMCALL_HOST_EXECUTION_GET_STATE, host_execution_get_state, WITH_ANSWER, TINT(result), TSPEC(execution, smx_action_t)) sep \ -ACTION(SIMCALL_HOST_EXECUTION_SET_PRIORITY, host_execution_set_priority, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t), TDOUBLE(priority)) sep \ -ACTION(SIMCALL_HOST_EXECUTION_WAIT, host_execution_wait, WITHOUT_ANSWER, TINT(result), TSPEC(execution, smx_action_t)) sep \ -ACTION(SIMCALL_HOST_GET_STORAGE_LIST, host_get_storage_list, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_PROCESS_CREATE, process_create, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t*), TSTRING(name), TSPEC(code, xbt_main_func_t), TPTR(data), TSTRING(hostname), TDOUBLE(kill_time), TINT(argc), TSPEC(argv, char**), TSPEC(properties, xbt_dict_t), TINT(auto_restart)) sep \ -ACTION(SIMCALL_PROCESS_KILL, process_kill, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_HOST_GET_BY_NAME, host_get_by_name, WITH_ANSWER, TDSPEC(result, smx_host_t), TSTRING(name)) sep \ +ACTION(SIMCALL_HOST_GET_NAME, host_get_name, WITH_ANSWER, TSTRING(result), TDSPEC(host, smx_host_t)) sep \ +ACTION(SIMCALL_HOST_GET_PROPERTIES, host_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(host, smx_host_t)) sep \ +ACTION(SIMCALL_HOST_GET_CORE, host_get_core, WITH_ANSWER, TINT(result), TDSPEC(host, smx_host_t)) sep \ ++ACTION(SIMCALL_HOST_GET_PROCESS_LIST, host_get_process_list, WITH_ANSWER, TDSPEC(result, xbt_swag_t), TDSPEC(host, smx_host_t)) sep \ +ACTION(SIMCALL_HOST_GET_SPEED, host_get_speed, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \ +ACTION(SIMCALL_HOST_GET_AVAILABLE_SPEED, host_get_available_speed, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \ +ACTION(SIMCALL_HOST_GET_STATE, host_get_state, WITH_ANSWER, TINT(result), TDSPEC(host, smx_host_t)) sep \ +ACTION(SIMCALL_HOST_GET_DATA, host_get_data, WITH_ANSWER, TDPTR(result), TDSPEC(host, smx_host_t)) sep \ +ACTION(SIMCALL_HOST_SET_DATA, host_set_data, WITH_ANSWER, TVOID(result), TDSPEC(host, smx_host_t), TDPTR(data)) sep \ ++ACTION(SIMCALL_HOST_GET_CURRENT_POWER_PEAK, host_get_current_power_peak, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \ ++ACTION(SIMCALL_HOST_GET_POWER_PEAK_AT, host_get_power_peak_at, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t), TINT(pstate_index)) sep \ ++ACTION(SIMCALL_HOST_GET_NB_PSTATES, host_get_nb_pstates, WITH_ANSWER, TINT(result), TDSPEC(host, smx_host_t)) sep \ ++ACTION(SIMCALL_HOST_SET_POWER_PEAK_AT, host_set_power_peak_at, WITH_ANSWER, TVOID(result), TDSPEC(host, smx_host_t), TINT(pstate_index)) sep \ ++ACTION(SIMCALL_HOST_GET_CONSUMED_ENERGY, host_get_consumed_energy, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \ +ACTION(SIMCALL_HOST_EXECUTE, host_execute, WITH_ANSWER, TDSPEC(result, smx_action_t), TSTRING(name), TDSPEC(host, smx_host_t), TDOUBLE(computation_amount), TDOUBLE(priority)) sep \ +ACTION(SIMCALL_HOST_PARALLEL_EXECUTE, host_parallel_execute, WITH_ANSWER, TDSPEC(result, smx_action_t), TSTRING(name), TINT(host_nb), TDSPEC(host_list, smx_host_t*), TDSPEC(computation_amount, double*), TDSPEC(communication_amount, double*), TDOUBLE(amount), TDOUBLE(rate)) sep \ +ACTION(SIMCALL_HOST_EXECUTION_DESTROY, host_execution_destroy, WITH_ANSWER, TVOID(result), TDSPEC(execution, smx_action_t)) sep \ +ACTION(SIMCALL_HOST_EXECUTION_CANCEL, host_execution_cancel, WITH_ANSWER, TVOID(result), TDSPEC(execution, smx_action_t)) sep \ +ACTION(SIMCALL_HOST_EXECUTION_GET_REMAINS, host_execution_get_remains, WITH_ANSWER, TDOUBLE(result), TDSPEC(execution, smx_action_t)) sep \ +ACTION(SIMCALL_HOST_EXECUTION_GET_STATE, host_execution_get_state, WITH_ANSWER, TINT(result), TDSPEC(execution, smx_action_t)) sep \ +ACTION(SIMCALL_HOST_EXECUTION_SET_PRIORITY, host_execution_set_priority, WITH_ANSWER, TVOID(result), TDSPEC(execution, smx_action_t), TDOUBLE(priority)) sep \ +ACTION(SIMCALL_HOST_EXECUTION_WAIT, host_execution_wait, WITHOUT_ANSWER, TINT(result), TDSPEC(execution, smx_action_t)) sep \ ++ACTION(SIMCALL_HOST_GET_STORAGE_LIST, host_get_storage_list, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(host, smx_host_t)) sep \ +ACTION(SIMCALL_PROCESS_CREATE, process_create, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t*), TSTRING(name), TFSPEC(code, xbt_main_func_t), TDPTR(data), TSTRING(hostname), TDOUBLE(kill_time), TINT(argc), TDSPEC(argv, char**), TDSPEC(properties, xbt_dict_t), TINT(auto_restart)) sep \ +ACTION(SIMCALL_PROCESS_KILL, process_kill, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \ ACTION(SIMCALL_PROCESS_KILLALL, process_killall, WITH_ANSWER, TVOID(result), TINT(reset_pid)) sep \ -ACTION(SIMCALL_PROCESS_CLEANUP, process_cleanup, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \ -ACTION(SIMCALL_PROCESS_CHANGE_HOST, process_change_host, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TSPEC(dest, smx_host_t)) sep \ -ACTION(SIMCALL_PROCESS_SUSPEND, process_suspend, WITHOUT_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \ -ACTION(SIMCALL_PROCESS_RESUME, process_resume, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_PROCESS_CLEANUP, process_cleanup, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_PROCESS_CHANGE_HOST, process_change_host, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TDSPEC(dest, smx_host_t)) sep \ +ACTION(SIMCALL_PROCESS_SUSPEND, process_suspend, WITHOUT_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_PROCESS_RESUME, process_resume, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \ ACTION(SIMCALL_PROCESS_COUNT, process_count, WITH_ANSWER, TINT(result)) sep \ -ACTION(SIMCALL_PROCESS_GET_PID, process_get_PID, WITH_ANSWER, TINT(result), TSPEC(process, smx_process_t)) sep \ -ACTION(SIMCALL_PROCESS_GET_PPID, process_get_PPID, WITH_ANSWER, TINT(result), TSPEC(process, smx_process_t)) sep \ -ACTION(SIMCALL_PROCESS_GET_DATA, process_get_data, WITH_ANSWER, TPTR(result), TSPEC(process, smx_process_t)) sep \ -ACTION(SIMCALL_PROCESS_SET_DATA, process_set_data, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TPTR(data)) sep \ -ACTION(SIMCALL_PROCESS_GET_HOST, process_get_host, WITH_ANSWER, TSPEC(result, smx_host_t), TSPEC(process, smx_process_t)) sep \ -ACTION(SIMCALL_PROCESS_GET_NAME, process_get_name, WITH_ANSWER, TSTRING(result), TSPEC(process, smx_process_t)) sep \ -ACTION(SIMCALL_PROCESS_IS_SUSPENDED, process_is_suspended, WITH_ANSWER, TINT(result), TSPEC(process, smx_process_t)) sep \ -ACTION(SIMCALL_PROCESS_GET_PROPERTIES, process_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_PROCESS_GET_PID, process_get_PID, WITH_ANSWER, TINT(result), TDSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_PROCESS_GET_PPID, process_get_PPID, WITH_ANSWER, TINT(result), TDSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_PROCESS_GET_DATA, process_get_data, WITH_ANSWER, TDPTR(result), TDSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_PROCESS_SET_DATA, process_set_data, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TDPTR(data)) sep \ +ACTION(SIMCALL_PROCESS_GET_HOST, process_get_host, WITH_ANSWER, TDSPEC(result, smx_host_t), TDSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_PROCESS_GET_NAME, process_get_name, WITH_ANSWER, TSTRING(result), TDSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_PROCESS_IS_SUSPENDED, process_is_suspended, WITH_ANSWER, TINT(result), TDSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_PROCESS_GET_PROPERTIES, process_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(process, smx_process_t)) sep \ ACTION(SIMCALL_PROCESS_SLEEP, process_sleep, WITHOUT_ANSWER, TINT(result), TDOUBLE(duration)) sep \ -ACTION(SIMCALL_PROCESS_ON_EXIT, process_on_exit, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TSPEC(fun, int_f_pvoid_t), TPTR(data)) sep \ -ACTION(SIMCALL_PROCESS_AUTO_RESTART_SET, process_auto_restart_set, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TINT(auto_restart)) sep \ -ACTION(SIMCALL_PROCESS_RESTART, process_restart, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(process, smx_process_t)) sep \ -ACTION(SIMCALL_RDV_CREATE, rdv_create, WITH_ANSWER, TSPEC(result, smx_rdv_t), TSTRING(name)) sep \ -ACTION(SIMCALL_RDV_DESTROY, rdv_destroy, WITH_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t)) sep \ -ACTION(SIMCALL_RDV_GET_BY_NAME, rdv_get_by_name, WITH_ANSWER, TSPEC(result, smx_host_t), TSTRING(name)) sep \ -ACTION(SIMCALL_RDV_COMM_COUNT_BY_HOST, rdv_comm_count_by_host, WITH_ANSWER, TUINT(result), TSPEC(rdv, smx_rdv_t), TSPEC(host, smx_host_t)) sep \ -ACTION(SIMCALL_RDV_GET_HEAD, rdv_get_head, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t)) sep \ -ACTION(SIMCALL_RDV_SET_RECV, rdv_set_receiver, WITH_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TSPEC(receiver, smx_process_t)) sep \ -ACTION(SIMCALL_RDV_GET_RECV, rdv_get_receiver, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(rdv, smx_rdv_t)) sep \ -ACTION(SIMCALL_COMM_IPROBE, comm_iprobe, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TINT(src), TINT(tag), TSPEC(match_fun, simix_match_func_t), TPTR(data)) sep \ -ACTION(SIMCALL_COMM_SEND, comm_send, WITHOUT_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TPTR(src_buff), TSIZE(src_buff_size), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(timeout)) sep \ -ACTION(SIMCALL_COMM_ISEND, comm_isend, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TPTR(src_buff), TSIZE(src_buff_size), TSPEC(match_fun, simix_match_func_t), TSPEC(clean_fun, simix_clean_func_t), TPTR(data), TINT(detached)) sep \ -ACTION(SIMCALL_COMM_RECV, comm_recv, WITHOUT_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(timeout)) sep \ -ACTION(SIMCALL_COMM_IRECV, comm_irecv, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data)) sep \ -ACTION(SIMCALL_COMM_RECV_BOUNDED, comm_recv_bounded, WITHOUT_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(timeout), TDOUBLE(rate)) sep \ -ACTION(SIMCALL_COMM_IRECV_BOUNDED, comm_irecv_bounded, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(rate)) sep \ -ACTION(SIMCALL_COMM_DESTROY, comm_destroy, WITH_ANSWER, TVOID(result), TSPEC(comm, smx_action_t)) sep \ -ACTION(SIMCALL_COMM_CANCEL, comm_cancel, WITH_ANSWER, TVOID(result), TSPEC(comm, smx_action_t)) sep \ -ACTION(SIMCALL_COMM_WAITANY, comm_waitany, WITHOUT_ANSWER, TINT(result), TSPEC(comms, xbt_dynar_t)) sep \ -ACTION(SIMCALL_COMM_WAIT, comm_wait, WITHOUT_ANSWER, TVOID(result), TSPEC(comm, smx_action_t), TDOUBLE(timeout)) sep \ -ACTION(SIMCALL_COMM_TEST, comm_test, WITHOUT_ANSWER, TINT(result), TSPEC(comm, smx_action_t)) sep \ -ACTION(SIMCALL_COMM_TESTANY, comm_testany, WITHOUT_ANSWER, TINT(result), TSPEC(comms, xbt_dynar_t)) sep \ -ACTION(SIMCALL_COMM_GET_REMAINS, comm_get_remains, WITH_ANSWER, TDOUBLE(result), TSPEC(comm, smx_action_t)) sep \ -ACTION(SIMCALL_COMM_GET_STATE, comm_get_state, WITH_ANSWER, TINT(result), TSPEC(comm, smx_action_t)) sep \ -ACTION(SIMCALL_COMM_GET_SRC_DATA, comm_get_src_data, WITH_ANSWER, TPTR(result), TSPEC(comm, smx_action_t)) sep \ -ACTION(SIMCALL_COMM_GET_DST_DATA, comm_get_dst_data, WITH_ANSWER, TPTR(result), TSPEC(comm, smx_action_t)) sep \ -ACTION(SIMCALL_COMM_GET_SRC_PROC, comm_get_src_proc, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(comm, smx_action_t)) sep \ -ACTION(SIMCALL_COMM_GET_DST_PROC, comm_get_dst_proc, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(comm, smx_action_t)) sep \ -ACTION(SIMCALL_MUTEX_INIT, mutex_init, WITH_ANSWER, TSPEC(result, smx_mutex_t)) sep \ -ACTION(SIMCALL_MUTEX_DESTROY, mutex_destroy, WITH_ANSWER, TVOID(result), TSPEC(mutex, smx_mutex_t)) sep \ -ACTION(SIMCALL_MUTEX_LOCK, mutex_lock, WITHOUT_ANSWER, TVOID(result), TSPEC(mutex, smx_mutex_t)) sep \ -ACTION(SIMCALL_MUTEX_TRYLOCK, mutex_trylock, WITH_ANSWER, TINT(result), TSPEC(mutex, smx_mutex_t)) sep \ -ACTION(SIMCALL_MUTEX_UNLOCK, mutex_unlock, WITH_ANSWER, TVOID(result), TSPEC(mutex, smx_mutex_t)) sep \ -ACTION(SIMCALL_COND_INIT, cond_init, WITH_ANSWER, TSPEC(result, smx_cond_t)) sep \ -ACTION(SIMCALL_COND_DESTROY, cond_destroy, WITH_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t)) sep \ -ACTION(SIMCALL_COND_SIGNAL, cond_signal, WITH_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t)) sep \ -ACTION(SIMCALL_COND_WAIT, cond_wait, WITHOUT_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t), TSPEC(mutex, smx_mutex_t)) sep \ -ACTION(SIMCALL_COND_WAIT_TIMEOUT, cond_wait_timeout, WITHOUT_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t), TSPEC(mutex, smx_mutex_t), TDOUBLE(timeout)) sep \ -ACTION(SIMCALL_COND_BROADCAST, cond_broadcast, WITH_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t)) sep \ -ACTION(SIMCALL_SEM_INIT, sem_init, WITH_ANSWER, TSPEC(result, smx_sem_t), TINT(capacity)) sep \ -ACTION(SIMCALL_SEM_DESTROY, sem_destroy, WITH_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t)) sep \ -ACTION(SIMCALL_SEM_RELEASE, sem_release, WITH_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t)) sep \ -ACTION(SIMCALL_SEM_WOULD_BLOCK, sem_would_block, WITH_ANSWER, TINT(result), TSPEC(sem, smx_sem_t)) sep \ -ACTION(SIMCALL_SEM_ACQUIRE, sem_acquire, WITHOUT_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t)) sep \ -ACTION(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem_acquire_timeout, WITHOUT_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t), TDOUBLE(timeout)) sep \ -ACTION(SIMCALL_SEM_GET_CAPACITY, sem_get_capacity, WITH_ANSWER, TINT(result), TSPEC(sem, smx_sem_t)) sep \ -ACTION(SIMCALL_FILE_GET_DATA, file_get_data, WITH_ANSWER, TPTR(result), TSPEC(fd, smx_file_t)) sep \ -ACTION(SIMCALL_FILE_SET_DATA, file_set_data, WITH_ANSWER, TVOID(result), TSPEC(fd, smx_file_t), TPTR(data)) sep \ -ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t), TSIZE(size)) sep \ -ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t), TSIZE(size)) sep \ -ACTION(SIMCALL_FILE_OPEN, file_open, WITHOUT_ANSWER, TSPEC(result, smx_file_t), TSTRING(mount), TSTRING(path)) sep \ -ACTION(SIMCALL_FILE_CLOSE, file_close, WITHOUT_ANSWER, TINT(result), TSPEC(fd, smx_file_t)) sep \ -ACTION(SIMCALL_FILE_UNLINK, file_unlink, WITH_ANSWER, TINT(result), TSPEC(fd, smx_file_t)) sep \ -ACTION(SIMCALL_FILE_LS, file_ls, WITHOUT_ANSWER, TSPEC(result, xbt_dict_t), TSTRING(mount), TSTRING(path)) sep \ -ACTION(SIMCALL_FILE_GET_SIZE, file_get_size, WITH_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t)) sep \ -ACTION(SIMCALL_FILE_GET_INFO, file_get_info, WITH_ANSWER, TSPEC(result, xbt_dynar_t), TSPEC(fd, smx_file_t)) sep \ +ACTION(SIMCALL_PROCESS_ON_EXIT, process_on_exit, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TFSPEC(fun, int_f_pvoid_t), TDPTR(data)) sep \ +ACTION(SIMCALL_PROCESS_AUTO_RESTART_SET, process_auto_restart_set, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TINT(auto_restart)) sep \ +ACTION(SIMCALL_PROCESS_RESTART, process_restart, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(process, smx_process_t)) sep \ +ACTION(SIMCALL_RDV_CREATE, rdv_create, WITH_ANSWER, TDSPEC(result, smx_rdv_t), TSTRING(name)) sep \ +ACTION(SIMCALL_RDV_DESTROY, rdv_destroy, WITH_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t)) sep \ +ACTION(SIMCALL_RDV_GET_BY_NAME, rdv_get_by_name, WITH_ANSWER, TDSPEC(result, smx_host_t), TSTRING(name)) sep \ +ACTION(SIMCALL_RDV_COMM_COUNT_BY_HOST, rdv_comm_count_by_host, WITH_ANSWER, TUINT(result), TDSPEC(rdv, smx_rdv_t), TDSPEC(host, smx_host_t)) sep \ +ACTION(SIMCALL_RDV_GET_HEAD, rdv_get_head, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t)) sep \ +ACTION(SIMCALL_RDV_SET_RECV, rdv_set_receiver, WITH_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDSPEC(receiver, smx_process_t)) sep \ +ACTION(SIMCALL_RDV_GET_RECV, rdv_get_receiver, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(rdv, smx_rdv_t)) sep \ +ACTION(SIMCALL_COMM_IPROBE, comm_iprobe, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TINT(src), TINT(tag), TFSPEC(match_fun, simix_match_func_t), TDPTR(data)) sep \ +ACTION(SIMCALL_COMM_SEND, comm_send, WITHOUT_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TDPTR(src_buff), TSIZE(src_buff_size), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(timeout)) sep \ +ACTION(SIMCALL_COMM_ISEND, comm_isend, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TDPTR(src_buff), TSIZE(src_buff_size), TFSPEC(match_fun, simix_match_func_t), TFSPEC(clean_fun, simix_clean_func_t), TDPTR(data), TINT(detached)) sep \ +ACTION(SIMCALL_COMM_RECV, comm_recv, WITHOUT_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(timeout)) sep \ +ACTION(SIMCALL_COMM_IRECV, comm_irecv, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data)) sep \ +ACTION(SIMCALL_COMM_RECV_BOUNDED, comm_recv_bounded, WITHOUT_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(timeout), TDOUBLE(rate)) sep \ +ACTION(SIMCALL_COMM_IRECV_BOUNDED, comm_irecv_bounded, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(rate)) sep \ +ACTION(SIMCALL_COMM_DESTROY, comm_destroy, WITH_ANSWER, TVOID(result), TDSPEC(comm, smx_action_t)) sep \ +ACTION(SIMCALL_COMM_CANCEL, comm_cancel, WITH_ANSWER, TVOID(result), TDSPEC(comm, smx_action_t)) sep \ +ACTION(SIMCALL_COMM_WAITANY, comm_waitany, WITHOUT_ANSWER, TINT(result), TDSPEC(comms, xbt_dynar_t)) sep \ +ACTION(SIMCALL_COMM_WAIT, comm_wait, WITHOUT_ANSWER, TVOID(result), TDSPEC(comm, smx_action_t), TDOUBLE(timeout)) sep \ +ACTION(SIMCALL_COMM_TEST, comm_test, WITHOUT_ANSWER, TINT(result), TDSPEC(comm, smx_action_t)) sep \ +ACTION(SIMCALL_COMM_TESTANY, comm_testany, WITHOUT_ANSWER, TINT(result), TDSPEC(comms, xbt_dynar_t)) sep \ +ACTION(SIMCALL_COMM_GET_REMAINS, comm_get_remains, WITH_ANSWER, TDOUBLE(result), TDSPEC(comm, smx_action_t)) sep \ +ACTION(SIMCALL_COMM_GET_STATE, comm_get_state, WITH_ANSWER, TINT(result), TDSPEC(comm, smx_action_t)) sep \ +ACTION(SIMCALL_COMM_GET_SRC_DATA, comm_get_src_data, WITH_ANSWER, TDPTR(result), TDSPEC(comm, smx_action_t)) sep \ +ACTION(SIMCALL_COMM_GET_DST_DATA, comm_get_dst_data, WITH_ANSWER, TDPTR(result), TDSPEC(comm, smx_action_t)) sep \ +ACTION(SIMCALL_COMM_GET_SRC_PROC, comm_get_src_proc, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(comm, smx_action_t)) sep \ +ACTION(SIMCALL_COMM_GET_DST_PROC, comm_get_dst_proc, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(comm, smx_action_t)) sep \ +ACTION(SIMCALL_MUTEX_INIT, mutex_init, WITH_ANSWER, TDSPEC(result, smx_mutex_t)) sep \ +ACTION(SIMCALL_MUTEX_DESTROY, mutex_destroy, WITH_ANSWER, TVOID(result), TDSPEC(mutex, smx_mutex_t)) sep \ +ACTION(SIMCALL_MUTEX_LOCK, mutex_lock, WITHOUT_ANSWER, TVOID(result), TDSPEC(mutex, smx_mutex_t)) sep \ +ACTION(SIMCALL_MUTEX_TRYLOCK, mutex_trylock, WITH_ANSWER, TINT(result), TDSPEC(mutex, smx_mutex_t)) sep \ +ACTION(SIMCALL_MUTEX_UNLOCK, mutex_unlock, WITH_ANSWER, TVOID(result), TDSPEC(mutex, smx_mutex_t)) sep \ +ACTION(SIMCALL_COND_INIT, cond_init, WITH_ANSWER, TDSPEC(result, smx_cond_t)) sep \ +ACTION(SIMCALL_COND_DESTROY, cond_destroy, WITH_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t)) sep \ +ACTION(SIMCALL_COND_SIGNAL, cond_signal, WITH_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t)) sep \ +ACTION(SIMCALL_COND_WAIT, cond_wait, WITHOUT_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t), TDSPEC(mutex, smx_mutex_t)) sep \ +ACTION(SIMCALL_COND_WAIT_TIMEOUT, cond_wait_timeout, WITHOUT_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t), TDSPEC(mutex, smx_mutex_t), TDOUBLE(timeout)) sep \ +ACTION(SIMCALL_COND_BROADCAST, cond_broadcast, WITH_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t)) sep \ +ACTION(SIMCALL_SEM_INIT, sem_init, WITH_ANSWER, TDSPEC(result, smx_sem_t), TINT(capacity)) sep \ +ACTION(SIMCALL_SEM_DESTROY, sem_destroy, WITH_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t)) sep \ +ACTION(SIMCALL_SEM_RELEASE, sem_release, WITH_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t)) sep \ +ACTION(SIMCALL_SEM_WOULD_BLOCK, sem_would_block, WITH_ANSWER, TINT(result), TDSPEC(sem, smx_sem_t)) sep \ +ACTION(SIMCALL_SEM_ACQUIRE, sem_acquire, WITHOUT_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t)) sep \ +ACTION(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem_acquire_timeout, WITHOUT_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t), TDOUBLE(timeout)) sep \ +ACTION(SIMCALL_SEM_GET_CAPACITY, sem_get_capacity, WITH_ANSWER, TINT(result), TDSPEC(sem, smx_sem_t)) sep \ - ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TSIZE(result), TDPTR(ptr), TSIZE(size), TDSPEC(fd, smx_file_t)) sep \ - ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TCPTR(ptr), TSIZE(size), TDSPEC(fd, smx_file_t)) sep \ ++ACTION(SIMCALL_FILE_GET_DATA, file_get_data, WITH_ANSWER, TDPTR(result), TDSPEC(fd, smx_file_t)) sep \ ++ACTION(SIMCALL_FILE_SET_DATA, file_set_data, WITH_ANSWER, TVOID(result), TDSPEC(fd, smx_file_t), TDPTR(data)) sep \ ++ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TSIZE(result), TDSPEC(fd, smx_file_t), TSIZE(size)) sep \ ++ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TDSPEC(fd, smx_file_t), TSIZE(size)) sep \ +ACTION(SIMCALL_FILE_OPEN, file_open, WITHOUT_ANSWER, TDSPEC(result, smx_file_t), TSTRING(mount), TSTRING(path)) sep \ +ACTION(SIMCALL_FILE_CLOSE, file_close, WITHOUT_ANSWER, TINT(result), TDSPEC(fd, smx_file_t)) sep \ +ACTION(SIMCALL_FILE_UNLINK, file_unlink, WITH_ANSWER, TINT(result), TDSPEC(fd, smx_file_t)) sep \ +ACTION(SIMCALL_FILE_LS, file_ls, WITHOUT_ANSWER, TDSPEC(result, xbt_dict_t), TSTRING(mount), TSTRING(path)) sep \ +ACTION(SIMCALL_FILE_GET_SIZE, file_get_size, WITH_ANSWER, TSIZE(result), TDSPEC(fd, smx_file_t)) sep \ - ACTION(SIMCALL_ASR_GET_PROPERTIES, asr_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TSTRING(name)) sep ++ACTION(SIMCALL_FILE_GET_INFO, file_get_info, WITH_ANSWER, TDSPEC(result, xbt_dynar_t), TDSPEC(fd, smx_file_t)) sep \ + ACTION(SIMCALL_STORAGE_GET_FREE_SIZE, storage_get_free_size, WITH_ANSWER, TSIZE(result), TSTRING(name)) sep \ + ACTION(SIMCALL_STORAGE_GET_USED_SIZE, storage_get_used_size, WITH_ANSWER, TSIZE(result), TSTRING(name)) sep \ -ACTION(SIMCALL_STORAGE_GET_PROPERTIES, storage_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(storage, smx_storage_t)) sep \ -ACTION(SIMCALL_STORAGE_GET_CONTENT, storage_get_content, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(storage, smx_storage_t)) sep \ -ACTION(SIMCALL_ASR_GET_PROPERTIES, asr_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSTRING(name)) sep ++ACTION(SIMCALL_STORAGE_GET_PROPERTIES, storage_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(storage, smx_storage_t)) sep \ ++ACTION(SIMCALL_STORAGE_GET_CONTENT, storage_get_content, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(storage, smx_storage_t)) sep \ ++ACTION(SIMCALL_ASR_GET_PROPERTIES, asr_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TSTRING(name)) sep /* SIMCALL_COMM_IS_LATENCY_BOUNDED and SIMCALL_SET_CATEGORY make things complicated * because they are not always present */ @@@ -381,9 -381,9 +395,9 @@@ ACTION(SIMCALL_SET_CATEGORY, set_catego #ifdef HAVE_MC #define SIMCALL_LIST4(ACTION, sep) \ -ACTION(SIMCALL_MC_SNAPSHOT, mc_snapshot, WITH_ANSWER, TPTR(result)) sep \ -ACTION(SIMCALL_MC_COMPARE_SNAPSHOTS, mc_compare_snapshots, WITH_ANSWER, TINT(result), TPTR(s1), TPTR(s2)) sep \ +ACTION(SIMCALL_MC_SNAPSHOT, mc_snapshot, WITH_ANSWER, TDPTR(result)) sep \ +ACTION(SIMCALL_MC_COMPARE_SNAPSHOTS, mc_compare_snapshots, WITH_ANSWER, TINT(result), TDPTR(s1), TDPTR(s2)) sep \ - ACTION(SIMCALL_MC_RANDOM, mc_random, WITH_ANSWER, TINT(result)) sep + ACTION(SIMCALL_MC_RANDOM, mc_random, WITH_ANSWER, TINT(result), TINT(min), TINT(max)) sep #else #define SIMCALL_LIST4(ACTION, sep) #endif diff --cc src/surf/cpu.cpp index fe58cf0af0,0000000000..d550b0a888 mode 100644,000000..100644 --- a/src/surf/cpu.cpp +++ b/src/surf/cpu.cpp @@@ -1,161 -1,0 +1,164 @@@ +#include "cpu.hpp" + +extern "C" { ++XBT_LOG_EXTERNAL_CATEGORY(surf_kernel); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu, surf, + "Logging specific to the SURF cpu module"); +} + +CpuModelPtr surf_cpu_model; + +/********* + * Model * + *********/ + +void CpuModel::updateActionsStateLazy(double now, double delta) +{ + void *_action; - ActionLmmPtr action; ++ CpuActionLmmPtr action; + while ((xbt_heap_size(p_actionHeap) > 0) + && (double_equals(xbt_heap_maxkey(p_actionHeap), now))) { - action = (ActionLmmPtr) xbt_heap_pop(p_actionHeap); - XBT_DEBUG("Something happened to action %p", action); ++ action = dynamic_cast(static_cast(xbt_heap_pop(p_actionHeap))); ++ XBT_CDEBUG(surf_kernel, "Something happened to action %p", action); +#ifdef HAVE_TRACING + if (TRACE_is_enabled()) { + CpuPtr cpu = (CpuPtr) lmm_constraint_id(lmm_get_cnst_from_var(p_maxminSystem, action->p_variable, 0)); + TRACE_surf_host_set_utilization(cpu->m_name, action->p_category, + lmm_variable_getvalue(action->p_variable), + action->m_lastUpdate, + now - action->m_lastUpdate); + } +#endif + + action->m_finish = surf_get_clock(); - XBT_DEBUG("Action %p finished", action); ++ XBT_CDEBUG(surf_kernel, "Action %p finished", action); ++ ++ action->updateEnergy(); + + /* set the remains to 0 due to precision problems when updating the remaining amount */ + action->m_remains = 0; + action->setState(SURF_ACTION_DONE); + action->heapRemove(p_actionHeap); //FIXME: strange call since action was already popped + } +#ifdef HAVE_TRACING + if (TRACE_is_enabled()) { + //defining the last timestamp that we can safely dump to trace file + //without losing the event ascending order (considering all CPU's) + double smaller = -1; + xbt_swag_foreach(_action, p_runningActionSet) { - action = dynamic_cast(static_cast(_action)); ++ action = dynamic_cast(static_cast(_action)); + if (smaller < 0) { + smaller = action->m_lastUpdate; + continue; + } + if (action->m_lastUpdate < smaller) { + smaller = action->m_lastUpdate; + } + } + if (smaller > 0) { + TRACE_last_timestamp_to_dump = smaller; + } + } +#endif + return; +} + +void CpuModel::updateActionsStateFull(double now, double delta) +{ + void *_action, *_next_action; - ActionLmmPtr action = NULL; - ActionLmmPtr next_action = NULL; ++ CpuActionLmmPtr action = NULL; + xbt_swag_t running_actions = p_runningActionSet; + + xbt_swag_foreach_safe(_action, _next_action, running_actions) { - action = dynamic_cast(static_cast(_action)); ++ action = dynamic_cast(static_cast(_action)); +#ifdef HAVE_TRACING + if (TRACE_is_enabled()) { + CpuPtr x = (CpuPtr) lmm_constraint_id(lmm_get_cnst_from_var + (p_maxminSystem, action->p_variable, 0)); + + TRACE_surf_host_set_utilization(x->m_name, + action->p_category, + lmm_variable_getvalue(action->p_variable), + now - delta, + delta); + TRACE_last_timestamp_to_dump = now - delta; + } +#endif + + double_update(&(action->m_remains), + lmm_variable_getvalue(action->p_variable) * delta); + + + if (action->m_maxDuration != NO_MAX_DURATION) + double_update(&(action->m_maxDuration), delta); + + + if ((action->m_remains <= 0) && + (lmm_get_variable_weight(action->p_variable) > 0)) { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + + } else if ((action->m_maxDuration != NO_MAX_DURATION) && + (action->m_maxDuration <= 0)) { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + } ++ action->updateEnergy(); + } + + return; +} + +/************ + * Resource * + ************/ + +double Cpu::getSpeed(double load) +{ + return load * m_powerPeak; +} + +double Cpu::getAvailableSpeed() +{ +/* number between 0 and 1 */ + return m_powerScale; +} + +int Cpu::getCore() +{ + return m_core; +} + +/********** + * Action * + **********/ + +void CpuActionLmm::updateRemainingLazy(double now) +{ + double delta = 0.0; + + xbt_assert(p_stateSet == p_model->p_runningActionSet, + "You're updating an action that is not running."); + + /* bogus priority, skip it */ + xbt_assert(m_priority > 0, + "You're updating an action that seems suspended."); + + delta = now - m_lastUpdate; + + if (m_remains > 0) { - XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate); ++ XBT_CDEBUG(surf_kernel, "Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate); + double_update(&(m_remains), m_lastValue * delta); + +#ifdef HAVE_TRACING + if (TRACE_is_enabled()) { + CpuPtr cpu = (CpuPtr) lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)); + TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate); + } +#endif - XBT_DEBUG("Updating action(%p): remains is now %lf", this, m_remains); ++ XBT_CDEBUG(surf_kernel, "Updating action(%p): remains is now %lf", this, m_remains); + } + + m_lastUpdate = now; + m_lastValue = lmm_variable_getvalue(p_variable); +} diff --cc src/surf/cpu.hpp index 5c699826a3,0000000000..b7c5e78d03 mode 100644,000000..100644 --- a/src/surf/cpu.hpp +++ b/src/surf/cpu.hpp @@@ -1,85 -1,0 +1,93 @@@ +#include "surf.hpp" + +#ifndef SURF_MODEL_CPU_H_ +#define SURF_MODEL_CPU_H_ + +/*********** + * Classes * + ***********/ +class CpuModel; +typedef CpuModel *CpuModelPtr; + +class Cpu; +typedef Cpu *CpuPtr; + +class CpuLmm; +typedef CpuLmm *CpuLmmPtr; + +class CpuAction; +typedef CpuAction *CpuActionPtr; + +class CpuActionLmm; +typedef CpuActionLmm *CpuActionLmmPtr; + +/********* + * Model * + *********/ +class CpuModel : public Model { +public: + CpuModel(string name) : Model(name) {}; + CpuPtr createResource(string name); + void updateActionsStateLazy(double now, double delta); + void updateActionsStateFull(double now, double delta); + + virtual void addTraces() =0; +}; + +/************ + * Resource * + ************/ +class Cpu : virtual public Resource { +public: + Cpu(){}; + Cpu(CpuModelPtr model, const char* name, xbt_dict_t properties) : Resource(model, name, properties) {}; + virtual ActionPtr execute(double size)=0; + virtual ActionPtr sleep(double duration)=0; + virtual int getCore(); + virtual double getSpeed(double load); + virtual double getAvailableSpeed(); ++ ++ virtual double getCurrentPowerPeak()=0; ++ virtual double getPowerPeakAt(int pstate_index)=0; ++ virtual int getNbPstates()=0; ++ virtual void setPowerPeakAt(int pstate_index)=0; ++ virtual double getConsumedEnergy()=0; ++ + void addTraces(void); + double m_powerPeak; /*< CPU power peak */ + double m_powerScale; /*< Percentage of CPU disponible */ +protected: + int m_core; + + //virtual boost::shared_ptr execute(double size) = 0; + //virtual boost::shared_ptr sleep(double duration) = 0; +}; + +class CpuLmm : public ResourceLmm, public Cpu { +public: + CpuLmm(){}; + CpuLmm(CpuModelPtr model, const char* name, xbt_dict_t properties) : ResourceLmm(), Cpu(model, name, properties) {}; + +}; + +/********** + * Action * + **********/ +class CpuAction : virtual public Action { +public: + CpuAction(){}; + CpuAction(ModelPtr model, double cost, bool failed) + : Action(model, cost, failed) {}; +}; + +class CpuActionLmm : public ActionLmm, public CpuAction { +public: + CpuActionLmm(){}; + CpuActionLmm(ModelPtr model, double cost, bool failed) + : Action(model, cost, failed), ActionLmm(model, cost, failed), CpuAction(model, cost, failed) {}; + void updateRemainingLazy(double now); ++ virtual void updateEnergy()=0; +}; + + +#endif /* SURF_MODEL_CPU_H_ */ diff --cc src/surf/cpu_cas01.cpp index 6b5f1b8fd9,0000000000..61e1e9ee39 mode 100644,000000..100644 --- a/src/surf/cpu_cas01.cpp +++ b/src/surf/cpu_cas01.cpp @@@ -1,337 -1,0 +1,505 @@@ +/* Copyright (c) 2009-2011. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "cpu_cas01.hpp" +#include "cpu_ti.hpp" +#include "surf.hpp" +#include "maxmin_private.h" +#include "simgrid/sg_config.h" + +extern "C" { - XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_cas, surf, ++XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_cas, surf_cpu, + "Logging specific to the SURF CPU IMPROVED module"); +} + +static xbt_swag_t + cpu_running_action_set_that_does_not_need_being_checked = NULL; + +/************* + * CallBacks * + *************/ + +static void parse_cpu_init(sg_platf_host_cbarg_t host){ + ((CpuCas01ModelPtr)surf_cpu_model)->parseInit(host); +} + +static void cpu_add_traces_cpu(){ + surf_cpu_model->addTraces(); +} + +static void cpu_define_callbacks() +{ + sg_platf_host_add_cb(parse_cpu_init); + sg_platf_postparse_add_cb(cpu_add_traces_cpu); +} + +/********* + * Model * + *********/ +void surf_cpu_model_init_Cas01() +{ + char *optim = xbt_cfg_get_string(_sg_cfg_set, "cpu/optim"); + + if (surf_cpu_model) + return; + + if (!strcmp(optim, "TI")) { + surf_cpu_model_init_ti(); + return; + } + + surf_cpu_model = new CpuCas01Model(); + cpu_define_callbacks(); + ModelPtr model = static_cast(surf_cpu_model); + xbt_dynar_push(model_list, &model); +} + +CpuCas01Model::CpuCas01Model() : CpuModel("cpu") +{ + ActionPtr action; + ActionLmmPtr actionlmm; + + char *optim = xbt_cfg_get_string(_sg_cfg_set, "cpu/optim"); + int select = xbt_cfg_get_boolean(_sg_cfg_set, "cpu/maxmin_selective_update"); + + if (!strcmp(optim, "Full")) { + p_updateMechanism = UM_FULL; + m_selectiveUpdate = select; + } else if (!strcmp(optim, "Lazy")) { + p_updateMechanism = UM_LAZY; + m_selectiveUpdate = 1; + xbt_assert((select == 1) + || + (xbt_cfg_is_default_value + (_sg_cfg_set, "cpu/maxmin_selective_update")), + "Disabling selective update while using the lazy update mechanism is dumb!"); + } else { + xbt_die("Unsupported optimization (%s) for this model", optim); + } + + cpu_running_action_set_that_does_not_need_being_checked = + xbt_swag_new(xbt_swag_offset(*action, p_stateHookup)); + + if (p_updateMechanism == UM_LAZY) { + shareResources = &CpuCas01Model::shareResourcesLazy; + updateActionsState = &CpuCas01Model::updateActionsStateLazy; + + } else if (p_updateMechanism == UM_FULL) { + shareResources = &CpuCas01Model::shareResourcesFull; + updateActionsState = &CpuCas01Model::updateActionsStateFull; + } else + xbt_die("Invalid cpu update mechanism!"); + + if (!p_maxminSystem) { + p_maxminSystem = lmm_system_new(m_selectiveUpdate); + } + + if (p_updateMechanism == UM_LAZY) { + p_actionHeap = xbt_heap_new(8, NULL); + xbt_heap_set_update_callback(p_actionHeap, surf_action_lmm_update_index_heap); + p_modifiedSet = xbt_swag_new(xbt_swag_offset(*actionlmm, p_actionListHookup)); + p_maxminSystem->keep_track = p_modifiedSet; + } +} + +CpuCas01Model::~CpuCas01Model() +{ + lmm_system_free(p_maxminSystem); + p_maxminSystem = NULL; + + if (p_actionHeap) + xbt_heap_free(p_actionHeap); + xbt_swag_free(p_modifiedSet); + + surf_cpu_model = NULL; + + xbt_swag_free(cpu_running_action_set_that_does_not_need_being_checked); + cpu_running_action_set_that_does_not_need_being_checked = NULL; +} + +void CpuCas01Model::parseInit(sg_platf_host_cbarg_t host) +{ + createResource(host->id, + host->power_peak, ++ host->pstate, + host->power_scale, + host->power_trace, + host->core_amount, + host->initial_state, + host->state_trace, + host->properties); +} + - CpuCas01LmmPtr CpuCas01Model::createResource(const char *name, double power_peak, double power_scale, ++CpuCas01LmmPtr CpuCas01Model::createResource(const char *name, xbt_dynar_t power_peak, ++ int pstate, double power_scale, + tmgr_trace_t power_trace, int core, + e_surf_resource_state_t state_initial, + tmgr_trace_t state_trace, + xbt_dict_t cpu_properties) +{ + CpuPtr cpu = NULL; + xbt_assert(!surf_cpu_resource_priv(surf_cpu_resource_by_name(name)), + "Host '%s' declared several times in the platform file", + name); + xbt_assert(power_peak > 0, "Power has to be >0"); + xbt_assert(core > 0, "Invalid number of cores %d", core); + - cpu = new CpuCas01Lmm(this, name, power_peak, power_scale, power_trace, core, state_initial, state_trace, cpu_properties); ++ cpu = new CpuCas01Lmm(this, name, power_peak, pstate, power_scale, power_trace, core, state_initial, state_trace, cpu_properties); + xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, static_cast(cpu)); + + return (CpuCas01LmmPtr) xbt_lib_get_elm_or_null(host_lib, name); +} + +double CpuCas01Model::shareResourcesFull(double now) +{ + return Model::shareResourcesMaxMin(p_runningActionSet, + p_maxminSystem, lmm_solve); +} + +void CpuCas01Model::addTraces() +{ + xbt_dict_cursor_t cursor = NULL; + char *trace_name, *elm; + static int called = 0; + if (called) + return; + called = 1; + + /* connect all traces relative to hosts */ + xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + CpuCas01LmmPtr host = static_cast(surf_cpu_resource_priv(surf_cpu_resource_by_name(elm))); + + xbt_assert(host, "Host %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + host->p_stateEvent = + tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(host)); + } + + xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + CpuCas01LmmPtr host = dynamic_cast(static_cast(surf_cpu_resource_priv(surf_cpu_resource_by_name(elm)))); + + xbt_assert(host, "Host %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + host->p_powerEvent = + tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(host)); + } +} + +/************ + * Resource * + ************/ - CpuCas01Lmm::CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, double powerPeak, - double powerScale, tmgr_trace_t powerTrace, int core, ++CpuCas01Lmm::CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, xbt_dynar_t powerPeak, ++ int pstate, double powerScale, tmgr_trace_t powerTrace, int core, + e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace, + xbt_dict_t properties) : + CpuLmm(model, name, properties), Resource(model, name, properties) { - m_powerPeak = powerPeak; ++ m_powerPeak = xbt_dynar_get_as(powerPeak, pstate, double); ++ p_powerPeakList = powerPeak; ++ m_pstate = pstate; ++ ++ p_energy = xbt_new(s_energy_cpu_cas01_t, 1); ++ p_energy->total_energy = 0; ++ p_energy->power_range_watts_list = getWattsRangeList(); ++ p_energy->last_updated = surf_get_clock(); ++ ++ XBT_DEBUG("CPU create: peak=%f, pstate=%d", m_powerPeak, m_pstate); ++ + m_powerScale = powerScale; + m_core = core; + p_stateCurrent = stateInitial; + if (powerTrace) + p_powerEvent = tmgr_history_add_trace(history, powerTrace, 0.0, 0, static_cast(this)); + + if (stateTrace) + p_stateEvent = tmgr_history_add_trace(history, stateTrace, 0.0, 0, static_cast(this)); + + p_constraint = lmm_constraint_new(p_model->p_maxminSystem, this, m_core * m_powerScale * m_powerPeak); +} + ++CpuCas01Lmm::~CpuCas01Lmm(){ ++ unsigned int iter; ++ xbt_dynar_t power_tuple = NULL; ++ xbt_dynar_foreach(p_energy->power_range_watts_list, iter, power_tuple) ++ xbt_dynar_free(&power_tuple); ++ xbt_dynar_free(&p_energy->power_range_watts_list); ++ xbt_dynar_free(&p_powerPeakList); ++ xbt_free(p_energy); ++ return; ++} ++ +bool CpuCas01Lmm::isUsed() +{ + return lmm_constraint_used(p_model->p_maxminSystem, p_constraint); +} + +void CpuCas01Lmm::updateState(tmgr_trace_event_t event_type, double value, double date) +{ + lmm_variable_t var = NULL; + lmm_element_t elem = NULL; + - surf_watched_hosts(); - + if (event_type == p_powerEvent) { + m_powerScale = value; + lmm_update_constraint_bound(surf_cpu_model->p_maxminSystem, p_constraint, + m_core * m_powerScale * + m_powerPeak); +#ifdef HAVE_TRACING + TRACE_surf_host_set_power(date, m_name, + m_core * m_powerScale * + m_powerPeak); +#endif + while ((var = lmm_get_var_from_cnst + (surf_cpu_model->p_maxminSystem, p_constraint, &elem))) { + CpuCas01ActionLmmPtr action = static_cast(static_cast(lmm_variable_id(var))); + + lmm_update_variable_bound(surf_cpu_model->p_maxminSystem, + action->p_variable, + m_powerScale * m_powerPeak); + } + if (tmgr_trace_event_free(event_type)) + p_powerEvent = NULL; + } else if (event_type == p_stateEvent) { - if (value > 0) ++ if (value > 0) { ++ if(p_stateCurrent == SURF_RESOURCE_OFF) ++ xbt_dynar_push_as(host_that_restart, char*, (char *)m_name); + p_stateCurrent = SURF_RESOURCE_ON; - else { ++ } else { + lmm_constraint_t cnst = p_constraint; + + p_stateCurrent = SURF_RESOURCE_OFF; + + while ((var = lmm_get_var_from_cnst(surf_cpu_model->p_maxminSystem, cnst, &elem))) { + ActionLmmPtr action = static_cast(lmm_variable_id(var)); + + if (action->getState() == SURF_ACTION_RUNNING || + action->getState() == SURF_ACTION_READY || + action->getState() == SURF_ACTION_NOT_IN_THE_SYSTEM) { + action->m_finish = date; + action->setState(SURF_ACTION_FAILED); + } + } + } + if (tmgr_trace_event_free(event_type)) + p_stateEvent = NULL; + } else { + XBT_CRITICAL("Unknown event ! \n"); + xbt_abort(); + } + + return; +} + +ActionPtr CpuCas01Lmm::execute(double size) +{ + + XBT_IN("(%s,%g)", m_name, size); + CpuCas01ActionLmmPtr action = new CpuCas01ActionLmm(surf_cpu_model, size, p_stateCurrent != SURF_RESOURCE_ON); + + action->m_suspended = 0; /* Should be useless because of the + calloc but it seems to help valgrind... */ + + action->p_variable = + lmm_variable_new(surf_cpu_model->p_maxminSystem, static_cast(action), + action->m_priority, + m_powerScale * m_powerPeak, 1); + if (surf_cpu_model->p_updateMechanism == UM_LAZY) { + action->m_indexHeap = -1; + action->m_lastUpdate = surf_get_clock(); + action->m_lastValue = 0.0; + } + lmm_expand(surf_cpu_model->p_maxminSystem, p_constraint, + action->p_variable, 1.0); + XBT_OUT(); + return action; +} + +ActionPtr CpuCas01Lmm::sleep(double duration) +{ + if (duration > 0) + duration = MAX(duration, MAXMIN_PRECISION); + + XBT_IN("(%s,%g)", m_name, duration); + CpuCas01ActionLmmPtr action = dynamic_cast(execute(1.0)); + + // FIXME: sleep variables should not consume 1.0 in lmm_expand + action->m_maxDuration = duration; + action->m_suspended = 2; + if (duration == NO_MAX_DURATION) { + /* Move to the *end* of the corresponding action set. This convention + is used to speed up update_resource_state */ + xbt_swag_remove(static_cast(action), action->p_stateSet); + action->p_stateSet = cpu_running_action_set_that_does_not_need_being_checked; + xbt_swag_insert(static_cast(action), action->p_stateSet); + } + + lmm_update_variable_weight(surf_cpu_model->p_maxminSystem, + action->p_variable, 0.0); + if (surf_cpu_model->p_updateMechanism == UM_LAZY) { // remove action from the heap + action->heapRemove(surf_cpu_model->p_actionHeap); + // this is necessary for a variable with weight 0 since such + // variables are ignored in lmm and we need to set its max_duration + // correctly at the next call to share_resources + xbt_swag_insert_at_head(static_cast(action), surf_cpu_model->p_modifiedSet); + } + + XBT_OUT(); + return action; +} + ++xbt_dynar_t CpuCas01Lmm::getWattsRangeList() ++{ ++ xbt_dynar_t power_range_list; ++ xbt_dynar_t power_tuple; ++ int i = 0, pstate_nb=0; ++ xbt_dynar_t current_power_values; ++ double min_power, max_power; ++ ++ if (m_properties == NULL) ++ return NULL; ++ ++ char* all_power_values_str = (char*)xbt_dict_get_or_null(m_properties, "power_per_state"); ++ ++ if (all_power_values_str == NULL) ++ return NULL; ++ ++ ++ power_range_list = xbt_dynar_new(sizeof(xbt_dynar_t), NULL); ++ xbt_dynar_t all_power_values = xbt_str_split(all_power_values_str, ","); ++ ++ pstate_nb = xbt_dynar_length(all_power_values); ++ for (i=0; i< pstate_nb; i++) ++ { ++ /* retrieve the power values associated with the current pstate */ ++ current_power_values = xbt_str_split(xbt_dynar_get_as(all_power_values, i, char*), ":"); ++ xbt_assert(xbt_dynar_length(current_power_values) > 1, ++ "Power properties incorrectly defined - could not retrieve min and max power values for host %s", ++ m_name); ++ ++ /* min_power corresponds to the idle power (cpu load = 0) */ ++ /* max_power is the power consumed at 100% cpu load */ ++ min_power = atof(xbt_dynar_get_as(current_power_values, 0, char*)); ++ max_power = atof(xbt_dynar_get_as(current_power_values, 1, char*)); ++ ++ power_tuple = xbt_dynar_new(sizeof(double), NULL); ++ xbt_dynar_push_as(power_tuple, double, min_power); ++ xbt_dynar_push_as(power_tuple, double, max_power); ++ ++ xbt_dynar_push_as(power_range_list, xbt_dynar_t, power_tuple); ++ xbt_dynar_free(¤t_power_values); ++ } ++ xbt_dynar_free(&all_power_values); ++ return power_range_list; ++} ++ ++/** ++ * Computes the power consumed by the host according to the current pstate and processor load ++ * ++ */ ++double CpuCas01Lmm::getCurrentWattsValue(double cpu_load) ++{ ++ xbt_dynar_t power_range_list = p_energy->power_range_watts_list; ++ ++ if (power_range_list == NULL) ++ { ++ XBT_DEBUG("No power range properties specified for host %s", m_name); ++ return 0; ++ } ++ xbt_assert(xbt_dynar_length(power_range_list) == xbt_dynar_length(p_powerPeakList), ++ "The number of power ranges in the properties does not match the number of pstates for host %s", ++ m_name); ++ ++ /* retrieve the power values associated with the current pstate */ ++ xbt_dynar_t current_power_values = xbt_dynar_get_as(power_range_list, m_pstate, xbt_dynar_t); ++ ++ /* min_power corresponds to the idle power (cpu load = 0) */ ++ /* max_power is the power consumed at 100% cpu load */ ++ double min_power = xbt_dynar_get_as(current_power_values, 0, double); ++ double max_power = xbt_dynar_get_as(current_power_values, 1, double); ++ double power_slope = max_power - min_power; ++ ++ double current_power = min_power + cpu_load * power_slope; ++ ++ XBT_DEBUG("[get_current_watts] min_power=%f, max_power=%f, slope=%f", min_power, max_power, power_slope); ++ XBT_DEBUG("[get_current_watts] Current power (watts) = %f, load = %f", current_power, cpu_load); ++ ++ return current_power; ++} ++ ++/** ++ * Updates the total energy consumed as the sum of the current energy and ++ * the energy consumed by the current action ++ */ ++void CpuCas01Lmm::updateEnergy(double cpu_load) ++{ ++ double start_time = p_energy->last_updated; ++ double finish_time = surf_get_clock(); ++ ++ XBT_DEBUG("[cpu_update_energy] action time interval=(%f-%f), current power peak=%f, current pstate=%d", ++ start_time, finish_time, m_powerPeak, m_pstate); ++ double current_energy = p_energy->total_energy; ++ double action_energy = getCurrentWattsValue(cpu_load)*(finish_time-start_time); ++ ++ p_energy->total_energy = current_energy + action_energy; ++ p_energy->last_updated = finish_time; ++ ++ XBT_DEBUG("[cpu_update_energy] old_energy_value=%f, action_energy_value=%f", current_energy, action_energy); ++} ++ ++double CpuCas01Lmm::getCurrentPowerPeak() ++{ ++ return m_powerPeak; ++} ++ ++double CpuCas01Lmm::getPowerPeakAt(int pstate_index) ++{ ++ xbt_dynar_t plist = p_powerPeakList; ++ xbt_assert((pstate_index <= xbt_dynar_length(plist)), "Invalid parameters (pstate index out of bounds)"); ++ ++ return xbt_dynar_get_as(plist, pstate_index, double); ++} ++ ++int CpuCas01Lmm::getNbPstates() ++{ ++ return xbt_dynar_length(p_powerPeakList); ++} ++ ++void CpuCas01Lmm::setPowerPeakAt(int pstate_index) ++{ ++ xbt_dynar_t plist = p_powerPeakList; ++ xbt_assert((pstate_index <= xbt_dynar_length(plist)), "Invalid parameters (pstate index out of bounds)"); ++ ++ double new_power_peak = xbt_dynar_get_as(plist, pstate_index, double); ++ m_pstate = pstate_index; ++ m_powerPeak = new_power_peak; ++} ++ ++double CpuCas01Lmm::getConsumedEnergy() ++{ ++ return p_energy->total_energy; ++} + +/********** + * Action * + **********/ + ++/** ++ * Update the CPU total energy for a finished action ++ * ++ */ ++void CpuCas01ActionLmm::updateEnergy() ++{ ++ CpuCas01LmmPtr cpu = static_cast(lmm_constraint_id(lmm_get_cnst_from_var ++ (p_model->p_maxminSystem, ++ p_variable, 0))); + ++ if(cpu->p_energy->last_updated < surf_get_clock()) { ++ double load = lmm_constraint_get_usage(cpu->p_constraint) / cpu->m_powerPeak; ++ cpu->updateEnergy(load); ++ } ++} diff --cc src/surf/cpu_cas01.hpp index 779a350e58,0000000000..5e12cc248a mode 100644,000000..100644 --- a/src/surf/cpu_cas01.hpp +++ b/src/surf/cpu_cas01.hpp @@@ -1,62 -1,0 +1,88 @@@ +#include "cpu.hpp" + +/*********** + * Classes * + ***********/ +class CpuCas01Model; +typedef CpuCas01Model *CpuCas01ModelPtr; + +class CpuCas01Lmm; +typedef CpuCas01Lmm *CpuCas01LmmPtr; + +class CpuCas01ActionLmm; +typedef CpuCas01ActionLmm *CpuCas01ActionLmmPtr; + +/********* + * Model * + *********/ +class CpuCas01Model : public CpuModel { +public: + CpuCas01Model(); + ~CpuCas01Model(); + + double (CpuCas01Model::*shareResources)(double now); + void (CpuCas01Model::*updateActionsState)(double now, double delta); + + void parseInit(sg_platf_host_cbarg_t host); - CpuCas01LmmPtr createResource(const char *name, double power_peak, double power_scale, ++ CpuCas01LmmPtr createResource(const char *name, xbt_dynar_t power_peak, int pstate, ++ double power_scale, + tmgr_trace_t power_trace, int core, + e_surf_resource_state_t state_initial, + tmgr_trace_t state_trace, + xbt_dict_t cpu_properties); + double shareResourcesFull(double now); + void addTraces(); +}; + +/************ + * Resource * + ************/ ++/* ++ * Energy-related properties for the cpu_cas01 model ++ */ ++typedef struct energy_cpu_cas01 { ++ xbt_dynar_t power_range_watts_list; /*< List of (min_power,max_power) pairs corresponding to each cpu pstate */ ++ double total_energy; /*< Total energy consumed by the host */ ++ double last_updated; /*< Timestamp of the last energy update event*/ ++} s_energy_cpu_cas01_t, *energy_cpu_cas01_t; ++ +class CpuCas01Lmm : public CpuLmm { +public: - CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, double powerPeak, - double powerScale, tmgr_trace_t powerTrace, int core, ++ CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, xbt_dynar_t power_peak, ++ int pstate, double powerScale, tmgr_trace_t powerTrace, int core, + e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace, + xbt_dict_t properties) ; ++ ~CpuCas01Lmm(); + void updateState(tmgr_trace_event_t event_type, double value, double date); + ActionPtr execute(double size); + ActionPtr sleep(double duration); + ++ xbt_dynar_t getWattsRangeList(); ++ double getCurrentWattsValue(double cpu_load); ++ void updateEnergy(double cpu_load); ++ ++ double getCurrentPowerPeak(); ++ double getPowerPeakAt(int pstate_index); ++ int getNbPstates(); ++ void setPowerPeakAt(int pstate_index); ++ double getConsumedEnergy(); ++ + bool isUsed(); + + tmgr_trace_event_t p_powerEvent; ++ ++ xbt_dynar_t p_powerPeakList; /*< List of supported CPU capacities */ ++ int m_pstate; /*< Current pstate (index in the power_peak_list)*/ ++ energy_cpu_cas01_t p_energy; /*< Structure with energy-consumption data */ +}; + +/********** + * Action * + **********/ +class CpuCas01ActionLmm: public CpuActionLmm { +public: + CpuCas01ActionLmm() {}; + CpuCas01ActionLmm(ModelPtr model, double cost, bool failed): Action(model, cost, failed), CpuActionLmm(model, cost, failed) {}; ++ void updateEnergy(); + +}; diff --cc src/surf/cpu_ti.cpp index e512106220,0000000000..545f2baf7e mode 100644,000000..100644 --- a/src/surf/cpu_ti.cpp +++ b/src/surf/cpu_ti.cpp @@@ -1,1000 -1,0 +1,1006 @@@ +#include "cpu_ti.hpp" +#include "trace_mgr_private.h" +#include "xbt/heap.h" + +#ifndef SURF_MODEL_CPUTI_H_ +#define SURF_MODEL_CPUTI_H_ + +extern "C" { - XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_ti, surf, ++XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_ti, surf_cpu, + "Logging specific to the SURF CPU TRACE INTEGRATION module"); +} + +static xbt_swag_t cpu_ti_running_action_set_that_does_not_need_being_checked; +static xbt_swag_t cpu_ti_modified_cpu; +static xbt_heap_t cpu_ti_action_heap; + +static void cpu_ti_action_update_index_heap(void *action, int i); + +/********* + * Trace * + *********/ + +CpuTiTrace::CpuTiTrace(tmgr_trace_t power_trace) +{ + s_tmgr_event_t val; + unsigned int cpt; + double integral = 0; + double time = 0; + int i = 0; + p_timePoints = (double*) xbt_malloc0(sizeof(double) * + (xbt_dynar_length(power_trace->s_list.event_list) + 1)); + p_integral = (double*) xbt_malloc0(sizeof(double) * + (xbt_dynar_length(power_trace->s_list.event_list) + 1)); + m_nbPoints = xbt_dynar_length(power_trace->s_list.event_list); + xbt_dynar_foreach(power_trace->s_list.event_list, cpt, val) { + p_timePoints[i] = time; + p_integral[i] = integral; + integral += val.delta * val.value; + time += val.delta; + i++; + } + p_timePoints[i] = time; + p_integral[i] = integral; +} + +CpuTiTrace::~CpuTiTrace() +{ + xbt_free(p_timePoints); + xbt_free(p_integral); +} + +CpuTiTgmr::~CpuTiTgmr() +{ + if (p_trace) + delete p_trace; +} + +/** +* \brief Integrate trace +* +* Wrapper around surf_cpu_integrate_trace_simple() to get +* the cyclic effect. +* +* \param trace Trace structure. +* \param a Begin of interval +* \param b End of interval +* \return the integrate value. -1 if an error occurs. +*/ +double CpuTiTgmr::integrate(double a, double b) +{ + double first_chunk; + double middle_chunk; + double last_chunk; + int a_index, b_index; + + if ((a < 0.0) || (a > b)) { + XBT_CRITICAL + ("Error, invalid integration interval [%.2f,%.2f]. You probably have a task executing with negative computation amount. Check your code.", + a, b); + xbt_abort(); + } + if (a == b) + return 0.0; + + if (m_type == TRACE_FIXED) { + return ((b - a) * m_value); + } + + if (ceil(a / m_lastTime) == a / m_lastTime) + a_index = 1 + (int) (ceil(a / m_lastTime)); + else + a_index = (int) (ceil(a / m_lastTime)); + + b_index = (int) (floor(b / m_lastTime)); + + if (a_index > b_index) { /* Same chunk */ + return p_trace->integrateSimple(a - (a_index - + 1) * m_lastTime, + b - + (b_index) * + m_lastTime); + } + + first_chunk = p_trace->integrateSimple(a - (a_index - + 1) * + m_lastTime, + m_lastTime); + middle_chunk = (b_index - a_index) * m_total; + last_chunk = p_trace->integrateSimple(0.0, + b - + (b_index) * + m_lastTime); + + XBT_DEBUG("first_chunk=%.2f middle_chunk=%.2f last_chunk=%.2f\n", + first_chunk, middle_chunk, last_chunk); + + return (first_chunk + middle_chunk + last_chunk); +} + +/** + * \brief Auxiliary function to calculate the integral between a and b. + * It simply calculates the integral at point a and b and returns the difference + * between them. + * \param trace Trace structure + * \param a Initial point + * \param b Final point + * \return Integral +*/ +double CpuTiTrace::integrateSimple(double a, double b) +{ + return integrateSimplePoint(b) - integrateSimplePoint(a); +} + +/** + * \brief Auxiliary function to calculate the integral at point a. + * \param trace Trace structure + * \param a point + * \return Integral +*/ +double CpuTiTrace::integrateSimplePoint(double a) +{ + double integral = 0; + int ind; + double a_aux = a; + ind = binarySearch(p_timePoints, a, 0, m_nbPoints - 1); + integral += p_integral[ind]; + XBT_DEBUG - ("a %lf ind %d integral %lf ind + 1 %lf ind %lf time +1 %lf time %lf", ++ ("a %f ind %d integral %f ind + 1 %f ind %f time +1 %f time %f", + a, ind, integral, p_integral[ind + 1], p_integral[ind], + p_timePoints[ind + 1], p_timePoints[ind]); + double_update(&a_aux, p_timePoints[ind]); + if (a_aux > 0) + integral += + ((p_integral[ind + 1] - + p_integral[ind]) / (p_timePoints[ind + 1] - + p_timePoints[ind])) * (a - p_timePoints[ind]); - XBT_DEBUG("Integral a %lf = %lf", a, integral); ++ XBT_DEBUG("Integral a %f = %f", a, integral); + + return integral; +} + +/** +* \brief Calculate the time needed to execute "amount" on cpu. +* +* Here, amount can span multiple trace periods +* +* \param trace CPU trace structure +* \param a Initial time +* \param amount Amount to be executed +* \return End time +*/ +double CpuTiTgmr::solve(double a, double amount) +{ + int quotient; + double reduced_b; + double reduced_amount; + double reduced_a; + double b; + +/* Fix very small negative numbers */ + if ((a < 0.0) && (a > -EPSILON)) { + a = 0.0; + } + if ((amount < 0.0) && (amount > -EPSILON)) { + amount = 0.0; + } + +/* Sanity checks */ + if ((a < 0.0) || (amount < 0.0)) { + XBT_CRITICAL + ("Error, invalid parameters [a = %.2f, amount = %.2f]. You probably have a task executing with negative computation amount. Check your code.", + a, amount); + xbt_abort(); + } + +/* At this point, a and amount are positive */ + + if (amount < EPSILON) + return a; + +/* Is the trace fixed ? */ + if (m_type == TRACE_FIXED) { + return (a + (amount / m_value)); + } + - XBT_DEBUG("amount %lf total %lf", amount, m_total); ++ XBT_DEBUG("amount %f total %f", amount, m_total); +/* Reduce the problem to one where amount <= trace_total */ + quotient = (int) (floor(amount / m_total)); + reduced_amount = (m_total) * ((amount / m_total) - + floor(amount / m_total)); + reduced_a = a - (m_lastTime) * (int) (floor(a / m_lastTime)); + - XBT_DEBUG("Quotient: %d reduced_amount: %lf reduced_a: %lf", quotient, ++ XBT_DEBUG("Quotient: %d reduced_amount: %f reduced_a: %f", quotient, + reduced_amount, reduced_a); + +/* Now solve for new_amount which is <= trace_total */ +/* + fprintf(stderr,"reduced_a = %.2f\n",reduced_a); + fprintf(stderr,"reduced_amount = %.2f\n",reduced_amount); + */ + reduced_b = solveSomewhatSimple(reduced_a, reduced_amount); + +/* Re-map to the original b and amount */ + b = (m_lastTime) * (int) (floor(a / m_lastTime)) + + (quotient * m_lastTime) + reduced_b; + return b; +} + +/** +* \brief Auxiliary function to solve integral +* +* Here, amount is <= trace->total +* and a <=trace->last_time +* +*/ +double CpuTiTgmr::solveSomewhatSimple(double a, double amount) +{ + double amount_till_end; + double b; + + XBT_DEBUG("Solve integral: [%.2f, amount=%.2f]", a, amount); + amount_till_end = integrate(a, m_lastTime); +/* + fprintf(stderr,"amount_till_end=%.2f\n",amount_till_end); + */ + + if (amount_till_end > amount) { + b = p_trace->solveSimple(a, amount); + } else { + b = m_lastTime + p_trace->solveSimple(0.0, amount - amount_till_end); + } + return b; +} + +/** + * \brief Auxiliary function to solve integral. + * It returns the date when the requested amount of flops is available + * \param trace Trace structure + * \param a Initial point + * \param amount Amount of flops + * \return The date when amount is available. +*/ +double CpuTiTrace::solveSimple(double a, double amount) +{ + double integral_a; + int ind; + double time; + integral_a = integrateSimplePoint(a); + ind = binarySearch(p_integral, integral_a + amount, 0, m_nbPoints - 1); + time = p_timePoints[ind]; + time += + (integral_a + amount - + p_integral[ind]) / ((p_integral[ind + 1] - + p_integral[ind]) / + (p_timePoints[ind + 1] - + p_timePoints[ind])); + + return time; +} + +/** +* \brief Auxiliary function to update the CPU power scale. +* +* This function uses the trace structure to return the power scale at the determined time a. +* \param trace Trace structure to search the updated power scale +* \param a Time +* \return CPU power scale +*/ +double CpuTiTgmr::getPowerScale(double a) +{ + double reduced_a; + int point; + s_tmgr_event_t val; + + reduced_a = a - floor(a / m_lastTime) * m_lastTime; + point = p_trace->binarySearch(p_trace->p_timePoints, reduced_a, 0, + p_trace->m_nbPoints - 1); + xbt_dynar_get_cpy(p_powerTrace->s_list.event_list, point, &val); + return val.value; +} + +/** +* \brief Creates a new integration trace from a tmgr_trace_t +* +* \param power_trace CPU availability trace +* \param value Percentage of CPU power available (useful to fixed tracing) +* \param spacing Initial spacing +* \return Integration trace structure +*/ +CpuTiTgmr::CpuTiTgmr(tmgr_trace_t power_trace, double value) +{ + double total_time = 0.0; + s_tmgr_event_t val; + unsigned int cpt; + p_trace = 0; + +/* no availability file, fixed trace */ + if (!power_trace) { + m_type = TRACE_FIXED; + m_value = value; - XBT_DEBUG("No availabily trace. Constant value = %lf", value); ++ XBT_DEBUG("No availability trace. Constant value = %lf", value); + return; + } + + /* only one point available, fixed trace */ + if (xbt_dynar_length(power_trace->s_list.event_list) == 1) { + xbt_dynar_get_cpy(power_trace->s_list.event_list, 0, &val); + m_type = TRACE_FIXED; + m_value = val.value; + return; + } + + m_type = TRACE_DYNAMIC; + p_powerTrace = power_trace; + + /* count the total time of trace file */ + xbt_dynar_foreach(power_trace->s_list.event_list, cpt, val) { + total_time += val.delta; + } + p_trace = new CpuTiTrace(power_trace); + m_lastTime = total_time; + m_total = p_trace->integrateSimple(0, total_time); + + XBT_DEBUG("Total integral %lf, last_time %lf ", + m_total, m_lastTime); +} + +/** + * \brief Binary search in array. + * It returns the first point of the interval in which "a" is. + * \param array Array + * \param a Value to search + * \param low Low bound to search in array + * \param high Upper bound to search in array + * \return Index of point +*/ +int CpuTiTrace::binarySearch(double *array, double a, int low, int high) +{ + xbt_assert(low < high, "Wrong parameters: low (%d) should be smaller than" + " high (%d)", low, high); + + int mid; + do { + mid = low + (high - low) / 2; - XBT_DEBUG("a %lf low %d high %d mid %d value %lf", a, low, high, mid, ++ XBT_DEBUG("a %f low %d high %d mid %d value %f", a, low, high, mid, + array[mid]); + + if (array[mid] > a) + high = mid; + else + low = mid; + } + while (low < high - 1); + + return low; +} + +/************* + * CallBacks * + *************/ + +static void parse_cpu_ti_init(sg_platf_host_cbarg_t host){ + ((CpuTiModelPtr)surf_cpu_model)->parseInit(host); +} + +static void add_traces_cpu_ti(){ + surf_cpu_model->addTraces(); +} + +static void cpu_ti_define_callbacks() +{ + sg_platf_host_add_cb(parse_cpu_ti_init); + sg_platf_postparse_add_cb(add_traces_cpu_ti); +} + +/********* + * Model * + *********/ + +void surf_cpu_model_init_ti() +{ + xbt_assert(!surf_cpu_model,"CPU model already initialized. This should not happen."); + surf_cpu_model = new CpuTiModel(); + cpu_ti_define_callbacks(); + ModelPtr model = static_cast(surf_cpu_model); + xbt_dynar_push(model_list, &model); +} + +CpuTiModel::CpuTiModel() : CpuModel("cpu_ti") +{ + xbt_assert(!surf_cpu_model,"CPU model already initialized. This should not happen."); + ActionPtr action; + CpuTi cpu; + + cpu_ti_running_action_set_that_does_not_need_being_checked = + xbt_swag_new(xbt_swag_offset(*action, p_stateHookup)); + + cpu_ti_modified_cpu = + xbt_swag_new(xbt_swag_offset(cpu, p_modifiedCpuHookup)); + + cpu_ti_action_heap = xbt_heap_new(8, NULL); + xbt_heap_set_update_callback(cpu_ti_action_heap, + cpu_ti_action_update_index_heap); +} + +CpuTiModel::~CpuTiModel() +{ + void **cpu; + xbt_lib_cursor_t cursor; + char *key; + + xbt_lib_foreach(host_lib, cursor, key, cpu){ + if(cpu[SURF_CPU_LEVEL]) + { + CpuTiPtr CPU = dynamic_cast(static_cast(cpu[SURF_CPU_LEVEL])); + xbt_swag_free(CPU->p_actionSet); + delete CPU->p_availTrace; + } + } + + surf_cpu_model = NULL; + + xbt_swag_free + (cpu_ti_running_action_set_that_does_not_need_being_checked); + xbt_swag_free(cpu_ti_modified_cpu); + cpu_ti_running_action_set_that_does_not_need_being_checked = NULL; + xbt_heap_free(cpu_ti_action_heap); +} + +void CpuTiModel::parseInit(sg_platf_host_cbarg_t host) +{ + createResource(host->id, + host->power_peak, ++ host->pstate, + host->power_scale, + host->power_trace, + host->core_amount, + host->initial_state, + host->state_trace, + host->properties); +} + +CpuTiPtr CpuTiModel::createResource(const char *name, - double powerPeak, ++ xbt_dynar_t powerPeak, ++ int pstate, + double powerScale, + tmgr_trace_t powerTrace, + int core, + e_surf_resource_state_t stateInitial, + tmgr_trace_t stateTrace, + xbt_dict_t cpuProperties) +{ + tmgr_trace_t empty_trace; + s_tmgr_event_t val; + CpuTiActionPtr cpuAction; + xbt_assert(core==1,"Multi-core not handled with this model yet"); + xbt_assert(!surf_cpu_resource_priv(surf_cpu_resource_by_name(name)), + "Host '%s' declared several times in the platform file", + name); - CpuTiPtr cpu = new CpuTi(this, name, powerPeak, powerScale, powerTrace, ++ CpuTiPtr cpu = new CpuTi(this, name, powerPeak, pstate, powerScale, powerTrace, + core, stateInitial, stateTrace, cpuProperties); + xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, static_cast(cpu)); + return (CpuTiPtr) xbt_lib_get_elm_or_null(host_lib, name); +} + +CpuTiActionPtr CpuTiModel::createAction(double cost, bool failed) +{ + return NULL;//new CpuTiAction(this, cost, failed); +} + +double CpuTiModel::shareResources(double now) +{ + void *_cpu, *_cpu_next; + double min_action_duration = -1; + +/* iterates over modified cpus to update share resources */ + xbt_swag_foreach_safe(_cpu, _cpu_next, cpu_ti_modified_cpu) { + static_cast(_cpu)->updateActionFinishDate(now); + } +/* get the min next event if heap not empty */ + if (xbt_heap_size(cpu_ti_action_heap) > 0) + min_action_duration = xbt_heap_maxkey(cpu_ti_action_heap) - now; + - XBT_DEBUG("Share resources, min next event date: %lf", min_action_duration); ++ XBT_DEBUG("Share resources, min next event date: %f", min_action_duration); + + return min_action_duration; +} + +void CpuTiModel::updateActionsState(double now, double delta) +{ + while ((xbt_heap_size(cpu_ti_action_heap) > 0) + && (xbt_heap_maxkey(cpu_ti_action_heap) <= now)) { + CpuTiActionPtr action = (CpuTiActionPtr) xbt_heap_pop(cpu_ti_action_heap); + XBT_DEBUG("Action %p: finish", action); + action->m_finish = surf_get_clock(); + /* set the remains to 0 due to precision problems when updating the remaining amount */ + action->m_remains = 0; + action->setState(SURF_ACTION_DONE); - /* update remaining amout of all actions */ ++ /* update remaining amount of all actions */ + action->p_cpu->updateRemainingAmount(surf_get_clock()); + } +} + +void CpuTiModel::addTraces() +{ + xbt_dict_cursor_t cursor = NULL; + char *trace_name, *elm; + + static int called = 0; + + if (called) + return; + called = 1; + +/* connect all traces relative to hosts */ + xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + CpuTiPtr cpu = static_cast(surf_cpu_resource_priv(surf_cpu_resource_by_name(elm))); + + xbt_assert(cpu, "Host %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + if (cpu->p_stateEvent) { + XBT_DEBUG("Trace already configured for this CPU(%s), ignoring it", + elm); + continue; + } + XBT_DEBUG("Add state trace: %s to CPU(%s)", trace_name, elm); + cpu->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(cpu)); + } + + xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + CpuTiPtr cpu = dynamic_cast(static_cast(surf_cpu_resource_priv(surf_cpu_resource_by_name(elm)))); + + xbt_assert(cpu, "Host %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + XBT_DEBUG("Add power trace: %s to CPU(%s)", trace_name, elm); + if (cpu->p_availTrace) + delete cpu->p_availTrace; + + cpu->p_availTrace = new CpuTiTgmr(trace, cpu->m_powerScale); + + /* add a fake trace event if periodicity == 0 */ + if (trace && xbt_dynar_length(trace->s_list.event_list) > 1) { + s_tmgr_event_t val; + xbt_dynar_get_cpy(trace->s_list.event_list, + xbt_dynar_length(trace->s_list.event_list) - 1, &val); + if (val.delta == 0) { + tmgr_trace_t empty_trace; + empty_trace = tmgr_empty_trace_new(); + cpu->p_powerEvent = + tmgr_history_add_trace(history, empty_trace, + cpu->p_availTrace->m_lastTime, 0, static_cast(cpu)); + } + } + } +} + +/************ + * Resource * + ************/ - CpuTi::CpuTi(CpuTiModelPtr model, const char *name, double powerPeak, - double powerScale, tmgr_trace_t powerTrace, int core, ++CpuTi::CpuTi(CpuTiModelPtr model, const char *name, xbt_dynar_t powerPeak, ++ int pstate, double powerScale, tmgr_trace_t powerTrace, int core, + e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace, + xbt_dict_t properties) : + Resource(model, name, properties), Cpu(model, name, properties) { + p_stateCurrent = stateInitial; - m_powerPeak = powerPeak; + m_powerScale = powerScale; + m_core = core; + tmgr_trace_t empty_trace; + s_tmgr_event_t val; + xbt_assert(core==1,"Multi-core not handled with this model yet"); + XBT_DEBUG("power scale %lf", powerScale); + p_availTrace = new CpuTiTgmr(powerTrace, powerScale); + + CpuTiActionPtr action; + p_actionSet = xbt_swag_new(xbt_swag_offset(*action, p_cpuListHookup)); + ++ xbt_dynar_get_cpy(powerPeak, 0, &m_powerPeak); ++ xbt_dynar_free(&powerPeak); /* kill memory leak */ ++ m_pstate = pstate; ++ XBT_DEBUG("CPU create: peak=%f, pstate=%d", m_powerPeak, m_pstate); ++ + p_modifiedCpuHookup.prev = 0; + p_modifiedCpuHookup.next = 0; + + if (stateTrace) + p_stateEvent = tmgr_history_add_trace(history, stateTrace, 0.0, 0, static_cast(this)); + if (powerTrace && xbt_dynar_length(powerTrace->s_list.event_list) > 1) { + // add a fake trace event if periodicity == 0 + xbt_dynar_get_cpy(powerTrace->s_list.event_list, + xbt_dynar_length(powerTrace->s_list.event_list) - 1, &val); + if (val.delta == 0) { + empty_trace = tmgr_empty_trace_new(); - p_powerEvent = ++ p_powerEvent = + tmgr_history_add_trace(history, empty_trace, + p_availTrace->m_lastTime, 0, static_cast(this)); + } + } +}; + +void CpuTi::updateState(tmgr_trace_event_t event_type, + double value, double date) +{ + void *_action; + CpuTiActionPtr action; + - surf_watched_hosts(); - + if (event_type == p_powerEvent) { + tmgr_trace_t power_trace; + CpuTiTgmrPtr trace; + s_tmgr_event_t val; + - XBT_DEBUG("Finish trace date: %lf value %lf date %lf", surf_get_clock(), ++ XBT_DEBUG("Finish trace date: %f value %lf date %f", surf_get_clock(), + value, date); + /* update remaining of actions and put in modified cpu swag */ + updateRemainingAmount(date); + xbt_swag_insert(this, cpu_ti_modified_cpu); + + power_trace = p_availTrace->p_powerTrace; + xbt_dynar_get_cpy(power_trace->s_list.event_list, + xbt_dynar_length(power_trace->s_list.event_list) - 1, &val); + /* free old trace */ + delete p_availTrace; + m_powerScale = val.value; + + trace = new CpuTiTgmr(TRACE_FIXED, val.value); - XBT_DEBUG("value %lf", val.value); ++ XBT_DEBUG("value %f", val.value); + + p_availTrace = trace; + + if (tmgr_trace_event_free(event_type)) + p_powerEvent = NULL; + + } else if (event_type == p_stateEvent) { - if (value > 0) ++ if (value > 0) { ++ if(p_stateCurrent == SURF_RESOURCE_OFF) ++ xbt_dynar_push_as(host_that_restart, char*, (char *)m_name); + p_stateCurrent = SURF_RESOURCE_ON; - else { ++ } else { + p_stateCurrent = SURF_RESOURCE_OFF; + + /* put all action running on cpu to failed */ + xbt_swag_foreach(_action, p_actionSet) { + action = static_cast(_action); + if (action->getState() == SURF_ACTION_RUNNING + || action->getState() == SURF_ACTION_READY + || action->getState() == SURF_ACTION_NOT_IN_THE_SYSTEM) { + action->m_finish = date; + action->setState(SURF_ACTION_FAILED); + if (action->m_indexHeap >= 0) { + CpuTiActionPtr heap_act = (CpuTiActionPtr) + xbt_heap_remove(cpu_ti_action_heap, action->m_indexHeap); + if (heap_act != action) + DIE_IMPOSSIBLE; + } + } + } + } + if (tmgr_trace_event_free(event_type)) + p_stateEvent = NULL; + } else { + XBT_CRITICAL("Unknown event ! \n"); + xbt_abort(); + } + + return; +} + +void CpuTi::updateActionFinishDate(double now) +{ + void *_action; + CpuTiActionPtr action; + double sum_priority = 0.0, total_area, min_finish = -1; + +/* update remaning amount of actions */ +updateRemainingAmount(now); + + xbt_swag_foreach(_action, p_actionSet) { + action = static_cast(_action); + /* action not running, skip it */ + if (action->p_stateSet != + surf_cpu_model->p_runningActionSet) + continue; + + /* bogus priority, skip it */ + if (action->m_priority <= 0) + continue; + + /* action suspended, skip it */ + if (action->m_suspended != 0) + continue; + + sum_priority += 1.0 / action->m_priority; + } + m_sumPriority = sum_priority; + + xbt_swag_foreach(_action, p_actionSet) { + action = static_cast(_action); + min_finish = -1; + /* action not running, skip it */ + if (action->p_stateSet != + surf_cpu_model->p_runningActionSet) + continue; + + /* verify if the action is really running on cpu */ + if (action->m_suspended == 0 && action->m_priority > 0) { + /* total area needed to finish the action. Used in trace integration */ + total_area = + (action->m_remains) * sum_priority * + action->m_priority; + + total_area /= m_powerPeak; + + action->m_finish = p_availTrace->solve(now, total_area); + /* verify which event will happen before (max_duration or finish time) */ + if (action->m_maxDuration != NO_MAX_DURATION && + action->m_start + action->m_maxDuration < action->m_finish) + min_finish = action->m_start + action->m_maxDuration; + else + min_finish = action->m_finish; + } else { + /* put the max duration time on heap */ + if (action->m_maxDuration != NO_MAX_DURATION) + min_finish = action->m_start + action->m_maxDuration; + } + /* add in action heap */ + XBT_DEBUG("action(%p) index %d", action, action->m_indexHeap); + if (action->m_indexHeap >= 0) { + CpuTiActionPtr heap_act = (CpuTiActionPtr) + xbt_heap_remove(cpu_ti_action_heap, action->m_indexHeap); + if (heap_act != action) + DIE_IMPOSSIBLE; + } + if (min_finish != NO_MAX_DURATION) + xbt_heap_push(cpu_ti_action_heap, action, min_finish); + + XBT_DEBUG - ("Update finish time: Cpu(%s) Action: %p, Start Time: %lf Finish Time: %lf Max duration %lf", ++ ("Update finish time: Cpu(%s) Action: %p, Start Time: %f Finish Time: %f Max duration %f", + m_name, action, action->m_start, + action->m_finish, + action->m_maxDuration); + } +/* remove from modified cpu */ + xbt_swag_remove(this, cpu_ti_modified_cpu); +} + +bool CpuTi::isUsed() +{ + return xbt_swag_size(p_actionSet); +} + + + +double CpuTi::getAvailableSpeed() +{ + m_powerScale = p_availTrace->getPowerScale(surf_get_clock()); + return Cpu::getAvailableSpeed(); +} + +/** +* \brief Update the remaining amount of actions +* +* \param now Current time +*/ +void CpuTi::updateRemainingAmount(double now) +{ + double area_total; + void* _action; + CpuTiActionPtr action; + + /* already updated */ + if (m_lastUpdate >= now) + return; + +/* calcule the surface */ + area_total = p_availTrace->integrate(m_lastUpdate, now) * m_powerPeak; - XBT_DEBUG("Flops total: %lf, Last update %lf", area_total, ++ XBT_DEBUG("Flops total: %f, Last update %f", area_total, + m_lastUpdate); + + xbt_swag_foreach(_action, p_actionSet) { + action = static_cast(_action); + /* action not running, skip it */ + if (action->p_stateSet != + getModel()->p_runningActionSet) + continue; + + /* bogus priority, skip it */ + if (action->m_priority <= 0) + continue; + + /* action suspended, skip it */ + if (action->m_suspended != 0) + continue; + + /* action don't need update */ + if (action->m_start >= now) + continue; + + /* skip action that are finishing now */ + if (action->m_finish >= 0 + && action->m_finish <= now) + continue; + + /* update remaining */ + double_update(&(action->m_remains), + area_total / (m_sumPriority * + action->m_priority)); - XBT_DEBUG("Update remaining action(%p) remaining %lf", action, ++ XBT_DEBUG("Update remaining action(%p) remaining %f", action, + action->m_remains); + } + m_lastUpdate = now; +} + +CpuActionPtr CpuTi::execute(double size) +{ + return _execute(size); +} + +CpuTiActionPtr CpuTi::_execute(double size) +{ + XBT_IN("(%s,%g)", m_name, size); + CpuTiActionPtr action = new CpuTiAction(static_cast(p_model), size, p_stateCurrent != SURF_RESOURCE_ON); + + action->p_cpu = this; + action->m_indexHeap = -1; + + xbt_swag_insert(this, cpu_ti_modified_cpu); + + xbt_swag_insert(action, p_actionSet); + + action->m_suspended = 0; /* Should be useless because of the + » calloc but it seems to help valgrind... */ + + XBT_OUT(); + return action; +} + + +CpuActionPtr CpuTi::sleep(double duration) +{ + if (duration > 0) + duration = MAX(duration, MAXMIN_PRECISION); + + XBT_IN("(%s,%g)", m_name, duration); + CpuTiActionPtr action = _execute(1.0); + action->m_maxDuration = duration; + action->m_suspended = 2; + if (duration == NO_MAX_DURATION) { + /* Move to the *end* of the corresponding action set. This convention + is used to speed up update_resource_state */ + xbt_swag_remove(static_cast(action), action->p_stateSet); + action->p_stateSet = cpu_ti_running_action_set_that_does_not_need_being_checked; + xbt_swag_insert(static_cast(action), action->p_stateSet); + } + XBT_OUT(); + return action; +} + +void CpuTi::printCpuTiModel() +{ + std::cout << getModel()->getName() << "<updateIndexHeap(i); +} +void CpuTiAction::updateIndexHeap(int i) +{ + m_indexHeap = i; +} + +void CpuTiAction::setState(e_surf_action_state_t state) +{ + Action::setState(state); + xbt_swag_insert(p_cpu, cpu_ti_modified_cpu); +} + +int CpuTiAction::unref() +{ + m_refcount--; + if (!m_refcount) { + xbt_swag_remove(static_cast(this), p_stateSet); + /* remove from action_set */ + xbt_swag_remove(this, p_cpu->p_actionSet); + /* remove from heap */ + xbt_heap_remove(cpu_ti_action_heap, this->m_indexHeap); + xbt_swag_insert(p_cpu, cpu_ti_modified_cpu); + delete this; + return 1; + } + return 0; +} + +void CpuTiAction::cancel() +{ + this->setState(SURF_ACTION_FAILED); + xbt_heap_remove(cpu_ti_action_heap, this->m_indexHeap); + xbt_swag_insert(p_cpu, cpu_ti_modified_cpu); + return; +} + +void CpuTiAction::recycle() +{ + DIE_IMPOSSIBLE; +} + +void CpuTiAction::suspend() +{ + XBT_IN("(%p)", this); + if (m_suspended != 2) { + m_suspended = 1; + xbt_heap_remove(cpu_ti_action_heap, m_indexHeap); + xbt_swag_insert(p_cpu, cpu_ti_modified_cpu); + } + XBT_OUT(); +} + +void CpuTiAction::resume() +{ + XBT_IN("(%p)", this); + if (m_suspended != 2) { + m_suspended = 0; + xbt_swag_insert(p_cpu, cpu_ti_modified_cpu); + } + XBT_OUT(); +} + +bool CpuTiAction::isSuspended() +{ + return m_suspended == 1; +} + +void CpuTiAction::setMaxDuration(double duration) +{ + double min_finish; + + XBT_IN("(%p,%g)", this, duration); + + m_maxDuration = duration; + + if (duration >= 0) + min_finish = (m_start + m_maxDuration) < m_finish ? + (m_start + m_maxDuration) : m_finish; + else + min_finish = m_finish; + +/* add in action heap */ + if (m_indexHeap >= 0) { + CpuTiActionPtr heap_act = (CpuTiActionPtr) + xbt_heap_remove(cpu_ti_action_heap, m_indexHeap); + if (heap_act != this) + DIE_IMPOSSIBLE; + } + xbt_heap_push(cpu_ti_action_heap, this, min_finish); + + XBT_OUT(); +} + +void CpuTiAction::setPriority(double priority) +{ + XBT_IN("(%p,%g)", this, priority); + m_priority = priority; + xbt_swag_insert(p_cpu, cpu_ti_modified_cpu); + XBT_OUT(); +} + +double CpuTiAction::getRemains() +{ + XBT_IN("(%p)", this); + p_cpu->updateRemainingAmount(surf_get_clock()); + XBT_OUT(); + return m_remains; +} + +static void check() { + CpuTiActionPtr cupAction = new CpuTiAction(NULL, 0, true); +} + +#endif /* SURF_MODEL_CPUTI_H_ */ + diff --cc src/surf/cpu_ti.hpp index 6d52dd9f67,0000000000..cccac330f7 mode 100644,000000..100644 --- a/src/surf/cpu_ti.hpp +++ b/src/surf/cpu_ti.hpp @@@ -1,163 -1,0 +1,178 @@@ +#include "cpu.hpp" +#include "trace_mgr_private.h" +#include "surf/surf_routing.h" + +/* Epsilon */ +#define EPSILON 0.000000001 + +/*********** + * Classes * + ***********/ +class CpuTiTrace; +typedef CpuTiTrace *CpuTiTracePtr; + +class CpuTiTgmr; +typedef CpuTiTgmr *CpuTiTgmrPtr; + +class CpuTiModel; +typedef CpuTiModel *CpuTiModelPtr; + +class CpuTi; +typedef CpuTi *CpuTiPtr; + +class CpuTiAction; +typedef CpuTiAction *CpuTiActionPtr; + +/********* + * Trace * + *********/ +class CpuTiTrace { +public: + CpuTiTrace(tmgr_trace_t powerTrace); + ~CpuTiTrace(); + + double integrateSimple(double a, double b); + double integrateSimplePoint(double a); + double solveSimple(double a, double amount); + + double *p_timePoints; + double *p_integral; + int m_nbPoints; + int binarySearch(double *array, double a, int low, int high); + +private: +}; + +enum trace_type { + + TRACE_FIXED, /*< Trace fixed, no availability file */ + TRACE_DYNAMIC /*< Dynamic, availability file disponible */ +}; + +class CpuTiTgmr { +public: + CpuTiTgmr(trace_type type, double value): m_type(type), m_value(value){}; + CpuTiTgmr(tmgr_trace_t power_trace, double value); + ~CpuTiTgmr(); + + double integrate(double a, double b); + double solve(double a, double amount); + double solveSomewhatSimple(double a, double amount); + double getPowerScale(double a); + + trace_type m_type; + double m_value; /*< Percentage of cpu power disponible. Value fixed between 0 and 1 */ + + /* Dynamic */ + double m_lastTime; /*< Integral interval last point (discret time) */ + double m_total; /*< Integral total between 0 and last_pointn */ + + CpuTiTracePtr p_trace; + tmgr_trace_t p_powerTrace; +}; + + +/********* + * Model * + *********/ +class CpuTiModel : public CpuModel { +public: + CpuTiModel(); + ~CpuTiModel(); + + void parseInit(sg_platf_host_cbarg_t host); - CpuTiPtr createResource(const char *name, double power_peak, double power_scale, ++ CpuTiPtr createResource(const char *name, xbt_dynar_t powerPeak, ++ int pstate, double power_scale, + tmgr_trace_t power_trace, int core, + e_surf_resource_state_t state_initial, + tmgr_trace_t state_trace, + xbt_dict_t cpu_properties); + CpuTiActionPtr createAction(double cost, bool failed); + double shareResources(double now); + void updateActionsState(double now, double delta); + void addTraces(); + +protected: + void NotifyResourceTurnedOn(ResourcePtr r){}; + void NotifyResourceTurnedOff(ResourcePtr r){}; + + void NotifyActionCancel(ActionPtr a){}; + void NotifyActionResume(ActionPtr a){}; + void NotifyActionSuspend(ActionPtr a){}; +}; + +/************ + * Resource * + ************/ +class CpuTi : public Cpu { +public: + CpuTi() {}; - CpuTi(CpuTiModelPtr model, const char *name, double powerPeak, - double powerScale, tmgr_trace_t powerTrace, int core, ++ CpuTi(CpuTiModelPtr model, const char *name, xbt_dynar_t powerPeak, ++ int pstate, double powerScale, tmgr_trace_t powerTrace, int core, + e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace, + xbt_dict_t properties) ; + ~CpuTi() {}; + + void updateState(tmgr_trace_event_t event_type, double value, double date); + void updateActionFinishDate(double now); + bool isUsed(); + void printCpuTiModel(); + CpuActionPtr execute(double size); + CpuTiActionPtr _execute(double size); + CpuActionPtr sleep(double duration); + double getAvailableSpeed(); + ++ xbt_dynar_t getWattsRangeList() {}; ++ double getCurrentWattsValue(double cpu_load) {}; ++ void updateEnergy(double cpu_load) {}; ++ ++ double getCurrentPowerPeak() {}; ++ double getPowerPeakAt(int pstate_index) {}; ++ int getNbPstates() {}; ++ void setPowerPeakAt(int pstate_index) {}; ++ double getConsumedEnergy() {}; ++ + CpuTiTgmrPtr p_availTrace; /*< Structure with data needed to integrate trace file */ + tmgr_trace_event_t p_stateEvent; /*< trace file with states events (ON or OFF) */ - tmgr_trace_event_t p_powerEvent; /*< trace file with availabitly events */ ++ tmgr_trace_event_t p_powerEvent; /*< trace file with availability events */ + xbt_swag_t p_actionSet; /*< set with all actions running on cpu */ - s_xbt_swag_hookup_t p_modifiedCpuHookup; /*< hookup to swag that indicacates whether share resources must be recalculated or not */ ++ s_xbt_swag_hookup_t p_modifiedCpuHookup; /*< hookup to swag that indicates whether share resources must be recalculated or not */ + double m_sumPriority; /*< the sum of actions' priority that are running on cpu */ + double m_lastUpdate; /*< last update of actions' remaining amount done */ ++ ++ int m_pstate; /*< Current pstate (index in the power_peak_list)*/ ++ double current_frequency; ++ + void updateRemainingAmount(double now); +}; + +/********** + * Action * + **********/ + +class CpuTiAction: public CpuAction { +public: + CpuTiAction() {}; + CpuTiAction(CpuTiModelPtr model, double cost, bool failed) + : Action(model, cost, failed), CpuAction(model, cost, failed) { + p_cpuListHookup.next = 0; + p_cpuListHookup.prev = 0; + }; + + void setState(e_surf_action_state_t state); + int unref(); + void cancel(); + void recycle(); + void updateIndexHeap(int i); + void suspend(); + void resume(); + bool isSuspended(); + void setMaxDuration(double duration); + void setPriority(double priority); + double getRemains(); + CpuTiPtr p_cpu; + int m_indexHeap; + s_xbt_swag_hookup_t p_cpuListHookup; + int m_suspended; +private: +}; diff --cc src/surf/network.cpp index 23a4230ba9,0000000000..e8e886e3ee mode 100644,000000..100644 --- a/src/surf/network.cpp +++ b/src/surf/network.cpp @@@ -1,698 -1,0 +1,698 @@@ +#include "network.hpp" +#include "maxmin_private.h" +#include "simgrid/sg_config.h" + +extern "C" { +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf, + "Logging specific to the SURF network module"); +} + +NetworkCm02ModelPtr surf_network_model = NULL; + +double sg_sender_gap = 0.0; +double sg_latency_factor = 1.0; /* default value; can be set by model or from command line */ +double sg_bandwidth_factor = 1.0; /* default value; can be set by model or from command line */ +double sg_weight_S_parameter = 0.0; /* default value; can be set by model or from command line */ + +double sg_tcp_gamma = 0.0; +int sg_network_crosstraffic = 0; + +/************* + * CallBacks * + *************/ + +static void net_parse_link_init(sg_platf_link_cbarg_t link){ + if (link->policy == SURF_LINK_FULLDUPLEX) { + char *link_id; + link_id = bprintf("%s_UP", link->id); + surf_network_model->createResource(link_id, + link->bandwidth, + link->bandwidth_trace, + link->latency, + link->latency_trace, + link->state, + link->state_trace, link->policy, link->properties); + xbt_free(link_id); + link_id = bprintf("%s_DOWN", link->id); + surf_network_model->createResource(link_id, + link->bandwidth, + link->bandwidth_trace, + link->latency, + link->latency_trace, + link->state, + link->state_trace, link->policy, link->properties); + xbt_free(link_id); + } else { + surf_network_model->createResource(link->id, + link->bandwidth, + link->bandwidth_trace, + link->latency, + link->latency_trace, + link->state, + link->state_trace, link->policy, link->properties); + } +} + +static void net_add_traces(void){ + xbt_dict_cursor_t cursor = NULL; + char *trace_name, *elm; + + static int called = 0; + if (called) + return; + called = 1; + + /* connect all traces relative to network */ + xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + NetworkCm02LinkLmmPtr link = dynamic_cast( + static_cast( + xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL))); + + xbt_assert(link, "Cannot connect trace %s to link %s: link undefined", + trace_name, elm); + xbt_assert(trace, + "Cannot connect trace %s to link %s: trace undefined", + trace_name, elm); + + link->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(link)); + } + + xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + NetworkCm02LinkLmmPtr link = dynamic_cast( + static_cast( + xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL))); + + xbt_assert(link, "Cannot connect trace %s to link %s: link undefined", + trace_name, elm); + xbt_assert(trace, + "Cannot connect trace %s to link %s: trace undefined", + trace_name, elm); + + link->p_power.event = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(link)); + } + + xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + NetworkCm02LinkLmmPtr link = dynamic_cast( + static_cast( + xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL))); + + xbt_assert(link, "Cannot connect trace %s to link %s: link undefined", + trace_name, elm); + xbt_assert(trace, + "Cannot connect trace %s to link %s: trace undefined", + trace_name, elm); + + link->p_latEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(link)); + } +} + +void net_define_callbacks(void) +{ + /* Figuring out the network links */ + sg_platf_link_add_cb(net_parse_link_init); + sg_platf_postparse_add_cb(net_add_traces); +} + +/********* + * Model * + *********/ + +/************************************************************************/ +/* New model based on optimizations discussed during Pedro Velho's thesis*/ +/************************************************************************/ +/* @techreport{VELHO:2011:HAL-00646896:1, */ +/* url = {http://hal.inria.fr/hal-00646896/en/}, */ +/* title = {{Flow-level network models: have we reached the limits?}}, */ +/* author = {Velho, Pedro and Schnorr, Lucas and Casanova, Henri and Legrand, Arnaud}, */ +/* type = {Rapport de recherche}, */ +/* institution = {INRIA}, */ +/* number = {RR-7821}, */ +/* year = {2011}, */ +/* month = Nov, */ +/* pdf = {http://hal.inria.fr/hal-00646896/PDF/rr-validity.pdf}, */ +/* } */ +void surf_network_model_init_LegrandVelho(void) +{ + if (surf_network_model) + return; + + surf_network_model = new NetworkCm02Model(); + net_define_callbacks(); + ModelPtr model = static_cast(surf_network_model); + xbt_dynar_push(model_list, &model); + + xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", + 13.01); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor", + 0.97); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 20537); +} + +/***************************************************************************/ +/* The nice TCP sharing model designed by Loris Marchal and Henri Casanova */ +/***************************************************************************/ +/* @TechReport{ rr-lip2002-40, */ +/* author = {Henri Casanova and Loris Marchal}, */ +/* institution = {LIP}, */ +/* title = {A Network Model for Simulation of Grid Application}, */ +/* number = {2002-40}, */ +/* month = {oct}, */ +/* year = {2002} */ +/* } */ +void surf_network_model_init_CM02(void) +{ + + if (surf_network_model) + return; + + surf_network_model = new NetworkCm02Model(); + net_define_callbacks(); + ModelPtr model = static_cast(surf_network_model); + xbt_dynar_push(model_list, &model); + + xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 1.0); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor", + 1.0); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 0.0); +} + +/***************************************************************************/ +/* The models from Steven H. Low */ +/***************************************************************************/ +/* @article{Low03, */ +/* author={Steven H. Low}, */ +/* title={A Duality Model of {TCP} and Queue Management Algorithms}, */ +/* year={2003}, */ +/* journal={{IEEE/ACM} Transactions on Networking}, */ +/* volume={11}, number={4}, */ +/* } */ +void surf_network_model_init_Reno(void) +{ + if (surf_network_model) + return; + + surf_network_model = new NetworkCm02Model(); + net_define_callbacks(); + ModelPtr model = static_cast(surf_network_model); + xbt_dynar_push(model_list, &model); + lmm_set_default_protocol_function(func_reno_f, func_reno_fp, + func_reno_fpi); + surf_network_model->f_networkSolve = lagrange_solve; + + xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 10.4); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor", + 0.92); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 8775); +} + + +void surf_network_model_init_Reno2(void) +{ + if (surf_network_model) + return; + + surf_network_model = new NetworkCm02Model(); + net_define_callbacks(); + ModelPtr model = static_cast(surf_network_model); + xbt_dynar_push(model_list, &model); + lmm_set_default_protocol_function(func_reno2_f, func_reno2_fp, + func_reno2_fpi); + surf_network_model->f_networkSolve = lagrange_solve; + + xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 10.4); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor", + 0.92); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S_parameter", + 8775); +} + +void surf_network_model_init_Vegas(void) +{ + if (surf_network_model) + return; + + surf_network_model = new NetworkCm02Model(); + net_define_callbacks(); + ModelPtr model = static_cast(surf_network_model); + xbt_dynar_push(model_list, &model); + lmm_set_default_protocol_function(func_vegas_f, func_vegas_fp, + func_vegas_fpi); + surf_network_model->f_networkSolve = lagrange_solve; + + xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 10.4); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor", + 0.92); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 8775); +} + +NetworkCm02Model::NetworkCm02Model() : NetworkCm02Model("network"){ +} + +NetworkCm02Model::NetworkCm02Model(string name) : Model(name){ + ActionLmmPtr comm; + + char *optim = xbt_cfg_get_string(_sg_cfg_set, "network/optim"); + int select = + xbt_cfg_get_boolean(_sg_cfg_set, "network/maxmin_selective_update"); + + if (!strcmp(optim, "Full")) { + p_updateMechanism = UM_FULL; + m_selectiveUpdate = select; + } else if (!strcmp(optim, "Lazy")) { + p_updateMechanism = UM_LAZY; + m_selectiveUpdate = 1; + xbt_assert((select == 1) + || + (xbt_cfg_is_default_value + (_sg_cfg_set, "network/maxmin_selective_update")), + "Disabling selective update while using the lazy update mechanism is dumb!"); + } else { + xbt_die("Unsupported optimization (%s) for this model", optim); + } + + if (!p_maxminSystem) + p_maxminSystem = lmm_system_new(m_selectiveUpdate); + + routing_model_create(static_cast(createResource("__loopback__", + 498000000, NULL, 0.000015, NULL, + SURF_RESOURCE_ON, NULL, + SURF_LINK_FATPIPE, NULL))); + + if (p_updateMechanism == UM_LAZY) { + p_actionHeap = xbt_heap_new(8, NULL); + xbt_heap_set_update_callback(p_actionHeap, surf_action_lmm_update_index_heap); + p_modifiedSet = xbt_swag_new(xbt_swag_offset(*comm, p_actionListHookup)); + p_maxminSystem->keep_track = p_modifiedSet; + } +} + +NetworkCm02LinkLmmPtr NetworkCm02Model::createResource(const char *name, + double bw_initial, + tmgr_trace_t bw_trace, + double lat_initial, + tmgr_trace_t lat_trace, + e_surf_resource_state_t state_initial, + tmgr_trace_t state_trace, + e_surf_link_sharing_policy_t policy, + xbt_dict_t properties) +{ + xbt_assert(!xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL), + "Link '%s' declared several times in the platform file.", + name); + + NetworkCm02LinkLmmPtr nw_link = + new NetworkCm02LinkLmm(this, name, properties, p_maxminSystem, sg_bandwidth_factor * bw_initial, history, + state_initial, state_trace, bw_initial, bw_trace, lat_initial, lat_trace, policy); + + + xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, static_cast(nw_link)); + XBT_DEBUG("Create link '%s'",name); + + return nw_link; +} + +void NetworkCm02Model::updateActionsStateLazy(double now, double delta) +{ + NetworkCm02ActionLmmPtr action; + while ((xbt_heap_size(p_actionHeap) > 0) + && (double_equals(xbt_heap_maxkey(p_actionHeap), now))) { + action = (NetworkCm02ActionLmmPtr) xbt_heap_pop(p_actionHeap); + XBT_DEBUG("Something happened to action %p", action); +#ifdef HAVE_TRACING + if (TRACE_is_enabled()) { + int n = lmm_get_number_of_cnst_from_var(p_maxminSystem, action->p_variable); + unsigned int i; + for (i = 0; i < n; i++){ + lmm_constraint_t constraint = lmm_get_cnst_from_var(p_maxminSystem, + action->p_variable, + i); + NetworkCm02LinkPtr link = static_cast(lmm_constraint_id(constraint)); + TRACE_surf_link_set_utilization(link->m_name, + action->p_category, + (lmm_variable_getvalue(action->p_variable)* + lmm_get_cnst_weight_from_var(p_maxminSystem, + action->p_variable, + i)), + action->m_lastUpdate, + now - action->m_lastUpdate); + } + } +#endif + + // if I am wearing a latency hat + if (action->m_hat == LATENCY) { + XBT_DEBUG("Latency paid for action %p. Activating", action); + lmm_update_variable_weight(p_maxminSystem, action->p_variable, action->m_weight); + action->heapRemove(p_actionHeap); + action->m_lastUpdate = surf_get_clock(); + + // if I am wearing a max_duration or normal hat + } else if (action->m_hat == MAX_DURATION || + action->m_hat == NORMAL) { + // no need to communicate anymore + // assume that flows that reached max_duration have remaining of 0 + action->m_finish = surf_get_clock(); + XBT_DEBUG("Action %p finished", action); + action->m_remains = 0; + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + action->heapRemove(p_actionHeap); + + action->gapRemove(); + } + } + return; +} + +xbt_dynar_t NetworkCm02Model::getRoute(RoutingEdgePtr src, RoutingEdgePtr dst) +{ + xbt_dynar_t route = NULL; + routing_platf->getRouteAndLatency(src, dst, &route, NULL); + return route; +} + +ActionPtr NetworkCm02Model::communicate(RoutingEdgePtr src, RoutingEdgePtr dst, + double size, double rate) +{ + unsigned int i; + void *_link; + NetworkCm02LinkLmmPtr link; + int failed = 0; + NetworkCm02ActionLmmPtr action = NULL; + double bandwidth_bound; + double latency = 0.0; + xbt_dynar_t back_route = NULL; + int constraints_per_variable = 0; + + xbt_dynar_t route = xbt_dynar_new(sizeof(RoutingEdgePtr), NULL); + + XBT_IN("(%s,%s,%g,%g)", src->p_name, dst->p_name, size, rate); + + routing_platf->getRouteAndLatency(src, dst, &route, &latency); + xbt_assert(!xbt_dynar_is_empty(route) || latency, + "You're trying to send data from %s to %s but there is no connection at all between these two hosts.", + src->p_name, dst->p_name); + + xbt_dynar_foreach(route, i, _link) { + link = dynamic_cast(static_cast(_link)); + if (link->p_stateCurrent == SURF_RESOURCE_OFF) { + failed = 1; + break; + } + } + if (sg_network_crosstraffic == 1) { + routing_platf->getRouteAndLatency(dst, src, &back_route, NULL); + xbt_dynar_foreach(back_route, i, _link) { + link = dynamic_cast(static_cast(_link)); + if (link->p_stateCurrent == SURF_RESOURCE_OFF) { + failed = 1; + break; + } + } + } + + action = new NetworkCm02ActionLmm(this, size, failed); + +#ifdef HAVE_LATENCY_BOUND_TRACKING + action->m_latencyLimited = 0; +#endif + action->m_weight = action->m_latency = latency; + + //FIXME:REMOVxbt_swag_insert(action, action->p_stateSet); + action->m_rate = rate; + if (p_updateMechanism == UM_LAZY) { + action->m_indexHeap = -1; + action->m_lastUpdate = surf_get_clock(); + } + + bandwidth_bound = -1.0; + if (sg_weight_S_parameter > 0) { + xbt_dynar_foreach(route, i, _link) { + link = dynamic_cast(static_cast(_link)); + action->m_weight += + sg_weight_S_parameter / + (link->p_power.peak * link->p_power.scale); + } + } + xbt_dynar_foreach(route, i, _link) { + link = dynamic_cast(static_cast(_link)); + double bb = bandwidthFactor(size) * (link->p_power.peak * link->p_power.scale); + bandwidth_bound = + (bandwidth_bound < 0.0) ? bb : min(bandwidth_bound, bb); + } + + action->m_latCurrent = action->m_latency; + action->m_latency *= latencyFactor(size); + action->m_rate = bandwidthConstraint(action->m_rate, bandwidth_bound, size); + if (m_haveGap) { + xbt_assert(!xbt_dynar_is_empty(route), + "Using a model with a gap (e.g., SMPI) with a platform without links (e.g. vivaldi)!!!"); + + //link = *(NetworkCm02LinkLmmPtr *) xbt_dynar_get_ptr(route, 0); + link = dynamic_cast(*static_cast(xbt_dynar_get_ptr(route, 0))); + gapAppend(size, link, action); + XBT_DEBUG("Comm %p: %s -> %s gap=%f (lat=%f)", + action, src->p_name, dst->p_name, action->m_senderGap, + action->m_latency); + } + + constraints_per_variable = xbt_dynar_length(route); + if (back_route != NULL) + constraints_per_variable += xbt_dynar_length(back_route); + + if (action->m_latency > 0) { + action->p_variable = lmm_variable_new(p_maxminSystem, action, 0.0, -1.0, + constraints_per_variable); + if (p_updateMechanism == UM_LAZY) { + // add to the heap the event when the latency is payed + XBT_DEBUG("Added action (%p) one latency event at date %f", action, + action->m_latency + action->m_lastUpdate); + action->heapInsert(p_actionHeap, action->m_latency + action->m_lastUpdate, xbt_dynar_is_empty(route) ? NORMAL : LATENCY); + } + } else + action->p_variable = lmm_variable_new(p_maxminSystem, action, 1.0, -1.0, constraints_per_variable); + + if (action->m_rate < 0) { + lmm_update_variable_bound(p_maxminSystem, action->p_variable, (action->m_latCurrent > 0) ? sg_tcp_gamma / (2.0 * action->m_latCurrent) : -1.0); + } else { + lmm_update_variable_bound(p_maxminSystem, action->p_variable, (action->m_latCurrent > 0) ? min(action->m_rate, sg_tcp_gamma / (2.0 * action->m_latCurrent)) : action->m_rate); + } + + xbt_dynar_foreach(route, i, _link) { + link = dynamic_cast(static_cast(_link)); + lmm_expand(p_maxminSystem, link->p_constraint, action->p_variable, 1.0); + } + + if (sg_network_crosstraffic == 1) { + XBT_DEBUG("Fullduplex active adding backward flow using 5%%"); + xbt_dynar_foreach(back_route, i, _link) { + link = dynamic_cast(static_cast(_link)); + lmm_expand(p_maxminSystem, link->p_constraint, action->p_variable, .05); + } + } + + xbt_dynar_free(&route); + XBT_OUT(); + + return action; +} + +double NetworkCm02Model::latencyFactor(double size) { + return sg_latency_factor; +} + +double NetworkCm02Model::bandwidthFactor(double size) { + return sg_bandwidth_factor; +} + +double NetworkCm02Model::bandwidthConstraint(double rate, double bound, double size) { + return rate; +} + +/************ + * Resource * + ************/ +NetworkCm02LinkLmm::NetworkCm02LinkLmm(NetworkCm02ModelPtr model, const char *name, xbt_dict_t props, + lmm_system_t system, + double constraint_value, + tmgr_history_t history, + e_surf_resource_state_t state_init, + tmgr_trace_t state_trace, + double metric_peak, + tmgr_trace_t metric_trace, + double lat_initial, + tmgr_trace_t lat_trace, + e_surf_link_sharing_policy_t policy) +: Resource(model, name, props), + ResourceLmm(model, name, props, system, constraint_value, history, state_init, state_trace, metric_peak, metric_trace), + NetworkCm02Link(model, name, props) +{ + m_latCurrent = lat_initial; + if (lat_trace) + p_latEvent = tmgr_history_add_trace(history, lat_trace, 0.0, 0, static_cast(this)); + + if (policy == SURF_LINK_FATPIPE) + lmm_constraint_shared(p_constraint); +} + +bool NetworkCm02LinkLmm::isUsed() +{ + return lmm_constraint_used(p_model->p_maxminSystem, p_constraint); +} + +double NetworkCm02Link::getLatency() +{ + return m_latCurrent; +} + +double NetworkCm02LinkLmm::getBandwidth() +{ + return p_power.peak * p_power.scale; +} + +bool NetworkCm02LinkLmm::isShared() +{ + return lmm_constraint_is_shared(p_constraint); +} + +void NetworkCm02LinkLmm::updateState(tmgr_trace_event_t event_type, + double value, double date) +{ - /* printf("[" "%lg" "] Asking to update network card \"%s\" with value " */ - /* "%lg" " for event %p\n", surf_get_clock(), nw_link->name, */ ++ /* printf("[" "%g" "] Asking to update network card \"%s\" with value " */ ++ /* "%g" " for event %p\n", surf_get_clock(), nw_link->name, */ + /* value, event_type); */ + + if (event_type == p_power.event) { + double delta = + sg_weight_S_parameter / value - sg_weight_S_parameter / + (p_power.peak * p_power.scale); + lmm_variable_t var = NULL; + lmm_element_t elem = NULL; + NetworkCm02ActionLmmPtr action = NULL; + + p_power.peak = value; + lmm_update_constraint_bound(p_model->p_maxminSystem, + p_constraint, + sg_bandwidth_factor * + (p_power.peak * p_power.scale)); +#ifdef HAVE_TRACING + TRACE_surf_link_set_bandwidth(date, m_name, sg_bandwidth_factor * p_power.peak * p_power.scale); +#endif + if (sg_weight_S_parameter > 0) { + while ((var = lmm_get_var_from_cnst(p_model->p_maxminSystem, p_constraint, &elem))) { + action = (NetworkCm02ActionLmmPtr) lmm_variable_id(var); + action->m_weight += delta; + if (!action->m_suspended) + lmm_update_variable_weight(p_model->p_maxminSystem, action->p_variable, action->m_weight); + } + } + if (tmgr_trace_event_free(event_type)) + p_power.event = NULL; + } else if (event_type == p_latEvent) { + double delta = value - m_latCurrent; + lmm_variable_t var = NULL; + lmm_element_t elem = NULL; + NetworkCm02ActionLmmPtr action = NULL; + + m_latCurrent = value; + while ((var = lmm_get_var_from_cnst(p_model->p_maxminSystem, p_constraint, &elem))) { + action = (NetworkCm02ActionLmmPtr) lmm_variable_id(var); + action->m_latCurrent += delta; + action->m_weight += delta; + if (action->m_rate < 0) + lmm_update_variable_bound(p_model->p_maxminSystem, action->p_variable, sg_tcp_gamma / (2.0 * action->m_latCurrent)); + else { + lmm_update_variable_bound(p_model->p_maxminSystem, action->p_variable, + min(action->m_rate, sg_tcp_gamma / (2.0 * action->m_latCurrent))); + + if (action->m_rate < sg_tcp_gamma / (2.0 * action->m_latCurrent)) { + XBT_INFO("Flow is limited BYBANDWIDTH"); + } else { + XBT_INFO("Flow is limited BYLATENCY, latency of flow is %f", + action->m_latCurrent); + } + } + if (!action->m_suspended) + lmm_update_variable_weight(p_model->p_maxminSystem, action->p_variable, action->m_weight); + + } + if (tmgr_trace_event_free(event_type)) + p_latEvent = NULL; + } else if (event_type == p_stateEvent) { + if (value > 0) + p_stateCurrent = SURF_RESOURCE_ON; + else { + lmm_constraint_t cnst = p_constraint; + lmm_variable_t var = NULL; + lmm_element_t elem = NULL; + + p_stateCurrent = SURF_RESOURCE_OFF; + while ((var = lmm_get_var_from_cnst(p_model->p_maxminSystem, cnst, &elem))) { + ActionPtr action = (ActionPtr) lmm_variable_id(var); + + if (action->getState() == SURF_ACTION_RUNNING || + action->getState() == SURF_ACTION_READY) { + action->m_finish = date; + action->setState(SURF_ACTION_FAILED); + } + } + } + if (tmgr_trace_event_free(event_type)) + p_stateEvent = NULL; + } else { + XBT_CRITICAL("Unknown event ! \n"); + xbt_abort(); + } + + XBT_DEBUG + ("There were a resource state event, need to update actions related to the constraint (%p)", + p_constraint); + return; +} + +/********** + * Action * + **********/ +void NetworkCm02ActionLmm::updateRemainingLazy(double now) +{ + double delta = 0.0; + + if (m_suspended != 0) + return; + + delta = now - m_lastUpdate; + + if (m_remains > 0) { + XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate); + double_update(&(m_remains), m_lastValue * delta); + + XBT_DEBUG("Updating action(%p): remains is now %lf", this, m_remains); + } + + if (m_maxDuration != NO_MAX_DURATION) + double_update(&m_maxDuration, delta); + + if (m_remains <= 0 && + (lmm_get_variable_weight(p_variable) > 0)) { + m_finish = surf_get_clock(); + setState(SURF_ACTION_DONE); + + heapRemove(p_model->p_actionHeap); + } else if (((m_maxDuration != NO_MAX_DURATION) + && (m_maxDuration <= 0))) { + m_finish = surf_get_clock(); + setState(SURF_ACTION_DONE); + heapRemove(p_model->p_actionHeap); + } + + m_lastUpdate = now; + m_lastValue = lmm_variable_getvalue(p_variable); +} +void NetworkCm02ActionLmm::recycle() +{ + return; +} + diff --cc src/surf/network_constant.cpp index 6b177d6ab4,0000000000..13fff27765 mode 100644,000000..100644 --- a/src/surf/network_constant.cpp +++ b/src/surf/network_constant.cpp @@@ -1,172 -1,0 +1,168 @@@ +#include "network_constant.hpp" +#include "surf/random_mgr.h" + +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network); - static random_data_t random_latency = NULL; +static int host_number_int = 0; + +static void netcste_count_hosts(sg_platf_host_cbarg_t h) { + host_number_int++; +} + +/********* + * Model * + *********/ +void surf_network_model_init_Constant() +{ + xbt_assert(surf_network_model == NULL); + surf_network_model = new NetworkConstantModel(); + - if (!random_latency) - random_latency = random_new(RAND, 100, 0.0, 1.0, .125, .034); - + sg_platf_host_add_cb(netcste_count_hosts); + + ModelPtr model = static_cast(surf_network_model); + xbt_dynar_push(model_list, &model); + + routing_model_create(NULL); +} + +double NetworkConstantModel::shareResources(double now) +{ + void *_action = NULL; + NetworkConstantActionLmmPtr action = NULL; + double min = -1.0; + + xbt_swag_foreach(_action, p_runningActionSet) { + action = dynamic_cast(static_cast(_action)); + if (action->m_latency > 0) { + if (min < 0) + min = action->m_latency; + else if (action->m_latency < min) + min = action->m_latency; + } + } + + return min; +} + +void NetworkConstantModel::updateActionsState(double now, double delta) +{ + void *_action, *_next_action; + NetworkConstantActionLmmPtr action = NULL; + + xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) { + action = dynamic_cast(static_cast(_action)); + if (action->m_latency > 0) { + if (action->m_latency > delta) { + double_update(&(action->m_latency), delta); + } else { + action->m_latency = 0.0; + } + } + double_update(&(action->m_remains), + action->m_cost * delta / action->m_latInit); + if (action->m_maxDuration != NO_MAX_DURATION) + double_update(&(action->m_maxDuration), delta); + + if (action->m_remains <= 0) { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + } else if ((action->m_maxDuration != NO_MAX_DURATION) + && (action->m_maxDuration <= 0)) { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + } + } +} + +ActionPtr NetworkConstantModel::communicate(RoutingEdgePtr src, RoutingEdgePtr dst, + double size, double rate) +{ + char *src_name = src->p_name; + char *dst_name = dst->p_name; + + XBT_IN("(%s,%s,%g,%g)", src_name, dst_name, size, rate); + NetworkConstantActionLmmPtr action = new NetworkConstantActionLmm(this, sg_latency_factor); + XBT_OUT(); + + return action; +} + +/************ + * Resource * + ************/ +bool NetworkConstantLinkLmm::isUsed() +{ + return 0; +} + +void NetworkConstantLinkLmm::updateState(tmgr_trace_event_t event_type, + double value, double time) +{ + DIE_IMPOSSIBLE; +} + +double NetworkConstantLinkLmm::getBandwidth() +{ + DIE_IMPOSSIBLE; + return -1.0; /* useless since DIE actually abort(), but eclipse prefer to have a useless and harmless return */ +} + +double NetworkConstantLinkLmm::getLatency() +{ + DIE_IMPOSSIBLE; + return -1.0; /* useless since DIE actually abort(), but eclipse prefer to have a useless and harmless return */ +} + +bool NetworkConstantLinkLmm::isShared() +{ + DIE_IMPOSSIBLE; + return -1; /* useless since DIE actually abort(), but eclipse prefer to have a useless and harmless return */ +} + +/********** + * Action * + **********/ + +int NetworkConstantActionLmm::unref() +{ + m_refcount--; + if (!m_refcount) { + xbt_swag_remove(static_cast(this), p_stateSet); + delete this; + return 1; + } + return 0; +} + +void NetworkConstantActionLmm::cancel() +{ + return; +} + +#ifdef HAVE_TRACING +void NetworkConstantActionLmm::setCategory(const char *category) +{ + //ignore completely the categories in constant model, they are not traced +} +#endif + +void NetworkConstantActionLmm::suspend() +{ + m_suspended = true; +} + +void NetworkConstantActionLmm::resume() +{ + if (m_suspended) + m_suspended = false; +} + +void NetworkConstantActionLmm::recycle() +{ + return; +} + +bool NetworkConstantActionLmm::isSuspended() +{ + return m_suspended; +} + diff --cc src/surf/network_smpi.cpp index b38b3fe3a4,0000000000..ee6e415d36 mode 100644,000000..100644 --- a/src/surf/network_smpi.cpp +++ b/src/surf/network_smpi.cpp @@@ -1,197 -1,0 +1,197 @@@ +#include "network_smpi.hpp" +#include "simgrid/sg_config.h" + +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network); + +xbt_dynar_t smpi_bw_factor = NULL; +xbt_dynar_t smpi_lat_factor = NULL; + +typedef struct s_smpi_factor *smpi_factor_t; +typedef struct s_smpi_factor { + long factor; + double value; +} s_smpi_factor_t; + +xbt_dict_t gap_lookup = NULL; + +static int factor_cmp(const void *pa, const void *pb) +{ + return (((s_smpi_factor_t*)pa)->factor > ((s_smpi_factor_t*)pb)->factor); +} + + +static xbt_dynar_t parse_factor(const char *smpi_coef_string) +{ + char *value = NULL; + unsigned int iter = 0; + s_smpi_factor_t fact; + xbt_dynar_t smpi_factor, radical_elements, radical_elements2 = NULL; + + smpi_factor = xbt_dynar_new(sizeof(s_smpi_factor_t), NULL); + radical_elements = xbt_str_split(smpi_coef_string, ";"); + xbt_dynar_foreach(radical_elements, iter, value) { + + radical_elements2 = xbt_str_split(value, ":"); + if (xbt_dynar_length(radical_elements2) != 2) + xbt_die("Malformed radical for smpi factor!"); + fact.factor = atol(xbt_dynar_get_as(radical_elements2, 0, char *)); + fact.value = atof(xbt_dynar_get_as(radical_elements2, 1, char *)); + xbt_dynar_push_as(smpi_factor, s_smpi_factor_t, fact); + XBT_DEBUG("smpi_factor:\t%ld : %f", fact.factor, fact.value); + xbt_dynar_free(&radical_elements2); + } + xbt_dynar_free(&radical_elements); + iter=0; + xbt_dynar_sort(smpi_factor, &factor_cmp); + xbt_dynar_foreach(smpi_factor, iter, fact) { + XBT_DEBUG("ordered smpi_factor:\t%ld : %f", fact.factor, fact.value); + + } + return smpi_factor; +} + +/********* + * Model * + *********/ + +/************************************************************************/ +/* New model based on LV08 and experimental results of MPI ping-pongs */ +/************************************************************************/ +/* @Inproceedings{smpi_ipdps, */ +/* author={Pierre-Nicolas Clauss and Mark Stillwell and Stéphane Genaud and Frédéric Suter and Henri Casanova and Martin Quinson}, */ +/* title={Single Node On-Line Simulation of {MPI} Applications with SMPI}, */ +/* booktitle={25th IEEE International Parallel and Distributed Processing Symposium (IPDPS'11)}, */ +/* address={Anchorage (Alaska) USA}, */ +/* month=may, */ +/* year={2011} */ +/* } */ +void surf_network_model_init_SMPI(void) +{ + + if (surf_network_model) + return; + surf_network_model = new NetworkSmpiModel(); + net_define_callbacks(); + xbt_dynar_push(model_list, &surf_network_model); + //network_solve = lmm_solve; + + xbt_cfg_setdefault_double(_sg_cfg_set, "network/sender_gap", 10e-6); + xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 8775); +} + +void NetworkSmpiModel::gapAppend(double size, const NetworkCm02LinkLmmPtr link, NetworkCm02ActionLmmPtr action) +{ + const char *src = link->m_name; + xbt_fifo_t fifo; + //surf_action_network_CM02_t last_action; + //double bw; + + if (sg_sender_gap > 0.0) { + if (!gap_lookup) { - gap_lookup = xbt_dict_new(); ++ gap_lookup = xbt_dict_new_homogeneous(NULL); + } + fifo = (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup, src); + action->m_senderGap = 0.0; + if (fifo && xbt_fifo_size(fifo) > 0) { + /* Compute gap from last send */ + /*last_action = + (surf_action_network_CM02_t) + xbt_fifo_get_item_content(xbt_fifo_get_last_item(fifo));*/ + // bw = net_get_link_bandwidth(link); + action->m_senderGap = sg_sender_gap; + /* max(sg_sender_gap,last_action->sender.size / bw);*/ + action->m_latency += action->m_senderGap; + } + /* Append action as last send */ + /*action->sender.link_name = link->lmm_resource.generic_resource.name; + fifo = + (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup, + action->sender.link_name); + if (!fifo) { + fifo = xbt_fifo_new(); + xbt_dict_set(gap_lookup, action->sender.link_name, fifo, NULL); + } + action->sender.fifo_item = xbt_fifo_push(fifo, action);*/ + action->m_senderSize = size; + } +} + +void NetworkSmpiModel::gapRemove(ActionLmmPtr lmm_action) +{ + xbt_fifo_t fifo; + size_t size; + NetworkCm02ActionLmmPtr action = (NetworkCm02ActionLmmPtr)(lmm_action); + + if (sg_sender_gap > 0.0 && action->p_senderLinkName + && action->p_senderFifoItem) { + fifo = + (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup, + action->p_senderLinkName); + xbt_fifo_remove_item(fifo, action->p_senderFifoItem); + size = xbt_fifo_size(fifo); + if (size == 0) { + xbt_fifo_free(fifo); + xbt_dict_remove(gap_lookup, action->p_senderLinkName); + size = xbt_dict_length(gap_lookup); + if (size == 0) { + xbt_dict_free(&gap_lookup); + } + } + } +} + +double NetworkSmpiModel::bandwidthFactor(double size) +{ + if (!smpi_bw_factor) + smpi_bw_factor = + parse_factor(sg_cfg_get_string("smpi/bw_factor")); + + unsigned int iter = 0; + s_smpi_factor_t fact; + double current=1.0; + xbt_dynar_foreach(smpi_bw_factor, iter, fact) { + if (size <= fact.factor) { - XBT_DEBUG("%lf <= %ld return %f", size, fact.factor, current); ++ XBT_DEBUG("%f <= %ld return %f", size, fact.factor, current); + return current; + }else + current=fact.value; + } - XBT_DEBUG("%lf > %ld return %f", size, fact.factor, current); ++ XBT_DEBUG("%f > %ld return %f", size, fact.factor, current); + + return current; +} +double NetworkSmpiModel::latencyFactor(double size) +{ + if (!smpi_lat_factor) + smpi_lat_factor = + parse_factor(sg_cfg_get_string("smpi/lat_factor")); + + unsigned int iter = 0; + s_smpi_factor_t fact; + double current=1.0; + xbt_dynar_foreach(smpi_lat_factor, iter, fact) { + if (size <= fact.factor) { - XBT_DEBUG("%lf <= %ld return %f", size, fact.factor, current); ++ XBT_DEBUG("%f <= %ld return %f", size, fact.factor, current); + return current; + }else + current=fact.value; + } - XBT_DEBUG("%lf > %ld return %f", size, fact.factor, current); ++ XBT_DEBUG("%f > %ld return %f", size, fact.factor, current); + + return current; +} + +double NetworkSmpiModel::bandwidthConstraint(double rate, double bound, double size) +{ + return rate < 0 ? bound : min(bound, rate * bandwidthFactor(size)); +} + +/************ + * Resource * + ************/ + + + +/********** + * Action * + **********/ diff --cc src/surf/storage.cpp index 7a288588ae,0000000000..12444185a9 mode 100644,000000..100644 --- a/src/surf/storage.cpp +++ b/src/surf/storage.cpp @@@ -1,646 -1,0 +1,702 @@@ +#include "storage.hpp" +#include "surf_private.h" + ++#define __STDC_FORMAT_MACROS ++#include ++ +extern "C" { +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_storage, surf, + "Logging specific to the SURF storage module"); +} + +xbt_lib_t storage_lib; +int ROUTING_STORAGE_LEVEL; //Routing for storagelevel +int ROUTING_STORAGE_HOST_LEVEL; +int SURF_STORAGE_LEVEL; +xbt_lib_t storage_type_lib; +int ROUTING_STORAGE_TYPE_LEVEL; //Routing for storage_type level + +static xbt_dynar_t storage_list; + +xbt_dynar_t mount_list = NULL; /* temporary store of current mount storage */ +StorageModelPtr surf_storage_model = NULL; + +static int storage_selective_update = 0; +static xbt_swag_t storage_running_action_set_that_does_not_need_being_checked = NULL; + +/************* + * CallBacks * + *************/ + +static XBT_INLINE void routing_storage_type_free(void *r) +{ + storage_type_t stype = (storage_type_t) r; + free(stype->model); + free(stype->type_id); + free(stype->content); + xbt_dict_free(&(stype->properties)); ++ xbt_dict_free(&(stype->properties)); + free(stype); +} + +static XBT_INLINE void surf_storage_resource_free(void *r) +{ + // specific to storage - StoragePtr storage = (StoragePtr) r; ++ StoragePtr storage = dynamic_cast(static_cast(r)); + xbt_dict_free(&storage->p_content); + xbt_dynar_free(&storage->p_writeActions); ++ free(storage->p_typeId); ++ free(storage->p_contentType); + // generic resource + delete storage; +} + +static XBT_INLINE void routing_storage_host_free(void *r) +{ + xbt_dynar_t dyn = (xbt_dynar_t) r; + xbt_dynar_free(&dyn); +} + +static void parse_storage_init(sg_platf_storage_cbarg_t storage) +{ + void* stype = xbt_lib_get_or_null(storage_type_lib, + storage->type_id, + ROUTING_STORAGE_TYPE_LEVEL); + if(!stype) xbt_die("No storage type '%s'",storage->type_id); + + // if storage content is not specified use the content of storage_type if exist + if(!strcmp(storage->content,"") && strcmp(((storage_type_t) stype)->content,"")){ + storage->content = ((storage_type_t) stype)->content; - XBT_DEBUG("For disk '%s' content is empty, use the content of storage type '%s'",storage->id,((storage_type_t) stype)->type_id); ++ storage->content_type = ((storage_type_t) stype)->content_type; ++ XBT_DEBUG("For disk '%s' content is empty, inherit the content (of type %s) from storage type '%s' ", ++ storage->id,((storage_type_t) stype)->content_type, ++ ((storage_type_t) stype)->type_id); + } + - XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s' \n\t\tmodel '%s' \n\t\tcontent '%s'\n\t\tproperties '%p'\n", ++ XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s' " ++ "\n\t\tmodel '%s' \n\t\tcontent '%s'\n\t\tcontent_type '%s' " ++ "\n\t\tproperties '%p'\n", + storage->id, + ((storage_type_t) stype)->model, + ((storage_type_t) stype)->type_id, + storage->content, ++ storage->content_type, + ((storage_type_t) stype)->properties); + + surf_storage_model->createResource(storage->id, ((storage_type_t) stype)->model, + ((storage_type_t) stype)->type_id, - storage->content); ++ storage->content, ++ storage->content_type, ++ storage->properties); +} + +static void parse_mstorage_init(sg_platf_mstorage_cbarg_t mstorage) +{ + XBT_DEBUG("parse_mstorage_init"); +} + +static void parse_storage_type_init(sg_platf_storage_type_cbarg_t storagetype_) +{ + XBT_DEBUG("parse_storage_type_init"); +} + +static void parse_mount_init(sg_platf_mount_cbarg_t mount) +{ + XBT_DEBUG("parse_mount_init"); +} + +static void storage_parse_storage(sg_platf_storage_cbarg_t storage) +{ + xbt_assert(!xbt_lib_get_or_null(storage_lib, storage->id,ROUTING_STORAGE_LEVEL), + "Reading a storage, processing unit \"%s\" already exists", storage->id); + + // Verification of an existing type_id +#ifndef NDEBUG + void* storage_type = xbt_lib_get_or_null(storage_type_lib, storage->type_id,ROUTING_STORAGE_TYPE_LEVEL); +#endif + xbt_assert(storage_type,"Reading a storage, type id \"%s\" does not exists", storage->type_id); + + XBT_DEBUG("ROUTING Create a storage name '%s' with type_id '%s' and content '%s'", + storage->id, + storage->type_id, + storage->content); + + xbt_lib_set(storage_lib, + storage->id, + ROUTING_STORAGE_LEVEL, + (void *) xbt_strdup(storage->type_id)); +} + - static xbt_dict_t parse_storage_content(char *filename, size_t *used_size) ++static xbt_dict_t parse_storage_content(char *filename, sg_storage_size_t *used_size) +{ + *used_size = 0; + if ((!filename) || (strcmp(filename, "") == 0)) + return NULL; + - xbt_dict_t parse_content = xbt_dict_new_homogeneous(NULL); ++ xbt_dict_t parse_content = xbt_dict_new_homogeneous(xbt_free); + FILE *file = NULL; + + file = surf_fopen(filename, "r"); + xbt_assert(file != NULL, "Cannot open file '%s' (path=%s)", filename, + xbt_str_join(surf_path, ":")); + + char *line = NULL; + size_t len = 0; + ssize_t read; + char path[1024]; - size_t size; ++ sg_storage_size_t size; + + + while ((read = xbt_getline(&line, &len, file)) != -1) { + if (read){ - if(sscanf(line,"%s %zu",path, &size)==2) { ++ if(sscanf(line,"%s %" SCNu64, path, &size) == 2) { + *used_size += size; - xbt_dict_set(parse_content,path,(void*) size,NULL); ++ sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1); ++ *psize = size; ++ xbt_dict_set(parse_content,path,psize,NULL); + } else { + xbt_die("Be sure of passing a good format for content file.\n"); + } + } + } + free(line); + fclose(file); + return parse_content; +} + +static void storage_parse_storage_type(sg_platf_storage_type_cbarg_t storage_type) +{ + xbt_assert(!xbt_lib_get_or_null(storage_type_lib, storage_type->id,ROUTING_STORAGE_TYPE_LEVEL), + "Reading a storage type, processing unit \"%s\" already exists", storage_type->id); + + storage_type_t stype = xbt_new0(s_storage_type_t, 1); + stype->model = xbt_strdup(storage_type->model); + stype->properties = storage_type->properties; + stype->content = xbt_strdup(storage_type->content); ++ stype->content_type = xbt_strdup(storage_type->content_type); + stype->type_id = xbt_strdup(storage_type->id); - stype->size = storage_type->size * 1000000000; /* storage_type->size is in Gbytes and stype->sizeis in bytes */ ++ stype->size = storage_type->size; + - XBT_DEBUG("ROUTING Create a storage type id '%s' with model '%s' content '%s'", ++ XBT_DEBUG("ROUTING Create a storage type id '%s' with model '%s', " ++ "content '%s', and content_type '%s'", + stype->type_id, + stype->model, - storage_type->content); ++ storage_type->content, ++ storage_type->content_type); + + xbt_lib_set(storage_type_lib, + stype->type_id, + ROUTING_STORAGE_TYPE_LEVEL, + (void *) stype); +} +static void storage_parse_mstorage(sg_platf_mstorage_cbarg_t mstorage) +{ + THROW_UNIMPLEMENTED; +// mount_t mnt = xbt_new0(s_mount_t, 1); +// mnt->id = xbt_strdup(mstorage->type_id); +// mnt->name = xbt_strdup(mstorage->name); +// +// if(!mount_list){ +// XBT_DEBUG("Creata a Mount list for %s",A_surfxml_host_id); +// mount_list = xbt_dynar_new(sizeof(char *), NULL); +// } +// xbt_dynar_push(mount_list,(void *) mnt); +// free(mnt->id); +// free(mnt->name); +// xbt_free(mnt); +// XBT_DEBUG("ROUTING Mount a storage name '%s' with type_id '%s'",mstorage->name, mstorage->id); +} + +static void mount_free(void *p) +{ + mount_t mnt = (mount_t) p; + xbt_free(mnt->name); +} + +static void storage_parse_mount(sg_platf_mount_cbarg_t mount) +{ + // Verification of an existing storage +#ifndef NDEBUG - void* storage = xbt_lib_get_or_null(storage_lib, mount->id,ROUTING_STORAGE_LEVEL); ++ void* storage = xbt_lib_get_or_null(storage_lib, mount->storageId, ROUTING_STORAGE_LEVEL); +#endif - xbt_assert(storage,"Disk id \"%s\" does not exists", mount->id); ++ xbt_assert(storage,"Disk id \"%s\" does not exists", mount->storageId); + - XBT_DEBUG("ROUTING Mount '%s' on '%s'",mount->id, mount->name); ++ XBT_DEBUG("ROUTING Mount '%s' on '%s'",mount->storageId, mount->name); + + s_mount_t mnt; - mnt.id = surf_storage_resource_priv(surf_storage_resource_by_name(mount->id)); ++ mnt.storage = surf_storage_resource_priv(surf_storage_resource_by_name(mount->storageId)); + mnt.name = xbt_strdup(mount->name); + + if(!mount_list){ + //FIXME:XBT_DEBUG("Create a Mount list for %s",A_surfxml_host_id); + mount_list = xbt_dynar_new(sizeof(s_mount_t), mount_free); + } + xbt_dynar_push(mount_list,&mnt); +} + +static void storage_define_callbacks() +{ + sg_platf_storage_add_cb(parse_storage_init); + sg_platf_storage_type_add_cb(parse_storage_type_init); + sg_platf_mstorage_add_cb(parse_mstorage_init); + sg_platf_mount_add_cb(parse_mount_init); +} + +void storage_register_callbacks() { + + ROUTING_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,xbt_free); + ROUTING_STORAGE_HOST_LEVEL = xbt_lib_add_level(storage_lib, routing_storage_host_free); + ROUTING_STORAGE_TYPE_LEVEL = xbt_lib_add_level(storage_type_lib, routing_storage_type_free); + SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib, surf_storage_resource_free); + + sg_platf_storage_add_cb(storage_parse_storage); + sg_platf_mstorage_add_cb(storage_parse_mstorage); + sg_platf_storage_type_add_cb(storage_parse_storage_type); + sg_platf_mount_add_cb(storage_parse_mount); +} + +/********* + * Model * + *********/ + +void surf_storage_model_init_default(void) +{ + surf_storage_model = new StorageModel(); + storage_define_callbacks(); + xbt_dynar_push(model_list, &surf_storage_model); +} + +StorageModel::StorageModel() : Model("Storage") { + StorageActionLmm action; + + XBT_DEBUG("surf_storage_model_init_internal"); + + storage_running_action_set_that_does_not_need_being_checked = + xbt_swag_new(xbt_swag_offset(action, p_stateHookup)); + + if (!p_maxminSystem) { + p_maxminSystem = lmm_system_new(storage_selective_update); + } +} + + +StorageModel::~StorageModel(){ + lmm_system_free(p_maxminSystem); + + surf_storage_model = NULL; + + xbt_dynar_free(&storage_list); + + xbt_swag_free(storage_running_action_set_that_does_not_need_being_checked); + storage_running_action_set_that_does_not_need_being_checked = NULL; +} + - StoragePtr StorageModel::createResource(const char* id, const char* model, const char* type_id, const char* content_name) ++StoragePtr StorageModel::createResource(const char* id, const char* model, const char* type_id, ++ const char* content_name, const char* content_type, xbt_dict_t properties) +{ + + xbt_assert(!surf_storage_resource_priv(surf_storage_resource_by_name(id)), + "Storage '%s' declared several times in the platform file", + id); + + storage_type_t storage_type = (storage_type_t) xbt_lib_get_or_null(storage_type_lib, type_id,ROUTING_STORAGE_TYPE_LEVEL); + - double Bread = atof((char*)xbt_dict_get(storage_type->properties, "Bread")); - double Bwrite = atof((char*)xbt_dict_get(storage_type->properties, "Bwrite")); - double Bconnection = atof((char*)xbt_dict_get(storage_type->properties, "Bconnection")); ++ double Bread = surf_parse_get_bandwidth((char*)xbt_dict_get(storage_type->properties, "Bread")); ++ double Bwrite = surf_parse_get_bandwidth((char*)xbt_dict_get(storage_type->properties, "Bwrite")); ++ double Bconnection = surf_parse_get_bandwidth((char*)xbt_dict_get(storage_type->properties, "Bconnection")); + - StoragePtr storage = new StorageLmm(this, NULL, NULL, p_maxminSystem, - Bread, Bwrite, Bconnection, (char *)content_name, storage_type->size); ++ StoragePtr storage = new StorageLmm(this, id, properties, p_maxminSystem, ++ Bread, Bwrite, Bconnection, ++ type_id, (char *)content_name, xbt_strdup(content_type), storage_type->size); + - xbt_lib_set(storage_lib, id, SURF_STORAGE_LEVEL, storage); ++ xbt_lib_set(storage_lib, id, SURF_STORAGE_LEVEL, static_cast(storage)); + + XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s' \n\t\tmodel '%s' \n\t\tproperties '%p'\n\t\tBread '%f'\n", + id, + model, + type_id, + storage_type->properties, + Bread); + - if(!storage_list) storage_list=xbt_dynar_new(sizeof(char *),NULL); ++ if(!storage_list) ++ storage_list = xbt_dynar_new(sizeof(char *),NULL); + xbt_dynar_push(storage_list, &storage); + + return storage; +} + +double StorageModel::shareResources(double now) +{ + XBT_DEBUG("storage_share_resources %f", now); + unsigned int i, j; + StoragePtr storage; + StorageActionLmmPtr write_action; + + double min_completion = shareResourcesMaxMin(p_runningActionSet, + p_maxminSystem, lmm_solve); + + double rate; + // Foreach disk + xbt_dynar_foreach(storage_list,i,storage) + { + rate = 0; + // Foreach write action on disk + xbt_dynar_foreach(storage->p_writeActions, j, write_action) + { + rate += lmm_variable_getvalue(write_action->p_variable); + } + if(rate > 0) + min_completion = MIN(min_completion, (storage->m_size-storage->m_usedSize)/rate); + } + + return min_completion; +} + +void StorageModel::updateActionsState(double now, double delta) +{ + void *_action, *_next_action; + StorageActionLmmPtr action = NULL; + - // Update the disk usage - // Update the file size - // For each action of type write + xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) { + action = dynamic_cast(static_cast(_action)); + if(action->m_type == WRITE) + { ++ // Update the disk usage ++ // Update the file size ++ // For each action of type write + double rate = lmm_variable_getvalue(action->p_variable); + /* Hack to avoid rounding differences between x86 and x86_64 - * (note that the next sizes are of type size_t). */ ++ * (note that the next sizes are of type sg_storage_size_t). */ + long incr = delta * rate + MAXMIN_PRECISION; + action->p_storage->m_usedSize += incr; // disk usage + action->p_file->size += incr; // file size - } - } + - xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) { - action = dynamic_cast(static_cast(_action)); ++ sg_storage_size_t *psize = xbt_new(sg_storage_size_t,1); ++ *psize = action->p_file->size; ++ ++ xbt_dict_t content_dict = action->p_storage->p_content; ++ xbt_dict_set(content_dict, action->p_file->name, psize, NULL); ++ } + + double_update(&action->m_remains, + lmm_variable_getvalue(action->p_variable) * delta); + + if (action->m_maxDuration != NO_MAX_DURATION) + double_update(&action->m_maxDuration, delta); + + if(action->m_remains > 0 && + lmm_get_variable_weight(action->p_variable) > 0 && + action->p_storage->m_usedSize == action->p_storage->m_size) + { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_FAILED); + } else if ((action->m_remains <= 0) && + (lmm_get_variable_weight(action->p_variable) > 0)) + { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + } else if ((action->m_maxDuration != NO_MAX_DURATION) && + (action->m_maxDuration <= 0)) + { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + } + } + + return; +} + +xbt_dict_t Storage::parseContent(char *filename) +{ + m_usedSize = 0; + if ((!filename) || (strcmp(filename, "") == 0)) + return NULL; + - xbt_dict_t parse_content = xbt_dict_new_homogeneous(NULL); ++ xbt_dict_t parse_content = xbt_dict_new_homogeneous(xbt_free); + FILE *file = NULL; + + file = surf_fopen(filename, "r"); + xbt_assert(file != NULL, "Cannot open file '%s' (path=%s)", filename, + xbt_str_join(surf_path, ":")); + + char *line = NULL; + size_t len = 0; + ssize_t read; + char path[1024]; - size_t size; ++ sg_storage_size_t size; + + + while ((read = xbt_getline(&line, &len, file)) != -1) { + if (read){ - if(sscanf(line,"%s %zu",path, &size)==2) { ++ if(sscanf(line,"%s %" SCNu64, path, &size) == 2) { + m_usedSize += size; - xbt_dict_set(parse_content,path,(void*) size,NULL); ++ sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1); ++ *psize = size; ++ xbt_dict_set(parse_content,path,psize,NULL); + } else { + xbt_die("Be sure of passing a good format for content file.\n"); + } + } + } + free(line); + fclose(file); + return parse_content; +} + +/************ + * Resource * + ************/ + +Storage::Storage(StorageModelPtr model, const char* name, xbt_dict_t properties) +: Resource(model, name, properties) +{ + p_writeActions = xbt_dynar_new(sizeof(char *),NULL); +} + +StorageLmm::StorageLmm(StorageModelPtr model, const char* name, xbt_dict_t properties, + lmm_system_t maxminSystem, double bread, double bwrite, double bconnection, - char *content_name, size_t size) ++ const char* type_id, char *content_name, char *content_type, size_t size) + : Resource(model, name, properties), ResourceLmm(), Storage(model, name, properties) { + XBT_DEBUG("Create resource with Bconnection '%f' Bread '%f' Bwrite '%f' and Size '%lu'", bconnection, bread, bwrite, ((unsigned long)size)); + + p_stateCurrent = SURF_RESOURCE_ON; + m_usedSize = 0; + m_size = 0; + + p_content = parseContent(content_name); ++ p_contentType = content_type; + p_constraint = lmm_constraint_new(maxminSystem, this, bconnection); + p_constraintRead = lmm_constraint_new(maxminSystem, this, bread); + p_constraintWrite = lmm_constraint_new(maxminSystem, this, bwrite); + m_size = size; ++ p_typeId = xbt_strdup(type_id); +} + +bool Storage::isUsed() +{ + THROW_UNIMPLEMENTED; + return false; +} + +void Storage::updateState(tmgr_trace_event_t event_type, double value, double date) +{ + THROW_UNIMPLEMENTED; +} + +StorageActionPtr StorageLmm::ls(const char* path) +{ + StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, p_stateCurrent != SURF_RESOURCE_ON, this, LS); + + action->p_lsDict = NULL; - xbt_dict_t ls_dict = xbt_dict_new(); ++ xbt_dict_t ls_dict = xbt_dict_new_homogeneous(xbt_free); + + char* key; - size_t size = 0; ++ sg_storage_size_t size = 0; + xbt_dict_cursor_t cursor = NULL; + + xbt_dynar_t dyn = NULL; + char* file = NULL; + + // for each file in the storage content + xbt_dict_foreach(p_content,cursor,key,size){ + // Search if file start with the prefix 'path' + if(xbt_str_start_with(key,path)){ + file = &key[strlen(path)]; + + // Split file with '/' + dyn = xbt_str_split(file,"/"); + file = xbt_dynar_get_as(dyn,0,char*); + + // file + if(xbt_dynar_length(dyn) == 1){ - xbt_dict_set(ls_dict,file,&size,NULL); ++ sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1); ++ *psize=size; ++ xbt_dict_set(ls_dict, file, psize, NULL); + } + // Directory + else + { + // if directory does not exist yet in the dictionary + if(!xbt_dict_get_or_null(ls_dict,file)) + xbt_dict_set(ls_dict,file,NULL,NULL); + } + xbt_dynar_free(&dyn); + } + } + + action->p_lsDict = ls_dict; + return action; +} + +StorageActionPtr StorageLmm::open(const char* mount, const char* path) +{ + XBT_DEBUG("\tOpen file '%s'",path); - size_t size = (size_t) xbt_dict_get_or_null(p_content, path); ++ sg_storage_size_t size, *psize; ++ psize = (sg_storage_size_t*) xbt_dict_get_or_null(p_content, path); + // if file does not exist create an empty file - if(!size){ - xbt_dict_set(p_content, path, &size, NULL); ++ if(psize) ++ size = *psize; ++ else { ++ psize = xbt_new(sg_storage_size_t,1); ++ size = 0; ++ *psize = size; ++ xbt_dict_set(p_content, path, psize, NULL); + XBT_DEBUG("File '%s' was not found, file created.",path); + } + surf_file_t file = xbt_new0(s_surf_file_t,1); + file->name = xbt_strdup(path); + file->size = size; - file->storage = xbt_strdup(mount); ++ file->mount = xbt_strdup(mount); + + StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, p_stateCurrent != SURF_RESOURCE_ON, this, OPEN); + action->p_file = file; + return action; +} + +StorageActionPtr StorageLmm::close(surf_file_t fd) +{ + char *filename = fd->name; - XBT_DEBUG("\tClose file '%s' size '%zu'", filename, fd->size); ++ XBT_DEBUG("\tClose file '%s' size '%" PRIu64 "'", filename, fd->size); + // unref write actions from storage + StorageActionLmmPtr write_action; + unsigned int i; + xbt_dynar_foreach(p_writeActions, i, write_action) { + if ((write_action->p_file) == fd) { + xbt_dynar_cursor_rm(p_writeActions, &i); + write_action->unref(); + } + } + free(fd->name); - free(fd->storage); ++ free(fd->mount); + xbt_free(fd); + StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, p_stateCurrent != SURF_RESOURCE_ON, this, CLOSE); + return action; +} + - StorageActionPtr StorageLmm::read(void* ptr, size_t size, surf_file_t fd) ++StorageActionPtr StorageLmm::read(surf_file_t fd, sg_storage_size_t size) +{ + if(size > fd->size) + size = fd->size; + StorageActionLmmPtr action = new StorageActionLmm(p_model, size, p_stateCurrent != SURF_RESOURCE_ON, this, READ); + return action; +} + - StorageActionPtr StorageLmm::write(const void* ptr, size_t size, surf_file_t fd) ++StorageActionPtr StorageLmm::write(surf_file_t fd, sg_storage_size_t size) +{ + char *filename = fd->name; - XBT_DEBUG("\tWrite file '%s' size '%zu/%zu'",filename,size,fd->size); ++ XBT_DEBUG("\tWrite file '%s' size '%" PRIu64 "/%" PRIu64 "'",filename,size,fd->size); + + StorageActionLmmPtr action = new StorageActionLmm(p_model, size, p_stateCurrent != SURF_RESOURCE_ON, this, WRITE); + action->p_file = fd; + + // If the storage is full + if(m_usedSize==m_size) { + action->setState(SURF_ACTION_FAILED); + } + return action; +} + ++xbt_dict_t StorageLmm::getContent() ++{ ++ /* For the moment this action has no cost, but in the future we could take in account access latency of the disk */ ++ /*surf_action_t action = storage_action_execute(storage,0, LS);*/ ++ ++ xbt_dict_t content_dict = xbt_dict_new_homogeneous(NULL); ++ xbt_dict_cursor_t cursor = NULL; ++ char *file; ++ sg_storage_size_t *psize; ++ ++ xbt_dict_foreach(p_content, cursor, file, psize){ ++ xbt_dict_set(content_dict,file,psize,NULL); ++ } ++ return content_dict; ++} ++ ++sg_storage_size_t StorageLmm::getSize(){ ++ return m_size; ++} ++ +/********** + * Action * + **********/ + +StorageActionLmm::StorageActionLmm(ModelPtr model, double cost, bool failed, StorageLmmPtr storage, e_surf_action_storage_type_t type) + : Action(model, cost, failed), ActionLmm(model, cost, failed), StorageAction(model, cost, failed, storage, type) { - XBT_IN("(%s,%zu", storage->m_name, cost); ++ XBT_IN("(%s,%" PRIu64, storage->m_name, cost); + p_variable = lmm_variable_new(p_model->p_maxminSystem, this, 1.0, -1.0 , 3); + + // Must be less than the max bandwidth for all actions + lmm_expand(p_model->p_maxminSystem, storage->p_constraint, p_variable, 1.0); + switch(type) { + case OPEN: + case CLOSE: + case STAT: + case LS: + break; + case READ: + lmm_expand(p_model->p_maxminSystem, storage->p_constraintRead, + p_variable, 1.0); + break; + case WRITE: + lmm_expand(p_model->p_maxminSystem, storage->p_constraintWrite, + p_variable, 1.0); + xbt_dynar_push(storage->p_writeActions, static_cast(this)); + break; + } + XBT_OUT(); +} + +int StorageActionLmm::unref() +{ + m_refcount--; + if (!m_refcount) { + xbt_swag_remove(static_cast(this), p_stateSet); + if (p_variable) + lmm_variable_free(p_model->p_maxminSystem, p_variable); +#ifdef HAVE_TRACING + xbt_free(p_category); +#endif + delete this; + return 1; + } + return 0; +} + +void StorageActionLmm::cancel() +{ + setState(SURF_ACTION_FAILED); + return; +} + +void StorageActionLmm::suspend() +{ + XBT_IN("(%p)", this); + if (m_suspended != 2) { + lmm_update_variable_weight(p_model->p_maxminSystem, + p_variable, + 0.0); + m_suspended = 1; + } + XBT_OUT(); +} + +void StorageActionLmm::resume() +{ + THROW_UNIMPLEMENTED; +} + +bool StorageActionLmm::isSuspended() +{ + return m_suspended == 1; +} + +void StorageActionLmm::setMaxDuration(double duration) +{ + THROW_UNIMPLEMENTED; +} + +void StorageActionLmm::setPriority(double priority) +{ + THROW_UNIMPLEMENTED; +} + diff --cc src/surf/storage.hpp index 94ac7fd699,0000000000..cceebf5ba6 mode 100644,000000..100644 --- a/src/surf/storage.hpp +++ b/src/surf/storage.hpp @@@ -1,143 -1,0 +1,150 @@@ +#include "surf.hpp" + +#ifndef STORAGE_HPP_ +#define STORAGE_HPP_ + +/*********** + * Classes * + ***********/ + +class StorageModel; +typedef StorageModel *StorageModelPtr; + +class Storage; +typedef Storage *StoragePtr; + +class StorageLmm; +typedef StorageLmm *StorageLmmPtr; + +class StorageAction; +typedef StorageAction *StorageActionPtr; + +class StorageActionLmm; +typedef StorageActionLmm *StorageActionLmmPtr; + + +/********* + * Model * + *********/ +class StorageModel : public Model { +public: + StorageModel(); + ~StorageModel(); - StoragePtr createResource(const char* id, const char* model, const char* type_id, const char* content_name); ++ StoragePtr createResource(const char* id, const char* model, const char* type_id, ++ const char* content_name, const char* content_type, xbt_dict_t properties); + double shareResources(double now); + void updateActionsState(double now, double delta); + +}; + +/************ + * Resource * + ************/ + +class Storage : virtual public Resource { +public: + Storage(StorageModelPtr model, const char* name, xbt_dict_t properties); + + bool isUsed(); + void updateState(tmgr_trace_event_t event_type, double value, double date); + - xbt_dict_t p_content; /* char * -> s_surf_file_t */ ++ xbt_dict_t p_content; ++ char* p_contentType; ++ sg_storage_size_t m_size; ++ sg_storage_size_t m_usedSize; ++ char * p_typeId; + + virtual StorageActionPtr open(const char* mount, const char* path)=0; + virtual StorageActionPtr close(surf_file_t fd)=0; + //virtual StorageActionPtr unlink(surf_file_t fd)=0; + virtual StorageActionPtr ls(const char *path)=0; - //virtual size_t getSize(surf_file_t fd); - virtual StorageActionPtr read(void* ptr, size_t size, surf_file_t fd)=0;//FIXME:why we have a useless param ptr ?? - virtual StorageActionPtr write(const void* ptr, size_t size, surf_file_t fd)=0;//FIXME:why we have a useless param ptr ?? ++ virtual StorageActionPtr read(surf_file_t fd, sg_storage_size_t size)=0; ++ virtual StorageActionPtr write(surf_file_t fd, sg_storage_size_t size)=0; ++ virtual xbt_dict_t getContent()=0; ++ virtual sg_storage_size_t getSize()=0; ++ + xbt_dict_t parseContent(char *filename); + - size_t m_size; - size_t m_usedSize; + xbt_dynar_t p_writeActions; +}; + +class StorageLmm : public ResourceLmm, public Storage { +public: + StorageLmm(StorageModelPtr model, const char* name, xbt_dict_t properties, + lmm_system_t maxminSystem, double bread, double bwrite, double bconnection, - char *content_name, size_t size); ++ const char* type_id, char *content_name, char *content_type, size_t size); + + StorageActionPtr open(const char* mount, const char* path); + StorageActionPtr close(surf_file_t fd); + //StorageActionPtr unlink(surf_file_t fd); + StorageActionPtr ls(const char *path); - //size_t getSize(surf_file_t fd); - StorageActionPtr read(void* ptr, size_t size, surf_file_t fd);//FIXME:why we have a useless param ptr ?? - StorageActionPtr write(const void* ptr, size_t size, surf_file_t fd);//FIXME:why we have a useless param ptr ?? ++ xbt_dict_t getContent(); ++ sg_storage_size_t getSize(); ++ StorageActionPtr read(surf_file_t fd, sg_storage_size_t size);//FIXME:why we have a useless param ptr ?? ++ StorageActionPtr write(surf_file_t fd, sg_storage_size_t size);//FIXME:why we have a useless param ptr ?? + + lmm_constraint_t p_constraintWrite; /* Constraint for maximum write bandwidth*/ + lmm_constraint_t p_constraintRead; /* Constraint for maximum write bandwidth*/ +}; + +/********** + * Action * + **********/ + +typedef enum { + READ=0, WRITE, STAT, OPEN, CLOSE, LS +} e_surf_action_storage_type_t; + + +class StorageAction : virtual public Action { +public: + StorageAction(){}; + StorageAction(ModelPtr model, double cost, bool failed, StoragePtr storage, e_surf_action_storage_type_t type) + : p_storage(storage), m_type(type) {}; + + + + e_surf_action_storage_type_t m_type; + StoragePtr p_storage; + surf_file_t p_file; + xbt_dict_t p_lsDict; +}; + +class StorageActionLmm : public ActionLmm, public StorageAction { +public: + StorageActionLmm(){}; + StorageActionLmm(ModelPtr model, double cost, bool failed, StorageLmmPtr storage, e_surf_action_storage_type_t type); + void suspend(); + int unref(); + void cancel(); + //FIXME:??void recycle(); + void resume(); + bool isSuspended(); + void setMaxDuration(double duration); + void setPriority(double priority); + +}; + + +typedef struct s_storage_type { + char *model; + char *content; ++ char *content_type; + char *type_id; + xbt_dict_t properties; - size_t size; ++ sg_storage_size_t size; +} s_storage_type_t, *storage_type_t; + +typedef struct s_mount { - void *id; ++ void *storage; + char *name; +} s_mount_t, *mount_t; + +typedef struct surf_file { + char *name; - char *storage; - size_t size; ++ char *mount; ++ sg_storage_size_t size; +} s_surf_file_t; + + +#endif /* STORAGE_HPP_ */ diff --cc src/surf/storage_private.h index dccf6f3966,ee023b417f..13b67f7afb --- a/src/surf/storage_private.h +++ b/src/surf/storage_private.h @@@ -22,12 -23,12 +23,20 @@@ typedef struct s_mount typedef struct surf_file { char *name; - char *storage; - size_t size; + char *mount; + sg_storage_size_t size; } s_surf_file_t; ++<<<<<<< HEAD +typedef struct storage { + //FIXME:s_surf_resource_t generic_resource; /*< Structure with generic data. Needed at begin to interact with SURF */ ++||||||| merged common ancestors ++typedef struct storage { ++ s_surf_resource_t generic_resource; /*< Structure with generic data. Needed at begin to interact with SURF */ ++======= + typedef struct surf_storage { + s_surf_resource_t generic_resource; /*< Structure with generic data. Needed at begin to interact with SURF */ ++>>>>>>> 045db1657e870c721be490b411868f4181a12ced e_surf_resource_state_t state_current; /*< STORAGE current state (ON or OFF) */ lmm_constraint_t constraint; /* Constraint for maximum bandwidth from connection */ lmm_constraint_t constraint_write; /* Constraint for maximum write bandwidth*/ diff --cc src/surf/surf.cpp index 41545d889f,0000000000..010de57854 mode 100644,000000..100644 --- a/src/surf/surf.cpp +++ b/src/surf/surf.cpp @@@ -1,1070 -1,0 +1,1053 @@@ +#include "surf_private.h" +#include "surf.hpp" +#include "network.hpp" +#include "cpu.hpp" +#include "workstation.hpp" +#include "simix/smx_host_private.h" +#include "surf_routing.hpp" +#include "simgrid/sg_config.h" +#include "mc/mc.h" + +extern "C" { +XBT_LOG_NEW_CATEGORY(surf, "All SURF categories"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf, + "Logging specific to SURF (kernel)"); +} + +/********* + * Utils * + *********/ + +/* This function is a pimple that we ought to fix. But it won't be easy. + * + * The surf_solve() function does properly return the set of actions that changed. + * Instead, each model change a global data, and then the caller of surf_solve must + * pick into these sets of action_failed and action_done. + * + * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up. + * We worked by putting sentinel actions on every resources we are interested in, + * so that surf informs us if/when the corresponding resource fails. + * + * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes. + * We have a set of resources that are currently down and for which simix needs to know when it comes back up. + * And the current function is called *at every simulation step* to sweep over that set, searching for a resource + * that was turned back up in the meanwhile. This is UGLY and slow. + * + * The proper solution would be to not rely on globals for the action_failed and action_done swags. + * They must be passed as parameter by the caller (the handling of these actions in simix may let you + * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this + * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more + * cleanup to do). + * + * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up + * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and + * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix + * sees it and react accordingly. This would kill that need for surf to call simix. + * + */ + +static void remove_watched_host(void *key) +{ + xbt_dict_remove(watched_hosts_lib, *(char**)key); +} + - void surf_watched_hosts(void) ++/*void surf_watched_hosts(void) +{ + char *key; + void *host; + xbt_dict_cursor_t cursor; + xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL); + + XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib"); + xbt_dict_foreach(watched_hosts_lib, cursor, key, host) + { + if(SIMIX_host_get_state((smx_host_t)host) == SURF_RESOURCE_ON){ + XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host)); + SIMIX_host_autorestart((smx_host_t)host); + xbt_dynar_push_as(hosts, char*, key); + } + else + XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key); + } + xbt_dynar_map(hosts, remove_watched_host); + xbt_dynar_free(&hosts); - } ++}*/ + + +xbt_dynar_t model_list = NULL; +tmgr_history_t history = NULL; +lmm_system_t maxmin_system = NULL; +xbt_dynar_t surf_path = NULL; ++xbt_dynar_t host_that_restart = NULL; ++xbt_dict_t watched_hosts_lib; + +/* Don't forget to update the option description in smx_config when you change this */ +s_surf_model_description_t surf_network_model_description[] = { + {"LV08", + "Realistic network analytic model (slow-start modeled by multiplying latency by 10.4, bandwidth by .92; bottleneck sharing uses a payload of S=8775 for evaluating RTT). ", + surf_network_model_init_LegrandVelho}, + {"Constant", + "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.", + surf_network_model_init_Constant}, + {"SMPI", + "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)", + surf_network_model_init_SMPI}, + {"CM02", + "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).", + surf_network_model_init_CM02}, +#ifdef HAVE_GTNETS + {"GTNets", + "Network pseudo-model using the GTNets simulator instead of an analytic model", + surf_network_model_init_GTNETS}, +#endif +#ifdef HAVE_NS3 + {"NS3", + "Network pseudo-model using the NS3 tcp model instead of an analytic model", + surf_network_model_init_NS3}, +#endif + {"Reno", + "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).", + surf_network_model_init_Reno}, + {"Reno2", + "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).", + surf_network_model_init_Reno2}, + {"Vegas", + "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).", + surf_network_model_init_Vegas}, + {NULL, NULL, NULL} /* this array must be NULL terminated */ +}; + +s_surf_model_description_t surf_cpu_model_description[] = { + {"Cas01", + "Simplistic CPU model (time=size/power).", + surf_cpu_model_init_Cas01}, + {NULL, NULL, NULL} /* this array must be NULL terminated */ +}; + +s_surf_model_description_t surf_workstation_model_description[] = { + {"default", + "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)", + surf_workstation_model_init_current_default}, + {"compound", + "Workstation model that is automatically chosen if you change the network and CPU models", + surf_workstation_model_init_compound}, + {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks", + surf_workstation_model_init_ptask_L07}, + {NULL, NULL, NULL} /* this array must be NULL terminated */ +}; + +s_surf_model_description_t surf_optimization_mode_description[] = { + {"Lazy", + "Lazy action management (partial invalidation in lmm + heap in action remaining).", + NULL}, + {"TI", + "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).", + NULL}, + {"Full", + "Full update of remaining and variables. Slow but may be useful when debugging.", + NULL}, + {NULL, NULL, NULL} /* this array must be NULL terminated */ +}; + +s_surf_model_description_t surf_storage_model_description[] = { + {"default", + "Simplistic storage model.", + surf_storage_model_init_default}, + {NULL, NULL, NULL} /* this array must be NULL terminated */ +}; + +#ifdef CONTEXT_THREADS +static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */ +#endif + +static double *surf_mins = NULL; /* return value of share_resources for each model */ +static int surf_min_index; /* current index in surf_mins */ +static double min; /* duration determined by surf_solve */ + +double NOW = 0; + +double surf_get_clock(void) +{ + return NOW; +} + - /*TODO: keepit void surf_watched_hosts(void) - { - char *key; - void *_host; - smx_host_t host; - xbt_dict_cursor_t cursor; - xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL); - - XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib"); - xbt_dict_foreach(watched_hosts_lib,cursor,key,_host) - { - host = (smx_host_t) host; - if(SIMIX_host_get_state(host) == SURF_RESOURCE_ON){ - XBT_INFO("Restart processes on host: %s",SIMIX_host_get_name(host)); - SIMIX_host_autorestart(host); - xbt_dynar_push_as(hosts, char*, key); - } - else - XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key); - } - xbt_dynar_map(hosts, remove_watched_host); - xbt_dynar_free(&hosts); - }*/ - +#ifdef _XBT_WIN32 +# define FILE_DELIM "\\" +#else +# define FILE_DELIM "/" /* FIXME: move to better location */ +#endif + +FILE *surf_fopen(const char *name, const char *mode) +{ + unsigned int cpt; + char *path_elm = NULL; + char *buff; + FILE *file = NULL; + + xbt_assert(name); + + if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */ + return fopen(name, mode); + + /* search relative files in the path */ + xbt_dynar_foreach(surf_path, cpt, path_elm) { + buff = bprintf("%s" FILE_DELIM "%s", path_elm, name); + file = fopen(buff, mode); + free(buff); + + if (file) + return file; + } + return NULL; +} + +/* + * Returns the initial path. On Windows the initial path is + * the current directory for the current process in the other + * case the function returns "./" that represents the current + * directory on Unix/Linux platforms. + */ + +const char *__surf_get_initial_path(void) +{ + +#ifdef _XBT_WIN32 + unsigned i; + char current_directory[MAX_PATH + 1] = { 0 }; + unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory); + char root[4] = { 0 }; + + if (!len) + return NULL; + + strncpy(root, current_directory, 3); + + for (i = 0; i < MAX_DRIVE; i++) { + if (toupper(root[0]) == disk_drives_letter_table[i][0]) + return disk_drives_letter_table[i]; + } + + return NULL; +#else + return "./"; +#endif +} + +/* The __surf_is_absolute_file_path() returns 1 if + * file_path is a absolute file path, in the other + * case the function returns 0. + */ +int __surf_is_absolute_file_path(const char *file_path) +{ +#ifdef _XBT_WIN32 + WIN32_FIND_DATA wfd = { 0 }; + HANDLE hFile = FindFirstFile(file_path, &wfd); + + if (INVALID_HANDLE_VALUE == hFile) + return 0; + + FindClose(hFile); + return 1; +#else + return (file_path[0] == '/'); +#endif +} + +/** Displays the long description of all registered models, and quit */ +void model_help(const char *category, s_surf_model_description_t * table) +{ + int i; + printf("Long description of the %s models accepted by this simulator:\n", + category); + for (i = 0; table[i].name; i++) + printf(" %s: %s\n", table[i].name, table[i].description); +} + +int find_model_description(s_surf_model_description_t * table, + const char *name) +{ + int i; + char *name_list = NULL; + + for (i = 0; table[i].name; i++) + if (!strcmp(name, table[i].name)) { + return i; + } + name_list = strdup(table[0].name); + for (i = 1; table[i].name; i++) { + name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3); + strcat(name_list, ", "); + strcat(name_list, table[i].name); + } + xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list); + return -1; +} + +static XBT_INLINE void routing_asr_host_free(void *p) +{ + delete ((RoutingEdgePtr) p); +} + +static XBT_INLINE void routing_asr_prop_free(void *p) +{ + xbt_dict_t elm = (xbt_dict_t) p; + xbt_dict_free(&elm); +} + +static XBT_INLINE void surf_cpu_free(void *r) +{ + delete dynamic_cast(static_cast(r)); +} + +static XBT_INLINE void surf_link_free(void *r) +{ + delete dynamic_cast(static_cast(r)); +} + +static XBT_INLINE void surf_workstation_free(void *r) +{ + delete dynamic_cast(static_cast(r)); +} + + +void sg_version(int *ver_major,int *ver_minor,int *ver_patch) { + *ver_major = SIMGRID_VERSION_MAJOR; + *ver_minor = SIMGRID_VERSION_MINOR; + *ver_patch = SIMGRID_VERSION_PATCH; +} + +void surf_init(int *argc, char **argv) +{ + XBT_DEBUG("Create all Libs"); + host_lib = xbt_lib_new(); + link_lib = xbt_lib_new(); + as_router_lib = xbt_lib_new(); + storage_lib = xbt_lib_new(); + storage_type_lib = xbt_lib_new(); - watched_hosts_lib = xbt_dict_new(); ++ watched_hosts_lib = xbt_dict_new_homogeneous(NULL); + + XBT_DEBUG("Add routing levels"); + ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free); + ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free); + ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free); + + XBT_DEBUG("Add SURF levels"); + SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free); + SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free); + SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free); + + xbt_init(argc, argv); + if (!model_list) + model_list = xbt_dynar_new(sizeof(surf_model_private_t), NULL); + if (!history) + history = tmgr_history_new(); + +#ifdef HAVE_TRACING + TRACE_add_start_function(TRACE_surf_alloc); + TRACE_add_end_function(TRACE_surf_release); +#endif + + sg_config_init(argc, argv); + + surf_action_init(); + if (MC_is_active()) + MC_memory_init(); +} + +void surf_exit(void) +{ + unsigned int iter; + ModelPtr model = NULL; + ++#ifdef HAVE_TRACING ++ TRACE_end(); /* Just in case it was not called by the upper ++ * layer (or there is no upper layer) */ ++#endif ++ + sg_config_finalize(); + + xbt_dynar_foreach(model_list, iter, model) + delete model; + xbt_dynar_free(&model_list); + routing_exit(); + + if (maxmin_system) { + lmm_system_free(maxmin_system); + maxmin_system = NULL; + } + if (history) { + tmgr_history_free(history); + history = NULL; + } + surf_action_exit(); + +#ifdef CONTEXT_THREADS + xbt_parmap_destroy(surf_parmap); + xbt_free(surf_mins); + surf_mins = NULL; +#endif - ++ xbt_dynar_free(&host_that_restart); + xbt_dynar_free(&surf_path); + + xbt_lib_free(&host_lib); + xbt_lib_free(&link_lib); + xbt_lib_free(&as_router_lib); + xbt_lib_free(&storage_lib); + xbt_lib_free(&storage_type_lib); + + xbt_dict_free(&watched_hosts_lib); + + tmgr_finalize(); + surf_parse_lex_destroy(); + surf_parse_free_callbacks(); + + NOW = 0; /* Just in case the user plans to restart the simulation afterward */ +} +/********* + * Model * + *********/ + +Model::Model(string name) + : m_name(name), m_resOnCB(0), m_resOffCB(0), + m_actSuspendCB(0), m_actCancelCB(0), m_actResumeCB(0), + p_maxminSystem(0) +{ + ActionPtr action; + p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup)); + p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup)); + p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup)); + p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup)); + + p_modifiedSet = NULL; + p_actionHeap = NULL; + p_updateMechanism = UM_UNDEFINED; + m_selectiveUpdate = 0; +} + +Model::~Model(){ +xbt_swag_free(p_readyActionSet); +xbt_swag_free(p_runningActionSet); +xbt_swag_free(p_failedActionSet); +xbt_swag_free(p_doneActionSet); +} + +double Model::shareResources(double now) +{ + //FIXME: set the good function once and for all + if (p_updateMechanism == UM_LAZY) + return shareResourcesLazy(now); + else if (p_updateMechanism == UM_FULL) + return shareResourcesFull(now); + else + xbt_die("Invalid cpu update mechanism!"); +} + +double Model::shareResourcesLazy(double now) +{ + ActionLmmPtr action = NULL; + double min = -1; + double value; + + XBT_DEBUG + ("Before share resources, the size of modified actions set is %d", + xbt_swag_size(p_modifiedSet)); + + lmm_solve(p_maxminSystem); + + XBT_DEBUG + ("After share resources, The size of modified actions set is %d", + xbt_swag_size(p_modifiedSet)); + + while((action = static_cast(xbt_swag_extract(p_modifiedSet)))) { + int max_dur_flag = 0; + + if (action->p_stateSet != p_runningActionSet) + continue; + + /* bogus priority, skip it */ + if (action->m_priority <= 0) + continue; + + action->updateRemainingLazy(now); + + min = -1; + value = lmm_variable_getvalue(action->p_variable); + if (value > 0) { + if (action->m_remains > 0) { + value = action->m_remains / value; + min = now + value; + } else { + value = 0.0; + min = now; + } + } + + if ((action->m_maxDuration != NO_MAX_DURATION) + && (min == -1 + || action->m_start + + action->m_maxDuration < min)) { + min = action->m_start + + action->m_maxDuration; + max_dur_flag = 1; + } + + XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action, + action->m_start, now + value, + action->m_maxDuration); + + if (min != -1) { + action->heapRemove(p_actionHeap); + action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL); + XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min, + now); + } else DIE_IMPOSSIBLE; + } + + //hereafter must have already the min value for this resource model + if (xbt_heap_size(p_actionHeap) > 0) + min = xbt_heap_maxkey(p_actionHeap) - now; + else + min = -1; + + XBT_DEBUG("The minimum with the HEAP %lf", min); + + return min; +} + +double Model::shareResourcesFull(double now) { + THROW_UNIMPLEMENTED; +} + + +double Model::shareResourcesMaxMin(xbt_swag_t running_actions, + lmm_system_t sys, + void (*solve) (lmm_system_t)) +{ + void *_action = NULL; + ActionLmmPtr action = NULL; + double min = -1; + double value = -1; + + solve(sys); + + xbt_swag_foreach(_action, running_actions) { + action = dynamic_cast(static_cast(_action)); + value = lmm_variable_getvalue(action->p_variable); + if ((value > 0) || (action->m_maxDuration >= 0)) + break; + } + + if (!_action) + return -1.0; + + if (value > 0) { + if (action->m_remains > 0) + min = action->m_remains / value; + else + min = 0.0; + if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) + min = action->m_maxDuration; + } else + min = action->m_maxDuration; + + + for (_action = xbt_swag_getNext(static_cast(action), running_actions->offset); + _action; + _action = xbt_swag_getNext(static_cast(action), running_actions->offset)) { + action = dynamic_cast(static_cast(_action)); + value = lmm_variable_getvalue(action->p_variable); + if (value > 0) { + if (action->m_remains > 0) + value = action->m_remains / value; + else + value = 0.0; + if (value < min) { + min = value; + XBT_DEBUG("Updating min (value) with %p: %f", action, min); + } + } + if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) { + min = action->m_maxDuration; + XBT_DEBUG("Updating min (duration) with %p: %f", action, min); + } + } + XBT_DEBUG("min value : %f", min); + + return min; +} + +void Model::updateActionsState(double now, double delta) +{ + if (p_updateMechanism == UM_FULL) + updateActionsStateFull(now, delta); + else if (p_updateMechanism == UM_LAZY) + updateActionsStateLazy(now, delta); + else + xbt_die("Invalid cpu update mechanism!"); +} + +void Model::updateActionsStateLazy(double now, double delta) +{ + +} + +void Model::updateActionsStateFull(double now, double delta) +{ + +} + + +void Model::addTurnedOnCallback(ResourceCallback rc) +{ + m_resOnCB = rc; +} + +void Model::notifyResourceTurnedOn(ResourcePtr r) +{ + m_resOnCB(r); +} + +void Model::addTurnedOffCallback(ResourceCallback rc) +{ + m_resOffCB = rc; +} + +void Model::notifyResourceTurnedOff(ResourcePtr r) +{ + m_resOffCB(r); +} + +void Model::addActionCancelCallback(ActionCallback ac) +{ + m_actCancelCB = ac; +} + +void Model::notifyActionCancel(ActionPtr a) +{ + m_actCancelCB(a); +} + +void Model::addActionResumeCallback(ActionCallback ac) +{ + m_actResumeCB = ac; +} + +void Model::notifyActionResume(ActionPtr a) +{ + m_actResumeCB(a); +} + +void Model::addActionSuspendCallback(ActionCallback ac) +{ + m_actSuspendCB = ac; +} + +void Model::notifyActionSuspend(ActionPtr a) +{ + m_actSuspendCB(a); +} + + +/************ + * Resource * + ************/ + +Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props) + : m_name(xbt_strdup(name)), m_running(true), p_model(model), m_properties(props) +{} + +Resource::Resource(){ + //FIXME:free(m_name); + //FIXME:xbt_dict_free(&m_properties); +} + +const char *Resource::getName() +{ + return m_name; +} + +xbt_dict_t Resource::getProperties() +{ + return m_properties; +} + +e_surf_resource_state_t Resource::getState() +{ + return p_stateCurrent; +} + +bool Resource::isOn() +{ + return m_running; +} + +void Resource::turnOn() +{ + if (!m_running) { + m_running = true; + p_model->notifyResourceTurnedOn(this); + } +} + +void Resource::turnOff() +{ + if (m_running) { + m_running = false; + p_model->notifyResourceTurnedOff(this); + } +} + +ResourceLmm::ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props, + lmm_system_t system, + double constraint_value, + tmgr_history_t history, + e_surf_resource_state_t state_init, + tmgr_trace_t state_trace, + double metric_peak, + tmgr_trace_t metric_trace) + : Resource(model, name, props) +{ + p_constraint = lmm_constraint_new(system, this, constraint_value); + p_stateCurrent = state_init; + if (state_trace) + p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast(this)); + p_power.scale = 1.0; + p_power.peak = metric_peak; + if (metric_trace) + p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast(this)); +} + +/********** + * Action * + **********/ + +const char *surf_action_state_names[6] = { + "SURF_ACTION_READY", + "SURF_ACTION_RUNNING", + "SURF_ACTION_FAILED", + "SURF_ACTION_DONE", + "SURF_ACTION_TO_FREE", + "SURF_ACTION_NOT_IN_THE_SYSTEM" +}; + +/** + * \brief Initializes the action module of Surf. + */ +void surf_action_init(void) { + + /* the action mallocator will always provide actions of the following size, + * so this size should be set to the maximum size of the surf action structures + */ + /*FIXME:action_mallocator_allocated_size = sizeof(s_surf_action_network_CM02_t); + action_mallocator = xbt_mallocator_new(65536, surf_action_mallocator_new_f, + surf_action_mallocator_free_f, surf_action_mallocator_reset_f);*/ +} + +/** + * \brief Uninitializes the action module of Surf. + */ +void surf_action_exit(void) { + //FIXME:xbt_mallocator_free(action_mallocator); +} + +Action::Action(){} + +Action::Action(ModelPtr model, double cost, bool failed): + m_cost(cost), p_model(model), m_failed(failed), m_remains(cost), + m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION), + m_start(surf_get_clock()), m_finish(-1.0) +{ + #ifdef HAVE_TRACING + p_category = NULL; + #endif + p_stateHookup.prev = 0; + p_stateHookup.next = 0; + if (failed) + p_stateSet = p_model->p_failedActionSet; + else + p_stateSet = p_model->p_runningActionSet; + + xbt_swag_insert(this, p_stateSet); +} + +Action::~Action() {} + +int Action::unref(){ + DIE_IMPOSSIBLE; +} + +void Action::cancel(){ + DIE_IMPOSSIBLE; +} + +void Action::recycle(){ + DIE_IMPOSSIBLE; +} + +e_surf_action_state_t Action::getState() +{ + if (p_stateSet == p_model->p_readyActionSet) + return SURF_ACTION_READY; + if (p_stateSet == p_model->p_runningActionSet) + return SURF_ACTION_RUNNING; + if (p_stateSet == p_model->p_failedActionSet) + return SURF_ACTION_FAILED; + if (p_stateSet == p_model->p_doneActionSet) + return SURF_ACTION_DONE; + return SURF_ACTION_NOT_IN_THE_SYSTEM; +} + +void Action::setState(e_surf_action_state_t state) +{ + //surf_action_state_t action_state = &(action->model_type->states); + XBT_IN("(%p,%s)", this, surf_action_state_names[state]); + xbt_swag_remove(this, p_stateSet); + + if (state == SURF_ACTION_READY) + p_stateSet = p_model->p_readyActionSet; + else if (state == SURF_ACTION_RUNNING) + p_stateSet = p_model->p_runningActionSet; + else if (state == SURF_ACTION_FAILED) + p_stateSet = p_model->p_failedActionSet; + else if (state == SURF_ACTION_DONE) + p_stateSet = p_model->p_doneActionSet; + else + p_stateSet = NULL; + + if (p_stateSet) + xbt_swag_insert(this, p_stateSet); + XBT_OUT(); +} + +double Action::getStartTime() +{ + return m_start; +} + +double Action::getFinishTime() +{ + /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */ + return m_remains == 0 ? m_finish : -1; +} + +double Action::getRemains() +{ + XBT_IN("(%p)", this); + XBT_OUT(); + return m_remains; +} + +void Action::setData(void* data) +{ + p_data = data; +} + +#ifdef HAVE_TRACING +void Action::setCategory(const char *category) +{ + XBT_IN("(%p,%s)", this, category); + p_category = xbt_strdup(category); + XBT_OUT(); +} +#endif + +void Action::ref(){ + m_refcount++; +} + +void ActionLmm::setMaxDuration(double duration) +{ + XBT_IN("(%p,%g)", this, duration); + m_maxDuration = duration; + if (p_model->p_updateMechanism == UM_LAZY) // remove action from the heap + heapRemove(p_model->p_actionHeap); + XBT_OUT(); +} + +void ActionLmm::gapRemove() {} + +void ActionLmm::setPriority(double priority) +{ + XBT_IN("(%p,%g)", this, priority); + m_priority = priority; + lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, priority); + + if (p_model->p_updateMechanism == UM_LAZY) + heapRemove(p_model->p_actionHeap); + XBT_OUT(); +} + +void ActionLmm::cancel(){ + setState(SURF_ACTION_FAILED); + if (p_model->p_updateMechanism == UM_LAZY) { + xbt_swag_remove(this, p_model->p_modifiedSet); + heapRemove(p_model->p_actionHeap); + } +} + +int ActionLmm::unref(){ + m_refcount--; + if (!m_refcount) { + xbt_swag_remove(static_cast(this), p_stateSet); + if (p_variable) + lmm_variable_free(p_model->p_maxminSystem, p_variable); + if (p_model->p_updateMechanism == UM_LAZY) { + /* remove from heap */ + heapRemove(p_model->p_actionHeap); + xbt_swag_remove(this, p_model->p_modifiedSet); + } +#ifdef HAVE_TRACING + xbt_free(p_category); +#endif + delete this; + return 1; + } + return 0; +} + +void ActionLmm::suspend() +{ + XBT_IN("(%p)", this); + if (m_suspended != 2) { + lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0); + m_suspended = 1; + if (p_model->p_updateMechanism == UM_LAZY) + heapRemove(p_model->p_actionHeap); + } + XBT_OUT(); +} + +void ActionLmm::resume() +{ + XBT_IN("(%p)", this); + if (m_suspended != 2) { + lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority); + m_suspended = 0; + if (p_model->p_updateMechanism == UM_LAZY) + heapRemove(p_model->p_actionHeap); + } + XBT_OUT(); +} + +bool ActionLmm::isSuspended() +{ + return m_suspended == 1; +} +/* insert action on heap using a given key and a hat (heap_action_type) + * a hat can be of three types for communications: + * + * NORMAL = this is a normal heap entry stating the date to finish transmitting + * LATENCY = this is a heap entry to warn us when the latency is payed + * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached + */ +void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat) +{ + m_hat = hat; + xbt_heap_push(heap, this, key); +} + +void ActionLmm::heapRemove(xbt_heap_t heap) +{ + m_hat = NOTSET; + if (m_indexHeap >= 0) { + xbt_heap_remove(heap, m_indexHeap); + } +} + +/* added to manage the communication action's heap */ +void surf_action_lmm_update_index_heap(void *action, int i) { + ((ActionLmmPtr)action)->updateIndexHeap(i); +} + +void ActionLmm::updateIndexHeap(int i) { + m_indexHeap = i; +} + +double ActionLmm::getRemains() +{ + XBT_IN("(%p)", this); + /* update remains before return it */ + if (p_model->p_updateMechanism == UM_LAZY) /* update remains before return it */ + updateRemainingLazy(surf_get_clock()); + XBT_OUT(); + return m_remains; +} + +//FIXME split code in the right places +void ActionLmm::updateRemainingLazy(double now) +{ + double delta = 0.0; + + if(p_model == static_cast(surf_network_model)) + { + if (m_suspended != 0) + return; + } + else + { + xbt_assert(p_stateSet == p_model->p_runningActionSet, + "You're updating an action that is not running."); + + /* bogus priority, skip it */ + xbt_assert(m_priority > 0, + "You're updating an action that seems suspended."); + } + + delta = now - m_lastUpdate; + + if (m_remains > 0) { - XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate); ++ XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate); + double_update(&m_remains, m_lastValue * delta); + +#ifdef HAVE_TRACING + if (p_model == static_cast(surf_cpu_model) && TRACE_is_enabled()) { + ResourcePtr cpu = static_cast(lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0))); + TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate); + } +#endif - XBT_DEBUG("Updating action(%p): remains is now %lf", this, m_remains); ++ XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains); + } + + if(p_model == static_cast(surf_network_model)) + { + if (m_maxDuration != NO_MAX_DURATION) + double_update(&m_maxDuration, delta); + + //FIXME: duplicated code + if ((m_remains <= 0) && + (lmm_get_variable_weight(p_variable) > 0)) { + m_finish = surf_get_clock(); + setState(SURF_ACTION_DONE); + heapRemove(p_model->p_actionHeap); + } else if (((m_maxDuration != NO_MAX_DURATION) + && (m_maxDuration <= 0))) { + m_finish = surf_get_clock(); + setState(SURF_ACTION_DONE); + heapRemove(p_model->p_actionHeap); + } + } + + m_lastUpdate = now; + m_lastValue = lmm_variable_getvalue(p_variable); +} + +/*void Action::cancel() +{ + p_model->notifyActionCancel(this); +} + +void Action::suspend() +{ + p_model->notifyActionSuspend(this); +} + +void Action::resume() +{ + p_model->notifyActionResume(this); +} + +bool Action::isSuspended() +{ + return false; +}*/ + diff --cc src/surf/surf.hpp index 862173d4cf,0000000000..874acdddf0 mode 100644,000000..100644 --- a/src/surf/surf.hpp +++ b/src/surf/surf.hpp @@@ -1,331 -1,0 +1,330 @@@ +//using namespace generic; + +#ifndef SURF_MODEL_H_ +#define SURF_MODEL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "surf/trace_mgr.h" +#include "xbt/lib.h" +#include "surf/surf_routing.h" +#include "simgrid/platf_interface.h" +#include "surf/surf.h" +#include "surf/surf_private.h" + +extern tmgr_history_t history; +#define NO_MAX_DURATION -1.0 + +using namespace std; + +/** \ingroup SURF_simulation + * \brief Return the current time + * + * Return the current time in millisecond. + */ + +/********* + * Utils * + *********/ + +/* user-visible parameters */ +extern double sg_tcp_gamma; +extern double sg_sender_gap; +extern double sg_latency_factor; +extern double sg_bandwidth_factor; +extern double sg_weight_S_parameter; +extern int sg_network_crosstraffic; +#ifdef HAVE_GTNETS +extern double sg_gtnets_jitter; +extern int sg_gtnets_jitter_seed; +#endif +extern xbt_dynar_t surf_path; + +#ifdef __cplusplus +extern "C" { +#endif +XBT_PUBLIC(double) surf_get_clock(void); - XBT_PUBLIC(void) surf_watched_hosts(void); +#ifdef __cplusplus +} +#endif + +extern double sg_sender_gap; +XBT_PUBLIC(int) SURF_CPU_LEVEL; //Surf cpu level + +int __surf_is_absolute_file_path(const char *file_path); + +/*********** + * Classes * + ***********/ +//class Model; +typedef Model* ModelPtr; + +//class Resource; +typedef Resource* ResourcePtr; +typedef boost::function ResourceCallback; + +//class Action; +typedef Action* ActionPtr; +typedef boost::function ActionCallback; + +//class ActionLmm; +typedef ActionLmm* ActionLmmPtr; + +enum heap_action_type{ + LATENCY = 100, + MAX_DURATION, + NORMAL, + NOTSET +}; + +/********* + * Trace * + *********/ +/* For the trace and trace:connect tag (store their content till the end of the parsing) */ +XBT_PUBLIC_DATA(xbt_dict_t) traces_set_list; +XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_host_avail; +XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_power; +XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_link_avail; +XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_bandwidth; +XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_latency; + + +/********* + * Model * + *********/ +XBT_PUBLIC_DATA(xbt_dynar_t) model_list; + +class Model { +public: + Model(string name); + virtual ~Model(); + + ResourcePtr createResource(string name); + ActionPtr createAction(double _cost, bool _failed); + virtual double shareResources(double now); + virtual double shareResourcesLazy(double now); + virtual double shareResourcesFull(double now); + double shareResourcesMaxMin(xbt_swag_t running_actions, + lmm_system_t sys, + void (*solve) (lmm_system_t)); + virtual void updateActionsState(double now, double delta); + virtual void updateActionsStateLazy(double now, double delta); + virtual void updateActionsStateFull(double now, double delta); + + string getName() {return m_name;}; + + void addTurnedOnCallback(ResourceCallback rc); + void notifyResourceTurnedOn(ResourcePtr r); + + void addTurnedOffCallback(ResourceCallback rc); + void notifyResourceTurnedOff(ResourcePtr r); + + void addActionCancelCallback(ActionCallback ac); + void notifyActionCancel(ActionPtr a); + void addActionResumeCallback(ActionCallback ac); + void notifyActionResume(ActionPtr a); + void addActionSuspendCallback(ActionCallback ac); + void notifyActionSuspend(ActionPtr a); + + lmm_system_t p_maxminSystem; + e_UM_t p_updateMechanism; + xbt_swag_t p_modifiedSet; + xbt_heap_t p_actionHeap; + int m_selectiveUpdate; + + xbt_swag_t p_readyActionSet; /**< Actions in state SURF_ACTION_READY */ + xbt_swag_t p_runningActionSet; /**< Actions in state SURF_ACTION_RUNNING */ + xbt_swag_t p_failedActionSet; /**< Actions in state SURF_ACTION_FAILED */ + xbt_swag_t p_doneActionSet; /**< Actions in state SURF_ACTION_DONE */ + string m_name; + +protected: + std::vector m_failedActions, m_runningActions; + +private: + ResourceCallback m_resOnCB, m_resOffCB; + ActionCallback m_actCancelCB, m_actSuspendCB, m_actResumeCB; +}; + +/************ + * Resource * + ************/ + +/** + * Resource which have a metric handled by a maxmin system + */ +typedef struct { + double scale; + double peak; + tmgr_trace_event_t event; +} s_surf_metric_t; + +class Resource { +public: + Resource(); + Resource(ModelPtr model, const char *name, xbt_dict_t properties); + virtual ~Resource() {}; + + virtual void updateState(tmgr_trace_event_t event_type, double value, double date)=0; + + //private + virtual bool isUsed()=0; + //FIXME:updateActionState(); + //FIXME:updateResourceState(); + //FIXME:finilize(); + + bool isOn(); + void turnOn(); + void turnOff(); + void setName(string name); + const char *getName(); + virtual xbt_dict_t getProperties(); + + ModelPtr getModel() {return p_model;}; + virtual e_surf_resource_state_t getState(); + void printModel() { std::cout << p_model->getName() << "<(static_cast(surf_cpu_resource_priv(resource))); +} + +static WorkstationCLM03Ptr get_casted_workstation(surf_resource_t resource){ + return dynamic_cast(static_cast(surf_workstation_resource_priv(resource))); +} + +char *surf_routing_edge_name(sg_routing_edge_t edge){ + return edge->p_name; +} + +#ifdef CONTEXT_THREADS +static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */ +#endif + +static double *surf_mins = NULL; /* return value of share_resources for each model */ +static int surf_min_index; /* current index in surf_mins */ +static double surf_min; /* duration determined by surf_solve */ + +void surf_presolve(void) +{ + double next_event_date = -1.0; + tmgr_trace_event_t event = NULL; + double value = -1.0; + ResourcePtr resource = NULL; + ModelPtr model = NULL; + unsigned int iter; + + XBT_DEBUG + ("First Run! Let's \"purge\" events and put models in the right state"); + while ((next_event_date = tmgr_history_next_date(history)) != -1.0) { + if (next_event_date > NOW) + break; + while ((event = + tmgr_history_get_next_event_leq(history, next_event_date, + &value, + (void **) &resource))) { + if (value >= 0){ + resource->updateState(event, value, NOW); + } + } + } + xbt_dynar_foreach(model_list, iter, model) + model->updateActionsState(NOW, 0.0); +} + +static void surf_share_resources(surf_model_t model) +{ + double next_action_end = -1.0; + int i = __sync_fetch_and_add(&surf_min_index, 1); + if (strcmp(model->m_name.c_str(), "network NS3")) { + XBT_DEBUG("Running for Resource [%s]", model->m_name.c_str()); + next_action_end = model->shareResources(NOW); + XBT_DEBUG("Resource [%s] : next action end = %f", + model->m_name.c_str(), next_action_end); + } + surf_mins[i] = next_action_end; +} + +static void surf_update_actions_state(surf_model_t model) +{ + model->updateActionsState(NOW, surf_min); +} + +double surf_solve(double max_date) +{ + surf_min = -1.0; /* duration */ + double next_event_date = -1.0; + double model_next_action_end = -1.0; + double value = -1.0; + ResourcePtr resource = NULL; + ModelPtr model = NULL; + tmgr_trace_event_t event = NULL; + unsigned int iter; + ++ if(!host_that_restart) ++ host_that_restart = xbt_dynar_new(sizeof(char*), NULL); ++ + if (max_date != -1.0 && max_date != NOW) { + surf_min = max_date - NOW; + } + + XBT_DEBUG("Looking for next action end for all models except NS3"); + + if (surf_mins == NULL) { + surf_mins = xbt_new(double, xbt_dynar_length(model_list)); + } + surf_min_index = 0; + + /* sequential version */ + xbt_dynar_foreach(model_list, iter, model) { + surf_share_resources(static_cast(model)); + } + + unsigned i; + for (i = 0; i < xbt_dynar_length(model_list); i++) { + if ((surf_min < 0.0 || surf_mins[i] < surf_min) + && surf_mins[i] >= 0.0) { + surf_min = surf_mins[i]; + } + } + + XBT_DEBUG("Min for resources (remember that NS3 don't update that value) : %f", surf_min); + + XBT_DEBUG("Looking for next trace event"); + + do { + XBT_DEBUG("Next TRACE event : %f", next_event_date); + + next_event_date = tmgr_history_next_date(history); + + if(!strcmp(surf_network_model->m_name.c_str(), "network NS3")){//FIXME: add surf_network_model->m_name && + if(next_event_date!=-1.0 && surf_min!=-1.0) { + surf_min = MIN(next_event_date - NOW, surf_min); + } else{ + surf_min = MAX(next_event_date - NOW, surf_min); + } + + XBT_DEBUG("Run for network at most %f", surf_min); + // run until min or next flow + model_next_action_end = surf_network_model->shareResources(surf_min); + + XBT_DEBUG("Min for network : %f", model_next_action_end); + if(model_next_action_end>=0.0) + surf_min = model_next_action_end; + } + + if (next_event_date < 0.0) { + XBT_DEBUG("no next TRACE event. Stop searching for it"); + break; + } + + if ((surf_min == -1.0) || (next_event_date > NOW + surf_min)) break; + + XBT_DEBUG("Updating models (min = %g, NOW = %g, next_event_date = %g)", surf_min, NOW, next_event_date); + while ((event = + tmgr_history_get_next_event_leq(history, next_event_date, + &value, + (void **) &resource))) { - if (resource->isUsed()) { ++ if (resource->isUsed() || xbt_dict_get_or_null(watched_hosts_lib, resource->m_name)) { + surf_min = next_event_date - NOW; + XBT_DEBUG + ("This event will modify model state. Next event set to %f", + surf_min); + } + /* update state of model_obj according to new value. Does not touch lmm. + It will be modified if needed when updating actions */ + XBT_DEBUG("Calling update_resource_state for resource %s with min %lf", - resource->p_model->m_name.c_str(), surf_min); ++ resource->m_name, surf_min); + resource->updateState(event, value, next_event_date); + } + } while (1); + + /* FIXME: Moved this test to here to avoid stopping simulation if there are actions running on cpus and all cpus are with availability = 0. + * This may cause an infinite loop if one cpu has a trace with periodicity = 0 and the other a trace with periodicity > 0. + * The options are: all traces with same periodicity(0 or >0) or we need to change the way how the events are managed */ + if (surf_min == -1.0) { + XBT_DEBUG("No next event at all. Bail out now."); + return -1.0; + } + + XBT_DEBUG("Duration set to %f", surf_min); + + NOW = NOW + surf_min; + + /* sequential version */ + xbt_dynar_foreach(model_list, iter, model) { + surf_update_actions_state(model); + } + +#ifdef HAVE_TRACING + TRACE_paje_dump_buffer (0); +#endif + + return surf_min; +} + +XBT_INLINE double surf_get_clock(void) +{ + return NOW; +} + +void routing_get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst, + xbt_dynar_t * route, double *latency){ + routing_platf->getRouteAndLatency(src, dst, route, latency); +} + +/********* + * MODEL * + *********/ + +void *surf_as_cluster_get_backbone(AS_t as){ + return static_cast(as)->p_backbone; +} + +void surf_as_cluster_set_backbone(AS_t as, void* backbone){ + static_cast(as)->p_backbone = dynamic_cast(static_cast(backbone)); +} + +const char *surf_model_name(surf_model_t model){ + return model->m_name.c_str(); +} + +xbt_swag_t surf_model_done_action_set(surf_model_t model){ + return model->p_doneActionSet; +} + +xbt_swag_t surf_model_failed_action_set(surf_model_t model){ + return model->p_failedActionSet; +} + +xbt_swag_t surf_model_ready_action_set(surf_model_t model){ + return model->p_readyActionSet; +} + +xbt_swag_t surf_model_running_action_set(surf_model_t model){ + return model->p_runningActionSet; +} + +surf_action_t surf_workstation_model_execute_parallel_task(surf_workstation_model_t model, + int workstation_nb, + void **workstation_list, + double *computation_amount, + double *communication_amount, + double rate){ + return static_cast(model->executeParallelTask(workstation_nb, workstation_list, computation_amount, communication_amount, rate)); +} + +surf_action_t surf_workstation_model_communicate(surf_workstation_model_t model, surf_resource_t src, surf_resource_t dst, double size, double rate){ + return model->communicate(get_casted_workstation(src), get_casted_workstation(dst), size, rate); +} + +xbt_dynar_t surf_workstation_model_get_route(surf_workstation_model_t model, + surf_resource_t src, surf_resource_t dst){ + return model->getRoute(get_casted_workstation(src), get_casted_workstation(dst)); +} + +surf_action_t surf_network_model_communicate(surf_network_model_t model, sg_routing_edge_t src, sg_routing_edge_t dst, double size, double rate){ + return model->communicate(src, dst, size, rate); +} + +const char *surf_resource_name(surf_cpp_resource_t resource){ + return resource->m_name; +} + +xbt_dict_t surf_resource_get_properties(surf_cpp_resource_t resource){ + return resource->getProperties(); +} + +e_surf_resource_state_t surf_resource_get_state(surf_cpp_resource_t resource){ + return resource->getState(); +} + +surf_action_t surf_workstation_sleep(surf_resource_t resource, double duration){ + return get_casted_workstation(resource)->sleep(duration); +} + +double surf_workstation_get_speed(surf_resource_t resource, double load){ + return get_casted_workstation(resource)->getSpeed(load); +} + +double surf_workstation_get_available_speed(surf_resource_t resource){ + return get_casted_workstation(resource)->getAvailableSpeed(); +} + +int surf_workstation_get_core(surf_resource_t resource){ + return get_casted_workstation(resource)->getCore(); +} + +surf_action_t surf_workstation_execute(surf_resource_t resource, double size){ + return get_casted_workstation(resource)->execute(size); +} + ++double surf_workstation_get_current_power_peak(surf_resource_t resource){ ++ return get_casted_workstation(resource)->getCurrentPowerPeak(); ++} ++ ++double surf_workstation_get_power_peak_at(surf_resource_t resource, int pstate_index){ ++ return get_casted_workstation(resource)->getPowerPeakAt(pstate_index); ++} ++ ++int surf_workstation_get_nb_pstates(surf_resource_t resource){ ++ return get_casted_workstation(resource)->getNbPstates(); ++} ++ ++void surf_workstation_set_power_peak_at(surf_resource_t resource, int pstate_index){ ++ return get_casted_workstation(resource)->setPowerPeakAt(pstate_index); ++} ++ ++double surf_workstation_get_consumed_energy(surf_resource_t resource){ ++ return get_casted_workstation(resource)->getConsumedEnergy(); ++} ++ ++xbt_dict_t surf_workstation_get_storage_list(surf_resource_t workstation){ ++ return get_casted_workstation(workstation)->getStorageList(); ++} +surf_action_t surf_workstation_open(surf_resource_t workstation, const char* mount, const char* path){ + return get_casted_workstation(workstation)->open(mount, path); +} + +surf_action_t surf_workstation_close(surf_resource_t workstation, surf_file_t fd){ + return get_casted_workstation(workstation)->close(fd); +} + +int surf_workstation_unlink(surf_resource_t workstation, surf_file_t fd){ + return get_casted_workstation(workstation)->unlink(fd); +} + +surf_action_t surf_workstation_ls(surf_resource_t workstation, const char* mount, const char *path){ + return get_casted_workstation(workstation)->ls(mount, path); +} + +size_t surf_workstation_get_size(surf_resource_t workstation, surf_file_t fd){ + return get_casted_workstation(workstation)->getSize(fd); +} + - surf_action_t surf_workstation_read(surf_resource_t resource, void *ptr, size_t size, surf_file_t fd){ - return get_casted_workstation(resource)->read(ptr, size, fd); ++surf_action_t surf_workstation_read(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size){ ++ return get_casted_workstation(resource)->read(fd, size); ++} ++ ++surf_action_t surf_workstation_write(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size){ ++ return get_casted_workstation(resource)->write(fd, size); ++} ++ ++xbt_dynar_t surf_workstation_get_info(surf_resource_t resource, surf_file_t fd){ ++ return get_casted_workstation(resource)->getInfo(fd); +} + - surf_action_t surf_workstation_write(surf_resource_t resource, const void *ptr, size_t size, surf_file_t fd){ - return get_casted_workstation(resource)->write(ptr, size, fd); ++sg_storage_size_t surf_workstation_get_free_size(surf_resource_t resource, const char* name){ ++ return get_casted_workstation(resource)->getFreeSize(name); ++} ++sg_storage_size_t surf_workstation_get_used_size(surf_resource_t resource, const char* name){ ++ return get_casted_workstation(resource)->getUsedSize(name); +} + +int surf_network_link_is_shared(surf_cpp_resource_t link){ + return dynamic_cast(link)->isShared(); +} + +double surf_network_link_get_bandwidth(surf_cpp_resource_t link){ + return dynamic_cast(link)->getBandwidth(); +} + +double surf_network_link_get_latency(surf_cpp_resource_t link){ + return dynamic_cast(link)->getLatency(); +} + ++xbt_dict_t surf_storage_get_content(surf_resource_t resource){ ++ return dynamic_cast(static_cast(surf_storage_resource_priv(resource)))->getContent(); ++} ++ ++sg_storage_size_t surf_storage_get_size(surf_resource_t resource){ ++ return dynamic_cast(static_cast(surf_storage_resource_priv(resource)))->getSize(); ++} ++ +surf_action_t surf_cpu_execute(surf_resource_t cpu, double size){ + return get_casted_cpu(cpu)->execute(size); +} + +surf_action_t surf_cpu_sleep(surf_resource_t cpu, double duration){ + return get_casted_cpu(cpu)->sleep(duration); +} + +double surf_action_get_start_time(surf_action_t action){ + return action->m_start; +} + +double surf_action_get_finish_time(surf_action_t action){ + return action->m_finish; +} + +double surf_action_get_remains(surf_action_t action){ + return action->getRemains(); +} + +void surf_action_unref(surf_action_t action){ + action->unref(); +} + +void surf_action_suspend(surf_action_t action){ + action->suspend(); +} + +void surf_action_resume(surf_action_t action){ + action->resume(); +} + +void surf_action_cancel(surf_action_t action){ + action->cancel(); +} + +void surf_action_set_priority(surf_action_t action, double priority){ + action->setPriority(priority); +} + +void surf_action_set_category(surf_action_t action, const char *category){ + action->setCategory(category); +} + +void *surf_action_get_data(surf_action_t action){ + return action->p_data; +} + +void surf_action_set_data(surf_action_t action, void *data){ + action->p_data = data; +} + +e_surf_action_state_t surf_action_get_state(surf_action_t action){ + return action->getState(); +} + +int surf_action_get_cost(surf_action_t action){ + return action->m_cost; +} + +surf_file_t surf_storage_action_get_file(surf_action_t action){ + return dynamic_cast(action)->p_file; +} + +xbt_dict_t surf_storage_action_get_ls_dict(surf_action_t action){ + return dynamic_cast(action)->p_lsDict; +} diff --cc src/surf/surf_routing.cpp index a3a53c4f81,ec7334ff20..d667710c46 --- a/src/surf/surf_routing.cpp +++ b/src/surf/surf_routing.cpp @@@ -1,7 -1,15 +1,16 @@@ -/* Copyright (c) 2009-2013. The SimGrid Team. ++/* Copyright (c) 2009, 2010, 2011. The SimGrid Team. + * All rights reserved. */ + + /* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "surf_routing.hpp" +#include "surf_routing_private.hpp" ++ + #include "simgrid/platf_interface.h" // platform creation API internal interface + #include "simgrid/sg_config.h" + -#include "surf_routing_private.h" -#include "surf/surf_routing.h" #include "surf/surfxml_parse_values.h" - #include "surf/random_mgr.h" /** * @ingroup SURF_build_api @@@ -999,6 -1011,16 +1018,15 @@@ static void routing_parse_peer(sg_platf XBT_DEBUG(" "); host_id = HOST_PEER(peer->id); link_id = LINK_PEER(peer->id); + router_id = ROUTER_PEER(peer->id); + + XBT_DEBUG("", peer->id); + s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER; + AS.id = peer->id; + AS.routing = A_surfxml_AS_routing_Cluster; + sg_platf_new_AS_begin(&AS); + - current_routing->link_up_down_list - = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL); ++ current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL); XBT_DEBUG("", host_id, peer->power); s_sg_platf_host_cbarg_t host; @@@ -1041,6 -1067,16 +1073,16 @@@ host_link.link_down= link_down; sg_platf_new_host_link(&host_link); + XBT_DEBUG("", router_id); + s_sg_platf_router_cbarg_t router; + memset(&router, 0, sizeof(router)); + router.id = router_id; + router.coord = peer->coord; + sg_platf_new_router(&router); - ((as_cluster_t)current_routing)->router = xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL); ++ static_cast(current_routing)->p_router = static_cast(xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL)); + + XBT_DEBUG(""); + sg_platf_new_AS_end(); XBT_DEBUG(" "); //xbt_dynar_free(&tab_elements_num); diff --cc src/surf/surf_routing_floyd.cpp index 1cfc5c0c89,0c1d32ad9d..16c25651c7 --- a/src/surf/surf_routing_floyd.cpp +++ b/src/surf/surf_routing_floyd.cpp @@@ -1,46 -1,35 +1,52 @@@ + /* Copyright (c) 2009-2013. The SimGrid Team. + * All rights reserved. */ + + /* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + #include "surf_routing_private.h" +#include "surf_routing_floyd.hpp" +#include "network.hpp" -/* Global vars */ -extern routing_platf_t routing_platf; - +extern "C" { XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_floyd, surf, "Routing part of surf"); +} -#define TO_FLOYD_COST(i,j) (as->cost_table)[(i)+(j)*table_size] -#define TO_FLOYD_PRED(i,j) (as->predecessor_table)[(i)+(j)*table_size] -#define TO_FLOYD_LINK(i,j) (as->link_table)[(i)+(j)*table_size] +#define TO_FLOYD_COST(i,j) (p_costTable)[(i)+(j)*table_size] +#define TO_FLOYD_PRED(i,j) (p_predecessorTable)[(i)+(j)*table_size] +#define TO_FLOYD_LINK(i,j) (p_linkTable)[(i)+(j)*table_size] -/* Routing model structure */ +AS_t model_floyd_create(void) +{ + return new AsFloyd(); +} -typedef struct { - s_as_t generic_routing; - /* vars for calculate the floyd algorithm. */ - int *predecessor_table; - double *cost_table; - sg_platf_route_cbarg_t *link_table; -} s_as_floyd_t, *as_floyd_t; +void model_floyd_end(AS_t current_routing) +{ + static_cast(current_routing)->end(); +} -static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_routing_edge_t dst, - sg_platf_route_cbarg_t res, double *lat); +AsFloyd::AsFloyd(): AsGeneric() { +} + +AsFloyd::~AsFloyd(){ + int i, j; + size_t table_size; + table_size = xbt_dynar_length(p_indexNetworkElm); + /* Delete link_table */ + for (i = 0; i < table_size; i++) + for (j = 0; j < table_size; j++) + generic_free_route(TO_FLOYD_LINK(i, j)); + xbt_free(p_linkTable); + /* Delete bypass dict */ + xbt_dict_free(&p_bypassRoutes); + /* Delete predecessor and cost table */ + xbt_free(p_predecessorTable); + xbt_free(p_costTable); +} /* Business methods */ -static xbt_dynar_t floyd_get_onelink_routes(AS_t asg) +xbt_dynar_t AsFloyd::getOneLinkRoutes() { xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free); sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t, 1); diff --cc src/surf/surf_routing_full.cpp index 21338ffc70,89e305fd91..f0767dcdb4 --- a/src/surf/surf_routing_full.cpp +++ b/src/surf/surf_routing_full.cpp @@@ -1,10 -1,10 +1,16 @@@ + /* Copyright (c) 2009-2013. The SimGrid Team. + * All rights reserved. */ + + /* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + #include "surf_routing_private.h" +#include "surf_routing_full.hpp" +#include "network.hpp" + +extern "C" { +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_full, surf, "Routing part of surf"); +} /* Global vars */ extern routing_platf_t routing_platf; diff --cc src/surf/workstation.cpp index 069500c690,0000000000..31aef932a1 mode 100644,000000..100644 --- a/src/surf/workstation.cpp +++ b/src/surf/workstation.cpp @@@ -1,254 -1,0 +1,321 @@@ +#include "workstation.hpp" +#include "simgrid/sg_config.h" + +extern "C" { +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_workstation, surf, + "Logging specific to the SURF workstation module"); +} + +WorkstationModelPtr surf_workstation_model = NULL; + +//FIXME:Faire hériter ou composer de cup et network + +/************* + * CallBacks * + *************/ + +static void workstation_new(sg_platf_host_cbarg_t host){ + surf_workstation_model->createResource(host->id); +} + +/********* + * Model * + *********/ + +void surf_workstation_model_init_current_default(void) +{ + surf_workstation_model = new WorkstationModel(); - xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", xbt_strdup("yes")); ++ xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "yes"); + surf_cpu_model_init_Cas01(); + surf_network_model_init_LegrandVelho(); + + ModelPtr model = static_cast(surf_workstation_model); + xbt_dynar_push(model_list, &model); + sg_platf_host_add_cb(workstation_new); +} + +void surf_workstation_model_init_compound() +{ + + xbt_assert(surf_cpu_model, "No CPU model defined yet!"); + xbt_assert(surf_network_model, "No network model defined yet!"); + surf_workstation_model = new WorkstationModel(); + + ModelPtr model = static_cast(surf_workstation_model); + xbt_dynar_push(model_list, &model); + sg_platf_host_add_cb(workstation_new); +} + +WorkstationModel::WorkstationModel() : Model("Workstation") { +} + +WorkstationModel::~WorkstationModel() { +} + +void WorkstationModel::parseInit(sg_platf_host_cbarg_t host){ + createResource(host->id); +} + +WorkstationCLM03Ptr WorkstationModel::createResource(string name){ + + WorkstationCLM03Ptr workstation = new WorkstationCLM03(surf_workstation_model, name.c_str(), NULL, + (xbt_dynar_t)xbt_lib_get_or_null(storage_lib, name.c_str(), ROUTING_STORAGE_HOST_LEVEL), + (RoutingEdgePtr)xbt_lib_get_or_null(host_lib, name.c_str(), ROUTING_HOST_LEVEL), + dynamic_cast(static_cast(xbt_lib_get_or_null(host_lib, name.c_str(), SURF_CPU_LEVEL)))); + XBT_DEBUG("Create workstation %s with %ld mounted disks", name.c_str(), xbt_dynar_length(workstation->p_storage)); + xbt_lib_set(host_lib, name.c_str(), SURF_WKS_LEVEL, static_cast(workstation)); + return workstation; +} + +double WorkstationModel::shareResources(double now){ + return -1.0; +} + +void WorkstationModel::updateActionsState(double now, double delta){ + return; +} + +ActionPtr WorkstationModel::executeParallelTask(int workstation_nb, + void **workstation_list, + double *computation_amount, + double *communication_amount, + double rate){ +#define cost_or_zero(array,pos) ((array)?(array)[pos]:0.0) + if ((workstation_nb == 1) + && (cost_or_zero(communication_amount, 0) == 0.0)) + return ((WorkstationCLM03Ptr)workstation_list[0])->execute(computation_amount[0]); + else if ((workstation_nb == 1) + && (cost_or_zero(computation_amount, 0) == 0.0)) + return communicate((WorkstationCLM03Ptr)workstation_list[0], (WorkstationCLM03Ptr)workstation_list[0],communication_amount[0], rate); + else if ((workstation_nb == 2) + && (cost_or_zero(computation_amount, 0) == 0.0) + && (cost_or_zero(computation_amount, 1) == 0.0)) { + int i,nb = 0; + double value = 0.0; + + for (i = 0; i < workstation_nb * workstation_nb; i++) { + if (cost_or_zero(communication_amount, i) > 0.0) { + nb++; + value = cost_or_zero(communication_amount, i); + } + } + if (nb == 1) + return communicate((WorkstationCLM03Ptr)workstation_list[0], (WorkstationCLM03Ptr)workstation_list[1],value, rate); + } +#undef cost_or_zero + + THROW_UNIMPLEMENTED; /* This model does not implement parallel tasks */ + return NULL; +} + +/* returns an array of network_link_CM02_t */ +xbt_dynar_t WorkstationModel::getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst) +{ + XBT_DEBUG("ws_get_route"); + return surf_network_model->getRoute(src->p_netElm, dst->p_netElm); +} + +ActionPtr WorkstationModel::communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, double size, double rate){ + return surf_network_model->communicate(src->p_netElm, dst->p_netElm, size, rate); +} + + + +/************ + * Resource * + ************/ +WorkstationCLM03::WorkstationCLM03(WorkstationModelPtr model, const char* name, xbt_dict_t properties, xbt_dynar_t storage, RoutingEdgePtr netElm, CpuPtr cpu) + : Resource(model, name, properties), p_storage(storage), p_netElm(netElm), p_cpu(cpu) {} + +bool WorkstationCLM03::isUsed(){ + THROW_IMPOSSIBLE; /* This model does not implement parallel tasks */ + return -1; +} + +void WorkstationCLM03::updateState(tmgr_trace_event_t event_type, double value, double date){ + THROW_IMPOSSIBLE; /* This model does not implement parallel tasks */ +} + +ActionPtr WorkstationCLM03::execute(double size) { + return p_cpu->execute(size); +} + +ActionPtr WorkstationCLM03::sleep(double duration) { + return p_cpu->sleep(duration); +} + +e_surf_resource_state_t WorkstationCLM03::getState() { + return p_cpu->getState(); +} + +int WorkstationCLM03::getCore(){ + return p_cpu->getCore(); +} + +double WorkstationCLM03::getSpeed(double load){ + return p_cpu->getSpeed(load); +} + +double WorkstationCLM03::getAvailableSpeed(){ + return p_cpu->getAvailableSpeed(); +} + ++double WorkstationCLM03::getCurrentPowerPeak() ++{ ++ return p_cpu->getCurrentPowerPeak(); ++} ++ ++double WorkstationCLM03::getPowerPeakAt(int pstate_index) ++{ ++ return p_cpu->getPowerPeakAt(pstate_index); ++} ++ ++int WorkstationCLM03::getNbPstates() ++{ ++ return p_cpu->getNbPstates(); ++} ++ ++void WorkstationCLM03::setPowerPeakAt(int pstate_index) ++{ ++ p_cpu->setPowerPeakAt(pstate_index); ++} ++ ++double WorkstationCLM03::getConsumedEnergy() ++{ ++ return p_cpu->getConsumedEnergy(); ++} ++ ++ +xbt_dict_t WorkstationCLM03::getProperties() +{ + return p_cpu->m_properties; +} + + - StoragePtr WorkstationCLM03::findStorageOnMountList(const char* storage) ++StoragePtr WorkstationCLM03::findStorageOnMountList(const char* mount) +{ + StoragePtr st = NULL; + s_mount_t mnt; + unsigned int cursor; + - XBT_DEBUG("Search for storage name '%s' on '%s'",storage,m_name); ++ XBT_DEBUG("Search for storage name '%s' on '%s'", mount, m_name); + xbt_dynar_foreach(p_storage,cursor,mnt) + { + XBT_DEBUG("See '%s'",mnt.name); - if(!strcmp(storage,mnt.name)){ - st = (StoragePtr)mnt.id; ++ if(!strcmp(mount,mnt.name)){ ++ st = dynamic_cast(static_cast(mnt.storage)); + break; + } + } - if(!st) xbt_die("Can't find mount '%s' for '%s'",storage,m_name); ++ if(!st) xbt_die("Can't find mount '%s' for '%s'", mount, m_name); + return st; +} + ++xbt_dict_t WorkstationCLM03::getStorageList() ++{ ++ s_mount_t mnt; ++ unsigned int i; ++ xbt_dict_t storage_list = xbt_dict_new_homogeneous(NULL); ++ char *storage_name = NULL; ++ ++ xbt_dynar_foreach(p_storage,i,mnt){ ++ storage_name = (char *)dynamic_cast(static_cast(mnt.storage))->m_name; ++ xbt_dict_set(storage_list,mnt.name,storage_name,NULL); ++ } ++ return storage_list; ++} ++ +ActionPtr WorkstationCLM03::open(const char* mount, const char* path) { + StoragePtr st = findStorageOnMountList(mount); + XBT_DEBUG("OPEN on disk '%s'", st->m_name); + return st->open(mount, path); +} + +ActionPtr WorkstationCLM03::close(surf_file_t fd) { - StoragePtr st = findStorageOnMountList(fd->storage); ++ StoragePtr st = findStorageOnMountList(fd->mount); + XBT_DEBUG("CLOSE on disk '%s'",st->m_name); + return st->close(fd); +} + - ActionPtr WorkstationCLM03::read(void* ptr, size_t size, surf_file_t fd) { - StoragePtr st = findStorageOnMountList(fd->storage); ++ActionPtr WorkstationCLM03::read(surf_file_t fd, sg_storage_size_t size) { ++ StoragePtr st = findStorageOnMountList(fd->mount); + XBT_DEBUG("READ on disk '%s'",st->m_name); - return st->read(ptr, size, fd); ++ return st->read(fd, size); +} + - ActionPtr WorkstationCLM03::write(const void* ptr, size_t size, surf_file_t fd) { - StoragePtr st = findStorageOnMountList(fd->storage); ++ActionPtr WorkstationCLM03::write(surf_file_t fd, sg_storage_size_t size) { ++ StoragePtr st = findStorageOnMountList(fd->mount); + XBT_DEBUG("WRITE on disk '%s'",st->m_name); - return st->write(ptr, size, fd); ++ return st->write(fd, size); +} + +int WorkstationCLM03::unlink(surf_file_t fd) { + if (!fd){ + XBT_WARN("No such file descriptor. Impossible to unlink"); + return 0; + } else { +// XBT_INFO("%s %zu", fd->storage, fd->size); - StoragePtr st = findStorageOnMountList(fd->storage); ++ StoragePtr st = findStorageOnMountList(fd->mount); + /* Check if the file is on this storage */ + if (!xbt_dict_get_or_null(st->p_content, fd->name)){ + XBT_WARN("File %s is not on disk %s. Impossible to unlink", fd->name, + st->m_name); + return 0; + } else { + XBT_DEBUG("UNLINK on disk '%s'",st->m_name); + st->m_usedSize -= fd->size; + + // Remove the file from storage + xbt_dict_remove(st->p_content, fd->name); + + free(fd->name); - free(fd->storage); ++ free(fd->mount); + xbt_free(fd); + return 1; + } + } +} + +ActionPtr WorkstationCLM03::ls(const char* mount, const char *path){ + XBT_DEBUG("LS on mount '%s' and file '%s'", mount, path); + StoragePtr st = findStorageOnMountList(mount); + return st->ls(path); +} + - size_t WorkstationCLM03::getSize(surf_file_t fd){ ++sg_storage_size_t WorkstationCLM03::getSize(surf_file_t fd){ + return fd->size; +} + ++xbt_dynar_t WorkstationCLM03::getInfo( surf_file_t fd) ++{ ++ StoragePtr st = findStorageOnMountList(fd->mount); ++ sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1); ++ *psize = fd->size; ++ xbt_dynar_t info = xbt_dynar_new(sizeof(void*), NULL); ++ xbt_dynar_push_as(info, sg_storage_size_t *, psize); ++ xbt_dynar_push_as(info, void *, fd->mount); ++ xbt_dynar_push_as(info, void *, (void *)st->m_name); ++ xbt_dynar_push_as(info, void *, st->p_typeId); ++ xbt_dynar_push_as(info, void *, st->p_contentType); ++ ++ return info; ++} ++ ++sg_storage_size_t WorkstationCLM03::getFreeSize(const char* name) ++{ ++ StoragePtr st = findStorageOnMountList(name); ++ return st->m_size - st->m_usedSize; ++} ++ ++sg_storage_size_t WorkstationCLM03::getUsedSize(const char* name) ++{ ++ StoragePtr st = findStorageOnMountList(name); ++ return st->m_usedSize; ++} ++ +e_surf_resource_state_t WorkstationCLM03Lmm::getState() { + return WorkstationCLM03::getState(); +} +/********** + * Action * + **********/ diff --cc src/surf/workstation.hpp index 675cfad5ea,0000000000..08940e0dc2 mode 100644,000000..100644 --- a/src/surf/workstation.hpp +++ b/src/surf/workstation.hpp @@@ -1,112 -1,0 +1,122 @@@ +#include "surf.hpp" +#include "storage.hpp" +#include "cpu.hpp" +#include "network.hpp" + +#ifndef WORKSTATION_HPP_ +#define WORKSTATION_HPP_ + +/*********** + * Classes * + ***********/ + +class WorkstationModel; +typedef WorkstationModel *WorkstationModelPtr; + +class WorkstationCLM03; +typedef WorkstationCLM03 *WorkstationCLM03Ptr; + +class WorkstationCLM03Lmm; +typedef WorkstationCLM03Lmm *WorkstationCLM03LmmPtr; + +class WorkstationAction; +typedef WorkstationAction *WorkstationActionPtr; + +/*FIXME:class WorkstationActionLmm; +typedef WorkstationActionLmm *WorkstationActionLmmPtr;*/ + +/********* + * Tools * + *********/ +extern WorkstationModelPtr surf_workstation_model; + +/********* + * Model * + *********/ +class WorkstationModel : public Model { +public: + WorkstationModel(string name): Model(name) {}; + WorkstationModel(); + ~WorkstationModel(); + virtual void parseInit(sg_platf_host_cbarg_t host); + WorkstationCLM03Ptr createResource(string name); + double shareResources(double now); + void updateActionsState(double now, double delta); + + virtual ActionPtr executeParallelTask(int workstation_nb, + void **workstation_list, + double *computation_amount, + double *communication_amount, + double rate); + virtual xbt_dynar_t getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst); + virtual ActionPtr communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, double size, double rate); +}; + +/************ + * Resource * + ************/ + +class WorkstationCLM03 : virtual public Resource { +public: + WorkstationCLM03(WorkstationModelPtr model, const char* name, xbt_dict_t properties, xbt_dynar_t storage, RoutingEdgePtr netElm, CpuPtr cpu); + + void updateState(tmgr_trace_event_t event_type, double value, double date); + + virtual ActionPtr execute(double size); + virtual ActionPtr sleep(double duration); + e_surf_resource_state_t getState(); + + virtual int getCore(); + virtual double getSpeed(double load); + virtual double getAvailableSpeed(); ++ virtual double getCurrentPowerPeak(); ++ virtual double getPowerPeakAt(int pstate_index); ++ virtual int getNbPstates(); ++ virtual void setPowerPeakAt(int pstate_index); ++ virtual double getConsumedEnergy(); + + xbt_dict_t getProperties(); + + StoragePtr findStorageOnMountList(const char* storage); ++ xbt_dict_t getStorageList(); + ActionPtr open(const char* mount, const char* path); + ActionPtr close(surf_file_t fd); + int unlink(surf_file_t fd); + ActionPtr ls(const char* mount, const char *path); - size_t getSize(surf_file_t fd); - ActionPtr read(void* ptr, size_t size, surf_file_t fd); - ActionPtr write(const void* ptr, size_t size, surf_file_t fd); ++ sg_storage_size_t getSize(surf_file_t fd); ++ ActionPtr read(surf_file_t fd, sg_storage_size_t size); ++ ActionPtr write(surf_file_t fd, sg_storage_size_t size); ++ xbt_dynar_t getInfo( surf_file_t fd); ++ sg_storage_size_t getFreeSize(const char* name); ++ sg_storage_size_t getUsedSize(const char* name); ++ + bool isUsed(); + //bool isShared(); + xbt_dynar_t p_storage; + RoutingEdgePtr p_netElm; + CpuPtr p_cpu; + NetworkCm02LinkPtr p_network; +}; + +class WorkstationCLM03Lmm : public WorkstationCLM03, public ResourceLmm { +public: + WorkstationCLM03Lmm(WorkstationModelPtr model, const char* name, xbt_dict_t props, xbt_dynar_t storage, RoutingEdgePtr netElm, CpuPtr cpu): + WorkstationCLM03(model, name, props, storage, netElm, cpu){}; + e_surf_resource_state_t getState(); +}; + +/********** + * Action * + **********/ +class WorkstationAction : virtual public Action { +public: + WorkstationAction(ModelPtr model, double cost, bool failed): Action(model, cost, failed) {}; +}; + +class WorkstationActionLmm : public ActionLmm, public WorkstationAction { +public: + WorkstationActionLmm(ModelPtr model, double cost, bool failed): ActionLmm(model, cost, failed), WorkstationAction(model, cost, failed) {}; +}; + + +#endif /* WORKSTATION_HPP_ */ diff --cc src/surf/workstation_ptask_L07.cpp index 8f11693496,0000000000..507d25e592 mode 100644,000000..100644 --- a/src/surf/workstation_ptask_L07.cpp +++ b/src/surf/workstation_ptask_L07.cpp @@@ -1,834 -1,0 +1,861 @@@ +/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "workstation_ptask_L07.hpp" +#include "cpu.hpp" +#include "surf_routing.hpp" + +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_workstation); + +static int ptask_host_count = 0; +static xbt_dict_t ptask_parallel_task_link_set = NULL; +lmm_system_t ptask_maxmin_system = NULL; + +WorkstationL07Model::WorkstationL07Model() : WorkstationModel("Workstation ptask_L07") { + if (!ptask_maxmin_system) + ptask_maxmin_system = lmm_system_new(1); + surf_workstation_model = NULL; + surf_network_model = new NetworkL07Model(); + surf_cpu_model = new CpuL07Model(); + routing_model_create(p_networkModel->createResource("__loopback__", + 498000000, NULL, + 0.000015, NULL, + SURF_RESOURCE_ON, NULL, + SURF_LINK_FATPIPE, NULL)); +} + +WorkstationL07Model::~WorkstationL07Model() { + xbt_dict_free(&ptask_parallel_task_link_set); + + delete surf_cpu_model; + delete surf_network_model; + ptask_host_count = 0; + + if (ptask_maxmin_system) { + lmm_system_free(ptask_maxmin_system); + ptask_maxmin_system = NULL; + } +} + +double WorkstationL07Model::shareResources(double now) +{ + void *_action; + WorkstationL07ActionLmmPtr action; + + xbt_swag_t running_actions = this->p_runningActionSet; + double min = this->shareResourcesMaxMin(running_actions, + ptask_maxmin_system, + bottleneck_solve); + + xbt_swag_foreach(_action, running_actions) { + action = dynamic_cast(static_cast(_action)); + if (action->m_latency > 0) { + if (min < 0) { + min = action->m_latency; + XBT_DEBUG("Updating min (value) with %p (start %f): %f", action, + action->m_start, min); + } else if (action->m_latency < min) { + min = action->m_latency; + XBT_DEBUG("Updating min (latency) with %p (start %f): %f", action, + action->m_start, min); + } + } + } + + XBT_DEBUG("min value : %f", min); + + return min; +} + +void WorkstationL07Model::updateActionsState(double now, double delta) +{ + double deltap = 0.0; + void *_action, *_next_action; + WorkstationL07ActionLmmPtr action; + + xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) { + action = dynamic_cast(static_cast(_action)); + + deltap = delta; + if (action->m_latency > 0) { + if (action->m_latency > deltap) { + double_update(&(action->m_latency), deltap); + deltap = 0.0; + } else { + double_update(&(deltap), action->m_latency); + action->m_latency = 0.0; + } + if ((action->m_latency == 0.0) && (action->m_suspended == 0)) { + action->updateBound(); + lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 1.0); + } + } + XBT_DEBUG("Action (%p) : remains (%g) updated by %g.", + action, action->m_remains, lmm_variable_getvalue(action->p_variable) * delta); + double_update(&(action->m_remains), lmm_variable_getvalue(action->p_variable) * delta); + + if (action->m_maxDuration != NO_MAX_DURATION) + double_update(&(action->m_maxDuration), delta); + + XBT_DEBUG("Action (%p) : remains (%g).", + action, action->m_remains); + if ((action->m_remains <= 0) && + (lmm_get_variable_weight(action->p_variable) > 0)) { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + } else if ((action->m_maxDuration != NO_MAX_DURATION) && + (action->m_maxDuration <= 0)) { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + } else { + /* Need to check that none of the model has failed */ + lmm_constraint_t cnst = NULL; + int i = 0; + void *constraint_id = NULL; + + while ((cnst = lmm_get_cnst_from_var(ptask_maxmin_system, action->p_variable, + i++))) { + constraint_id = lmm_constraint_id(cnst); + + if (static_cast(constraint_id)->p_stateCurrent == SURF_RESOURCE_OFF) { + XBT_DEBUG("Action (%p) Failed!!", action); + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_FAILED); + break; + } + } + } + } + return; +} + +ActionPtr WorkstationL07Model::executeParallelTask(int workstation_nb, + void **workstation_list, + double + *computation_amount, double + *communication_amount, + double rate) +{ + WorkstationL07ActionLmmPtr action; + int i, j; + unsigned int cpt; + int nb_link = 0; + int nb_host = 0; + double latency = 0.0; + + if (ptask_parallel_task_link_set == NULL) + ptask_parallel_task_link_set = xbt_dict_new_homogeneous(NULL); + + xbt_dict_reset(ptask_parallel_task_link_set); + + /* Compute the number of affected resources... */ + for (i = 0; i < workstation_nb; i++) { + for (j = 0; j < workstation_nb; j++) { + xbt_dynar_t route=NULL; + + if (communication_amount[i * workstation_nb + j] > 0) { + double lat=0.0; + unsigned int cpt; + void *_link; + LinkL07Ptr link; + + routing_platf->getRouteAndLatency(dynamic_cast( + static_cast( + workstation_list[i]))->p_netElm, + dynamic_cast( + static_cast( + workstation_list[j]))->p_netElm, + &route, + &lat); + latency = MAX(latency, lat); + + xbt_dynar_foreach(route, cpt, _link) { + link = dynamic_cast(static_cast(_link)); + xbt_dict_set(ptask_parallel_task_link_set, link->m_name, link, NULL); + } + } + } + } + + nb_link = xbt_dict_length(ptask_parallel_task_link_set); + xbt_dict_reset(ptask_parallel_task_link_set); + + for (i = 0; i < workstation_nb; i++) + if (computation_amount[i] > 0) + nb_host++; + + action = new WorkstationL07ActionLmm(this, 1, 0); + XBT_DEBUG("Creating a parallel task (%p) with %d cpus and %d links.", + action, workstation_nb, nb_link); + action->m_suspended = 0; /* Should be useless because of the + calloc but it seems to help valgrind... */ + action->m_workstationNb = workstation_nb; + action->p_workstationList = (WorkstationCLM03Ptr *) workstation_list; + action->p_computationAmount = computation_amount; + action->p_communicationAmount = communication_amount; + action->m_latency = latency; + action->m_rate = rate; + + action->p_variable = lmm_variable_new(ptask_maxmin_system, action, 1.0, + (action->m_rate > 0) ? action->m_rate : -1.0, + workstation_nb + nb_link); + + if (action->m_latency > 0) + lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 0.0); + + for (i = 0; i < workstation_nb; i++) + lmm_expand(ptask_maxmin_system, + static_cast(dynamic_cast( + static_cast(workstation_list[i]))->p_cpu)->p_constraint, + action->p_variable, computation_amount[i]); + + for (i = 0; i < workstation_nb; i++) { + for (j = 0; j < workstation_nb; j++) { + void *_link; + LinkL07Ptr link; + + xbt_dynar_t route=NULL; + if (communication_amount[i * workstation_nb + j] == 0.0) + continue; + + routing_platf->getRouteAndLatency(dynamic_cast( + static_cast(workstation_list[i]))->p_netElm, + dynamic_cast( + static_cast(workstation_list[j]))->p_netElm, + &route, NULL); + + xbt_dynar_foreach(route, cpt, _link) { + link = dynamic_cast(static_cast(_link)); + lmm_expand_add(ptask_maxmin_system, link->p_constraint, + action->p_variable, + communication_amount[i * workstation_nb + j]); + } + } + } + + if (nb_link + nb_host == 0) { + action->m_cost = 1.0; + action->m_remains = 0.0; + } + + return static_cast(action); +} + +ResourcePtr WorkstationL07Model::createResource(const char *name, double power_scale, + double power_initial, + tmgr_trace_t power_trace, + e_surf_resource_state_t state_initial, + tmgr_trace_t state_trace, + xbt_dict_t cpu_properties) +{ + WorkstationL07Ptr wk = NULL; + xbt_assert(!surf_workstation_resource_priv(surf_workstation_resource_by_name(name)), + "Host '%s' declared several times in the platform file.", + name); + + wk = new WorkstationL07(this, name, cpu_properties, + static_cast(xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL)), + dynamic_cast(static_cast(xbt_lib_get_or_null(host_lib, name, SURF_CPU_LEVEL)))); + + xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, static_cast(wk)); + + return wk;//FIXME:xbt_lib_get_elm_or_null(host_lib, name); +} + +ActionPtr WorkstationL07Model::communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, + double size, double rate) +{ + void **workstation_list = xbt_new0(void *, 2); + double *computation_amount = xbt_new0(double, 2); + double *communication_amount = xbt_new0(double, 4); + ActionPtr res = NULL; + + workstation_list[0] = static_cast(src); + workstation_list[1] = static_cast(dst); + communication_amount[1] = size; + + res = executeParallelTask(2, workstation_list, + computation_amount, + communication_amount, rate); + + return res; +} + +xbt_dynar_t WorkstationL07Model::getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst) +{ + xbt_dynar_t route=NULL; + routing_platf->getRouteAndLatency(src->p_netElm, dst->p_netElm, &route, NULL); + return route; +} + +ResourcePtr CpuL07Model::createResource(const char *name, double power_scale, + double power_initial, + tmgr_trace_t power_trace, + e_surf_resource_state_t state_initial, + tmgr_trace_t state_trace, + xbt_dict_t cpu_properties) +{ + CpuL07Ptr cpu = NULL; + xbt_assert(!surf_workstation_resource_priv(surf_workstation_resource_by_name(name)), + "Host '%s' declared several times in the platform file.", + name); + + cpu = new CpuL07(this, name, cpu_properties); + + cpu->p_power.scale = power_scale; + xbt_assert(cpu->p_power.scale > 0, "Power has to be >0"); + + cpu->m_powerCurrent = power_initial; + if (power_trace) + cpu->p_power.event = + tmgr_history_add_trace(history, power_trace, 0.0, 0, static_cast(cpu)); + + cpu->p_stateCurrent = state_initial; + if (state_trace) + cpu->p_stateEvent = + tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast(cpu)); + + cpu->p_constraint = + lmm_constraint_new(ptask_maxmin_system, cpu, + cpu->m_powerCurrent * cpu->p_power.scale); + + xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, static_cast(cpu)); + + return cpu;//FIXME:xbt_lib_get_elm_or_null(host_lib, name); +} + +ResourcePtr NetworkL07Model::createResource(const char *name, + double bw_initial, + tmgr_trace_t bw_trace, + double lat_initial, + tmgr_trace_t lat_trace, + e_surf_resource_state_t + state_initial, + tmgr_trace_t state_trace, + e_surf_link_sharing_policy_t + policy, xbt_dict_t properties) +{ + LinkL07Ptr nw_link = new LinkL07(this, xbt_strdup(name), properties); + xbt_assert(!xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL), + "Link '%s' declared several times in the platform file.", + name); + + nw_link->m_bwCurrent = bw_initial; + if (bw_trace) + nw_link->p_bwEvent = + tmgr_history_add_trace(history, bw_trace, 0.0, 0, static_cast(nw_link)); + nw_link->p_stateCurrent = state_initial; + nw_link->m_latCurrent = lat_initial; + if (lat_trace) + nw_link->p_latEvent = + tmgr_history_add_trace(history, lat_trace, 0.0, 0, static_cast(nw_link)); + if (state_trace) + nw_link->p_stateEvent = + tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast(nw_link)); + + nw_link->p_constraint = + lmm_constraint_new(ptask_maxmin_system, nw_link, + nw_link->m_bwCurrent); + + if (policy == SURF_LINK_FATPIPE) + lmm_constraint_shared(nw_link->p_constraint); + + xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, static_cast(nw_link)); + return nw_link; +} + +void WorkstationL07Model::addTraces() +{ + xbt_dict_cursor_t cursor = NULL; + char *trace_name, *elm; + + if (!trace_connect_list_host_avail) + return; + + /* Connect traces relative to cpu */ + xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + CpuL07Ptr host = dynamic_cast( + static_cast( + surf_cpu_resource_priv( + surf_cpu_resource_by_name(elm)))); + + xbt_assert(host, "Host %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + host->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(host)); + } + + xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + CpuL07Ptr host = dynamic_cast( + static_cast( + surf_cpu_resource_priv( + surf_cpu_resource_by_name(elm)))); + + xbt_assert(host, "Host %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + host->p_power.event = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(host)); + } + + /* Connect traces relative to network */ + xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + LinkL07Ptr link = dynamic_cast(static_cast(xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL))); + + xbt_assert(link, "Link %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + link->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(link)); + } + + xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + LinkL07Ptr link = dynamic_cast(static_cast(xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL))); + + xbt_assert(link, "Link %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + link->p_bwEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(link)); + } + + xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + LinkL07Ptr link = dynamic_cast(static_cast(xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL))); + + xbt_assert(link, "Link %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + link->p_latEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast(link)); + } +} + +/************ + * Resource * + ************/ + +WorkstationL07::WorkstationL07(WorkstationModelPtr model, const char* name, xbt_dict_t props, RoutingEdgePtr netElm, CpuPtr cpu) + : Resource(model, name, props), WorkstationCLM03Lmm(model, name, props, NULL, netElm, cpu) +{ +} + ++double WorkstationL07::getPowerPeakAt(int pstate_index) ++{ ++ XBT_DEBUG("[ws_get_power_peak_at] Not implemented for workstation_ptask_L07"); ++ return 0.0; ++} ++ ++int WorkstationL07::getNbPstates() ++{ ++ XBT_DEBUG("[ws_get_nb_pstates] Not implemented for workstation_ptask_L07"); ++ return 0.0; ++} ++ ++void WorkstationL07::setPowerPeakAt(int pstate_index) ++{ ++ XBT_DEBUG("[ws_set_power_peak_at] Not implemented for workstation_ptask_L07"); ++} ++ ++double WorkstationL07::getConsumedEnergy() ++{ ++ XBT_DEBUG("[ws_get_consumed_energy] Not implemented for workstation_ptask_L07"); ++ return 0.0; ++} ++ +CpuL07::CpuL07(CpuL07ModelPtr model, const char* name, xbt_dict_t props) + : Resource(model, name, props), CpuLmm(model, name, props) { + +} + +LinkL07::LinkL07(NetworkL07ModelPtr model, const char* name, xbt_dict_t props) + : Resource(model, name, props), NetworkCm02LinkLmm(model, name, props) { + +} + +bool CpuL07::isUsed(){ + return lmm_constraint_used(ptask_maxmin_system, p_constraint); +} + +bool LinkL07::isUsed(){ + return lmm_constraint_used(ptask_maxmin_system, p_constraint); +} + +void CpuL07::updateState(tmgr_trace_event_t event_type, double value, double date){ + XBT_DEBUG("Updating cpu %s (%p) with value %g", m_name, this, value); + if (event_type == p_power.event) { + m_powerCurrent = value; + lmm_update_constraint_bound(ptask_maxmin_system, p_constraint, m_powerCurrent * p_power.scale); + if (tmgr_trace_event_free(event_type)) + p_power.event = NULL; + } else if (event_type == p_stateEvent) { + if (value > 0) + p_stateCurrent = SURF_RESOURCE_ON; + else + p_stateCurrent = SURF_RESOURCE_OFF; + if (tmgr_trace_event_free(event_type)) + p_stateEvent = NULL; + } else { + XBT_CRITICAL("Unknown event ! \n"); + xbt_abort(); + } + return; +} + +void LinkL07::updateState(tmgr_trace_event_t event_type, double value, double date){ + XBT_DEBUG("Updating link %s (%p) with value=%f for date=%g", m_name, this, value, date); + if (event_type == p_bwEvent) { + m_bwCurrent = value; + lmm_update_constraint_bound(ptask_maxmin_system, p_constraint, m_bwCurrent); + if (tmgr_trace_event_free(event_type)) + p_bwEvent = NULL; + } else if (event_type == p_latEvent) { + lmm_variable_t var = NULL; + WorkstationL07ActionLmmPtr action; + lmm_element_t elem = NULL; + + m_latCurrent = value; + while ((var = lmm_get_var_from_cnst(ptask_maxmin_system, p_constraint, &elem))) { + action = (WorkstationL07ActionLmmPtr) lmm_variable_id(var); + action->updateBound(); + } + if (tmgr_trace_event_free(event_type)) + p_latEvent = NULL; + } else if (event_type == p_stateEvent) { + if (value > 0) + p_stateCurrent = SURF_RESOURCE_ON; + else + p_stateCurrent = SURF_RESOURCE_OFF; + if (tmgr_trace_event_free(event_type)) + p_stateEvent = NULL; + } else { + XBT_CRITICAL("Unknown event ! \n"); + xbt_abort(); + } + return; +} + +e_surf_resource_state_t WorkstationL07::getState() +{ + return p_cpu->p_stateCurrent; +} + +e_surf_resource_state_t CpuL07::getState() +{ + return p_stateCurrent; +} + +double CpuL07::getSpeed(double load) +{ + return load * p_power.scale; +} + +double CpuL07::getAvailableSpeed() +{ + return m_powerCurrent; +} + +ActionPtr WorkstationL07::execute(double size) +{ + void **workstation_list = xbt_new0(void *, 1); + double *computation_amount = xbt_new0(double, 1); + double *communication_amount = xbt_new0(double, 1); + + workstation_list[0] = static_cast(this); + communication_amount[0] = 0.0; + computation_amount[0] = size; + + return static_cast(p_model)->executeParallelTask(1, workstation_list, + computation_amount, + communication_amount, -1); +} + +ActionPtr WorkstationL07::sleep(double duration) +{ + WorkstationL07ActionLmmPtr action = NULL; + + XBT_IN("(%s,%g)", m_name, duration); + + action = dynamic_cast(execute(1.0)); + action->m_maxDuration = duration; + action->m_suspended = 2; + lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 0.0); + + XBT_OUT(); + return action; +} + +double LinkL07::getBandwidth() +{ + return m_bwCurrent; +} + +double LinkL07::getLatency() +{ + return m_latCurrent; +} + +bool LinkL07::isShared() +{ + return lmm_constraint_is_shared(p_constraint); +} + +/********** + * Action * + **********/ + +WorkstationL07ActionLmm::~WorkstationL07ActionLmm(){ + free(p_workstationList); + free(p_communicationAmount); + free(p_computationAmount); +#ifdef HAVE_TRACING + xbt_free(p_category); +#endif +} + +void WorkstationL07ActionLmm::updateBound() +{ + double lat_current = 0.0; + double lat_bound = -1.0; + int i, j; + + for (i = 0; i < m_workstationNb; i++) { + for (j = 0; j < m_workstationNb; j++) { + xbt_dynar_t route=NULL; + + if (p_communicationAmount[i * m_workstationNb + j] > 0) { + double lat = 0.0; + routing_platf->getRouteAndLatency(dynamic_cast( + static_cast(((void**)p_workstationList)[i]))->p_netElm, + dynamic_cast( + static_cast(((void**)p_workstationList)[j]))->p_netElm, + &route, &lat); + + lat_current = MAX(lat_current, lat * p_communicationAmount[i * m_workstationNb + j]); + } + } + } + lat_bound = sg_tcp_gamma / (2.0 * lat_current); + XBT_DEBUG("action (%p) : lat_bound = %g", this, lat_bound); + if ((m_latency == 0.0) && (m_suspended == 0)) { + if (m_rate < 0) + lmm_update_variable_bound(ptask_maxmin_system, p_variable, lat_bound); + else + lmm_update_variable_bound(ptask_maxmin_system, p_variable, min(m_rate, lat_bound)); + } +} + +int WorkstationL07ActionLmm::unref() +{ + m_refcount--; + if (!m_refcount) { + xbt_swag_remove(static_cast(this), p_stateSet); + if (p_variable) + lmm_variable_free(ptask_maxmin_system, p_variable); + delete this; + return 1; + } + return 0; +} + +void WorkstationL07ActionLmm::cancel() +{ + setState(SURF_ACTION_FAILED); + return; +} + +void WorkstationL07ActionLmm::suspend() +{ + XBT_IN("(%p))", this); + if (m_suspended != 2) { + m_suspended = 1; + lmm_update_variable_weight(ptask_maxmin_system, p_variable, 0.0); + } + XBT_OUT(); +} + +void WorkstationL07ActionLmm::resume() +{ + XBT_IN("(%p)", this); + if (m_suspended != 2) { + lmm_update_variable_weight(ptask_maxmin_system, p_variable, 1.0); + m_suspended = 0; + } + XBT_OUT(); +} + +bool WorkstationL07ActionLmm::isSuspended() +{ + return m_suspended == 1; +} + +void WorkstationL07ActionLmm::setMaxDuration(double duration) +{ /* FIXME: should inherit */ + XBT_IN("(%p,%g)", this, duration); + m_maxDuration = duration; + XBT_OUT(); +} + +void WorkstationL07ActionLmm::setPriority(double priority) +{ /* FIXME: should inherit */ + XBT_IN("(%p,%g)", this, priority); + m_priority = priority; + XBT_OUT(); +} + +double WorkstationL07ActionLmm::getRemains() +{ + XBT_IN("(%p)", this); + XBT_OUT(); + return m_remains; +} + + + + + + + + + +static void ptask_finalize(void) +{ + xbt_dict_free(&ptask_parallel_task_link_set); + + delete surf_workstation_model; + surf_workstation_model = NULL; + delete surf_network_model; + surf_network_model = NULL; + + ptask_host_count = 0; + + if (ptask_maxmin_system) { + lmm_system_free(ptask_maxmin_system); + ptask_maxmin_system = NULL; + } +} + +/**************************************/ +/******* Resource Private **********/ +/**************************************/ + + + + + + + + + + + + + + + + +/**************************************/ +/*** Resource Creation & Destruction **/ +/**************************************/ + +static void ptask_parse_workstation_init(sg_platf_host_cbarg_t host) +{ ++ double power_peak = xbt_dynar_get_as(host->power_peak, host->pstate, double); ++ //cpu->power_peak = power_peak; ++ xbt_dynar_free(&(host->power_peak)); /* kill memory leak */ + static_cast(surf_workstation_model)->createResource( + host->id, - host->power_peak, ++ power_peak, + host->power_scale, + host->power_trace, + host->initial_state, + host->state_trace, + host->properties); +} + +static void ptask_parse_cpu_init(sg_platf_host_cbarg_t host) +{ - static_cast(surf_cpu_model)->createResource( ++ double power_peak = xbt_dynar_get_as(host->power_peak, host->pstate, double); ++ static_cast(surf_cpu_model)->createResource( + host->id, - host->power_peak, ++ power_peak, + host->power_scale, + host->power_trace, + host->initial_state, + host->state_trace, + host->properties); +} + + + +static void ptask_parse_link_init(sg_platf_link_cbarg_t link) +{ + if (link->policy == SURF_LINK_FULLDUPLEX) { + char *link_id; + link_id = bprintf("%s_UP", link->id); + static_cast(surf_network_model)->createResource(link_id, + link->bandwidth, + link->bandwidth_trace, + link->latency, + link->latency_trace, + link->state, + link->state_trace, + link->policy, + link->properties); + xbt_free(link_id); + link_id = bprintf("%s_DOWN", link->id); + static_cast(surf_network_model)->createResource(link_id, + link->bandwidth, + link->bandwidth_trace, + link->latency, + link->latency_trace, + link->state, + link->state_trace, + link->policy, + NULL); /* FIXME: We need to deep copy the + * properties or we won't be able to free + * it */ + xbt_free(link_id); + } else { + static_cast(surf_network_model)->createResource(link->id, + link->bandwidth, + link->bandwidth_trace, + link->latency, + link->latency_trace, + link->state, + link->state_trace, + link->policy, + link->properties); + } + + current_property_set = NULL; +} + +static void ptask_add_traces(){ + static_cast(surf_workstation_model)->addTraces(); +} + +static void ptask_define_callbacks() +{ + sg_platf_host_add_cb(ptask_parse_cpu_init); + sg_platf_host_add_cb(ptask_parse_workstation_init); + sg_platf_link_add_cb(ptask_parse_link_init); + sg_platf_postparse_add_cb(ptask_add_traces); +} + +/**************************************/ +/*************** Generic **************/ +/**************************************/ +void surf_workstation_model_init_ptask_L07(void) +{ + XBT_INFO("surf_workstation_model_init_ptask_L07"); + xbt_assert(!surf_cpu_model, "CPU model type already defined"); + xbt_assert(!surf_network_model, "network model type already defined"); + ptask_define_callbacks(); + surf_workstation_model = new WorkstationL07Model(); + ModelPtr model = static_cast(surf_workstation_model); + xbt_dynar_push(model_list, &model); +} diff --cc src/surf/workstation_ptask_L07.hpp index ded3df2b38,0000000000..0cd7713492 mode 100644,000000..100644 --- a/src/surf/workstation_ptask_L07.hpp +++ b/src/surf/workstation_ptask_L07.hpp @@@ -1,173 -1,0 +1,184 @@@ +#include "workstation.hpp" + +#ifndef WORKSTATION_L07_HPP_ +#define WORKSTATION_L07_HPP_ + +/*********** + * Classes * + ***********/ + +class WorkstationL07Model; +typedef WorkstationL07Model *WorkstationL07ModelPtr; + +class CpuL07Model; +typedef CpuL07Model *CpuL07ModelPtr; + +class NetworkL07Model; +typedef NetworkL07Model *NetworkL07ModelPtr; + +class WorkstationL07; +typedef WorkstationL07 *WorkstationL07Ptr; + +class CpuL07; +typedef CpuL07 *CpuL07Ptr; + +class LinkL07; +typedef LinkL07 *LinkL07Ptr; + +class WorkstationL07ActionLmm; +typedef WorkstationL07ActionLmm *WorkstationL07ActionLmmPtr; + +/*FIXME:class WorkstationActionLmm; +typedef WorkstationActionLmm *WorkstationActionLmmPtr;*/ + +/********* + * Tools * + *********/ + +/********* + * Model * + *********/ +class WorkstationL07Model : public WorkstationModel { +public: + WorkstationL07Model(); + ~WorkstationL07Model(); + + double shareResources(double now); + void updateActionsState(double now, double delta); + ResourcePtr createResource(const char *name, double power_scale, + double power_initial, + tmgr_trace_t power_trace, + e_surf_resource_state_t state_initial, + tmgr_trace_t state_trace, + xbt_dict_t cpu_properties); + ActionPtr executeParallelTask(int workstation_nb, + void **workstation_list, + double *computation_amount, + double *communication_amount, + double rate); + xbt_dynar_t getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst); + ActionPtr communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, double size, double rate); + void addTraces(); + CpuL07ModelPtr p_cpuModel; + NetworkL07ModelPtr p_networkModel; +}; + +class CpuL07Model : public CpuModel { +public: + CpuL07Model() : CpuModel("cpuL07") {}; + ~CpuL07Model() {surf_cpu_model = NULL;}; + ResourcePtr createResource(const char *name, double power_scale, + double power_initial, + tmgr_trace_t power_trace, + e_surf_resource_state_t state_initial, + tmgr_trace_t state_trace, + xbt_dict_t cpu_properties); + void addTraces() {DIE_IMPOSSIBLE;}; + WorkstationL07ModelPtr p_workstationModel; +}; + +class NetworkL07Model : public NetworkCm02Model { +public: + NetworkL07Model() : NetworkCm02Model(0) {}; + ~NetworkL07Model() {surf_network_model = NULL;}; + ResourcePtr createResource(const char *name, + double bw_initial, + tmgr_trace_t bw_trace, + double lat_initial, + tmgr_trace_t lat_trace, + e_surf_resource_state_t + state_initial, + tmgr_trace_t state_trace, + e_surf_link_sharing_policy_t + policy, xbt_dict_t properties); + + xbt_dynar_t getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst) {DIE_IMPOSSIBLE;}; + ActionPtr communicate(RoutingEdgePtr src, RoutingEdgePtr dst, double size, double rate) {DIE_IMPOSSIBLE;}; + void addTraces() {DIE_IMPOSSIBLE;}; + WorkstationL07ModelPtr p_workstationModel; +}; + +/************ + * Resource * + ************/ + +class WorkstationL07 : public WorkstationCLM03Lmm { +public: + WorkstationL07(WorkstationModelPtr model, const char* name, xbt_dict_t props, RoutingEdgePtr netElm, CpuPtr cpu); + //bool isUsed(); + bool isUsed() {DIE_IMPOSSIBLE;}; + void updateState(tmgr_trace_event_t event_type, double value, double date) {DIE_IMPOSSIBLE;}; + ActionPtr execute(double size); + ActionPtr sleep(double duration); + e_surf_resource_state_t getState(); ++ double getPowerPeakAt(int pstate_index); ++ int getNbPstates(); ++ void setPowerPeakAt(int pstate_index); ++ double getConsumedEnergy(); +}; + +class CpuL07 : public CpuLmm { +public: + CpuL07(CpuL07ModelPtr model, const char* name, xbt_dict_t properties); + bool isUsed(); + //bool isUsed() {DIE_IMPOSSIBLE;}; + void updateState(tmgr_trace_event_t event_type, double value, double date); + e_surf_resource_state_t getState(); + double getSpeed(double load); + double getAvailableSpeed(); + ActionPtr execute(double size) {DIE_IMPOSSIBLE;}; + ActionPtr sleep(double duration) {DIE_IMPOSSIBLE;}; ++ ++ double getCurrentPowerPeak() {}; ++ double getPowerPeakAt(int pstate_index) {}; ++ int getNbPstates() {}; ++ void setPowerPeakAt(int pstate_index) {}; ++ double getConsumedEnergy() {}; ++ + double m_powerCurrent; +}; + +class LinkL07 : public NetworkCm02LinkLmm { +public: + LinkL07(NetworkL07ModelPtr model, const char* name, xbt_dict_t props); + bool isUsed(); + void updateState(tmgr_trace_event_t event_type, double value, double date); + double getBandwidth(); + double getLatency(); + bool isShared(); + + double m_latCurrent; + tmgr_trace_event_t p_latEvent; + double m_bwCurrent; + tmgr_trace_event_t p_bwEvent; +}; + +/********** + * Action * + **********/ +class WorkstationL07ActionLmm : public WorkstationActionLmm { +public: + WorkstationL07ActionLmm(ModelPtr model, double cost, bool failed) + : Action(model, cost, failed), WorkstationActionLmm(model, cost, failed) {}; + ~WorkstationL07ActionLmm(); + + void updateBound(); + + int unref(); + void cancel(); + void suspend(); + void resume(); + bool isSuspended(); + void setMaxDuration(double duration); + void setPriority(double priority); + double getRemains(); + + int m_workstationNb; + WorkstationCLM03Ptr *p_workstationList; + double *p_computationAmount; + double *p_communicationAmount; + double m_latency; + double m_rate; +}; + +#endif /* WORKSTATION_L07_HPP_ */