+ storage_t storage = NULL;
+
+ xbt_assert(!surf_storage_resource_by_name(id),
+ "Storage '%s' declared several times in the platform file",
+ id);
+ storage = (storage_t) surf_resource_new(sizeof(s_storage_t),
+ surf_storage_model, id,NULL);
+
+ storage->state_current = SURF_RESOURCE_ON;
+ storage->used_size = 0;
+ storage->size = 0;
+ storage->write_actions = xbt_dynar_new(sizeof(char *),NULL);
+
+ storage_type_t storage_type = xbt_lib_get_or_null(storage_type_lib, type_id,ROUTING_STORAGE_TYPE_LEVEL);
+ double Bread = atof(xbt_dict_get(storage_type->properties,"Bread"));
+ double Bwrite = atof(xbt_dict_get(storage_type->properties,"Bwrite"));
+ double Bconnection = atof(xbt_dict_get(storage_type->properties,"Bconnection"));
+ XBT_DEBUG("Create resource with Bconnection '%f' Bread '%f' Bwrite '%f' and Size '%ld'",Bconnection,Bread,Bwrite,storage_type->size);
+ storage->constraint = lmm_constraint_new(storage_maxmin_system, storage, Bconnection);
+ storage->constraint_read = lmm_constraint_new(storage_maxmin_system, storage, Bread);
+ storage->constraint_write = lmm_constraint_new(storage_maxmin_system, storage, Bwrite);
+ storage->content = parse_storage_content((char*)content_name,&(storage->used_size));
+ storage->size = storage_type->size;
+
+ xbt_lib_set(storage_lib, id, SURF_STORAGE_LEVEL, 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 *),free);
+ xbt_dynar_push(storage_list,&storage);
+
+ return storage;
+}
+
+static void storage_finalize(void)
+{
+ lmm_system_free(storage_maxmin_system);
+ storage_maxmin_system = NULL;
+
+ surf_model_exit(surf_storage_model);
+ surf_storage_model = NULL;
+
+ xbt_swag_free
+ (storage_running_action_set_that_does_not_need_being_checked);
+ storage_running_action_set_that_does_not_need_being_checked = NULL;
+}
+
+static void storage_update_actions_state(double now, double delta)
+{
+ surf_action_storage_t action = NULL;
+ surf_action_storage_t next_action = NULL;
+ xbt_swag_t running_actions = surf_storage_model->states.running_action_set;
+
+ // Update the disk usage
+ // Update the file size
+ // Foreach action of type write
+ xbt_swag_foreach_safe(action, next_action, running_actions) {
+ if(action->type == WRITE)
+ {
+ double rate = lmm_variable_getvalue(GENERIC_LMM_ACTION(action).variable);
+ ((storage_t)(action->storage))->used_size += delta * rate; // disk usage
+ ((surf_action_t)action)->file->content->stat.size += delta * rate; // file size
+ }
+ }
+
+ xbt_swag_foreach_safe(action, next_action, running_actions) {
+ double_update(&(GENERIC_ACTION(action).remains),
+ lmm_variable_getvalue(GENERIC_LMM_ACTION(action).variable) * delta);
+ if (GENERIC_LMM_ACTION(action).generic_action.max_duration != NO_MAX_DURATION)
+ double_update(&(GENERIC_ACTION(action).max_duration), delta);
+ if(GENERIC_ACTION(action).remains > 0 &&
+ lmm_get_variable_weight(GENERIC_LMM_ACTION(action).variable) > 0 &&
+ ((storage_t)action->storage)->used_size == ((storage_t)action->storage)->size) {
+ GENERIC_ACTION(action).finish = surf_get_clock();
+ storage_action_state_set((surf_action_t) action, SURF_ACTION_FAILED);
+ } else
+ if ((GENERIC_ACTION(action).remains <= 0) &&
+ (lmm_get_variable_weight(GENERIC_LMM_ACTION(action).variable) > 0)) {
+ GENERIC_ACTION(action).finish = surf_get_clock();
+ storage_action_state_set((surf_action_t) action, SURF_ACTION_DONE);
+ } else if ((GENERIC_ACTION(action).max_duration != NO_MAX_DURATION) &&
+ (GENERIC_ACTION(action).max_duration <= 0)) {
+ GENERIC_ACTION(action).finish = surf_get_clock();
+ storage_action_state_set((surf_action_t) action, SURF_ACTION_DONE);
+ }
+ }
+
+ return;
+}
+
+static double storage_share_resources(double NOW)
+{
+ XBT_DEBUG("storage_share_resources %f",NOW);
+ s_surf_action_storage_t action;
+ unsigned int i,j;
+ storage_t storage;
+ surf_action_storage_t write_action;
+
+ double min_completion = generic_maxmin_share_resources(surf_storage_model->states.running_action_set,
+ xbt_swag_offset(action, generic_lmm_action.variable),
+ storage_maxmin_system, lmm_solve);
+
+ double rate;
+ // Foreach disk
+ xbt_dynar_foreach(storage_list,i,storage)
+ {
+ rate = 0;
+ // Foreach write action on disk
+ xbt_dynar_foreach(storage->write_actions,j,write_action)
+ {
+ rate += lmm_variable_getvalue(write_action->generic_lmm_action.variable);
+ }
+ if(rate > 0)
+ min_completion = MIN(min_completion, (storage->size-storage->used_size)/rate);
+ }
+
+ return min_completion;
+}
+
+static int storage_resource_used(void *resource_id)
+{
+ THROW_UNIMPLEMENTED;
+ return 0;
+}
+
+static void storage_resources_state(void *id, tmgr_trace_event_t event_type,
+ double value, double time)
+{
+ THROW_UNIMPLEMENTED;
+}
+
+static int storage_action_unref(surf_action_t action)
+{
+ action->refcount--;
+ if (!action->refcount) {
+ xbt_swag_remove(action, action->state_set);
+ if (((surf_action_lmm_t) action)->variable)
+ lmm_variable_free(storage_maxmin_system,
+ ((surf_action_lmm_t) action)->variable);
+#ifdef HAVE_TRACING
+ xbt_free(action->category);
+#endif
+ surf_action_free(&action);
+ return 1;
+ }
+ return 0;
+}
+
+static void storage_action_cancel(surf_action_t action)
+{
+ surf_action_state_set(action, SURF_ACTION_FAILED);
+ return;
+}
+
+static void storage_action_state_set(surf_action_t action, e_surf_action_state_t state)
+{
+ surf_action_state_set(action, state);
+ return;
+}
+
+static void storage_action_suspend(surf_action_t action)
+{
+ XBT_IN("(%p)", action);
+ if (((surf_action_lmm_t) action)->suspended != 2) {
+ lmm_update_variable_weight(storage_maxmin_system,
+ ((surf_action_lmm_t) action)->variable,
+ 0.0);
+ ((surf_action_lmm_t) action)->suspended = 1;
+ }
+ XBT_OUT();
+}
+
+static void storage_action_resume(surf_action_t action)
+{
+ THROW_UNIMPLEMENTED;
+}
+
+static int storage_action_is_suspended(surf_action_t action)
+{
+ return (((surf_action_lmm_t) action)->suspended == 1);
+}
+
+static void storage_action_set_max_duration(surf_action_t action, double duration)
+{
+ THROW_UNIMPLEMENTED;
+}