From 59ee07d949014eace7f574354a69fbba0fd2be4e Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Thu, 20 Oct 2011 13:26:28 +0200 Subject: [PATCH 1/1] setup a mallocator for the simdag tasks. The gain is quite disapointing, but not null --- src/simdag/private.h | 8 ++ src/simdag/sd_global.c | 5 +- src/simdag/sd_task.c | 187 ++++++++++++++++++++++++----------------- 3 files changed, 123 insertions(+), 77 deletions(-) diff --git a/src/simdag/private.h b/src/simdag/private.h index 6939ecae93..88bb0a92d3 100644 --- a/src/simdag/private.h +++ b/src/simdag/private.h @@ -14,6 +14,7 @@ #include "simdag/datatypes.h" #include "surf/surf.h" #include "xbt/swag.h" +#include "xbt/mallocator.h" #include #define SD_INITIALISED() (sd_global != NULL) @@ -29,6 +30,8 @@ typedef struct SD_global { SD_link_t *recyclable_route; /* array returned by SD_route_get_list and mallocated only once */ + xbt_mallocator_t task_mallocator; /* to not remalloc new tasks */ + int watch_point_reached; /* has a task just reached a watch point? */ /* task state sets */ @@ -130,6 +133,11 @@ int __SD_task_try_to_run(SD_task_t task); void __SD_task_just_done(SD_task_t task); bool acyclic_graph_detail(xbt_dynar_t dag); +/* Task mallocator functions */ +void* SD_task_new_f(void); +void SD_task_recycle_f(void *t); +void SD_task_free_f(void *t); + /* Functions to test if the task is in a given state. */ /* Returns whether the given task is scheduled or runnable. */ diff --git a/src/simdag/sd_global.c b/src/simdag/sd_global.c index 12682cc48a..eb0b892ca1 100644 --- a/src/simdag/sd_global.c +++ b/src/simdag/sd_global.c @@ -66,6 +66,8 @@ void SD_init(int *argc, char **argv) sd_global->recyclable_route = NULL; sd_global->watch_point_reached = 0; + sd_global->task_mallocator=xbt_mallocator_new(65536, SD_task_new_f,SD_task_free_f,SD_task_recycle_f); + sd_global->not_scheduled_task_set = xbt_swag_new(xbt_swag_offset(task, state_hookup)); sd_global->schedulable_task_set = @@ -411,7 +413,7 @@ void SD_exit(void) #endif if (SD_INITIALISED()) { - XBT_DEBUG("Destroying workstation and link dictionaries..."); + xbt_mallocator_free(sd_global->task_mallocator); XBT_DEBUG("Destroying workstation and link arrays if necessary..."); if (sd_global->workstation_list != NULL) @@ -432,6 +434,7 @@ void SD_exit(void) xbt_swag_free(sd_global->running_task_set); xbt_swag_free(sd_global->done_task_set); xbt_swag_free(sd_global->failed_task_set); + xbt_swag_free(sd_global->return_set); XBT_DEBUG("Exiting Surf..."); surf_exit(); diff --git a/src/simdag/sd_task.c b/src/simdag/sd_task.c index 57e34a8677..f1d202feca 100644 --- a/src/simdag/sd_task.c +++ b/src/simdag/sd_task.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2006, 2007, 2008, 2009, 2010. The SimGrid Team. +/* Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -16,47 +16,60 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sd_task, sd, static void __SD_task_remove_dependencies(SD_task_t task); static void __SD_task_destroy_scheduling_data(SD_task_t task); -/** - * \brief Creates a new task. - * - * \param name the name of the task (can be \c NULL) - * \param data the user data you want to associate with the task (can be \c NULL) - * \param amount amount of the task - * \return the new task - * \see SD_task_destroy() - */ -SD_task_t SD_task_create(const char *name, void *data, double amount) -{ +void* SD_task_new_f(void) { + SD_task_t task = xbt_new0(s_SD_task_t, 1); + task->tasks_before = xbt_dynar_new(sizeof(SD_dependency_t), NULL); + task->tasks_after = xbt_dynar_new(sizeof(SD_dependency_t), NULL); - SD_task_t task; - SD_CHECK_INIT_DONE(); + return task; +} +void SD_task_recycle_f(void *t) { + SD_task_t task = (SD_task_t)t; + + __SD_task_remove_dependencies(task); + /* if the task was scheduled or runnable we have to free the scheduling parameters */ + if (__SD_task_is_scheduled_or_runnable(task)) + __SD_task_destroy_scheduling_data(task); + if (task->state_set != NULL) {/* would be null if just created */ + xbt_swag_remove(task, task->state_set); + } + xbt_swag_remove(task, sd_global->return_set); - task = xbt_new(s_SD_task_t, 1); + if (task->name != NULL) + xbt_free(task->name); - /* general information */ - task->data = data; /* user data */ - task->name = xbt_strdup(name); + if (task->surf_action != NULL) + surf_workstation_model->action_unref(task->surf_action); + + if (task->workstation_list != NULL) + xbt_free(task->workstation_list); + + if (task->communication_amount) + xbt_free(task->communication_amount); + + if (task->computation_amount) + xbt_free(task->computation_amount); + + /* Reset the content */ task->kind = SD_TASK_NOT_TYPED; task->state_hookup.prev = NULL; task->state_hookup.next = NULL; task->state_set = sd_global->not_scheduled_task_set; + xbt_swag_insert(task, task->state_set); task->state = SD_NOT_SCHEDULED; task->return_hookup.prev = NULL; task->return_hookup.next = NULL; task->marked = 0; - xbt_swag_insert(task, task->state_set); - task->amount = amount; - task->remains = amount; task->start_time = -1.0; task->finish_time = -1.0; task->surf_action = NULL; task->watch_points = 0; /* dependencies */ - task->tasks_before = xbt_dynar_new(sizeof(SD_dependency_t), NULL); - task->tasks_after = xbt_dynar_new(sizeof(SD_dependency_t), NULL); + xbt_dynar_reset(task->tasks_before); // = new(sizeof(SD_dependency_t), NULL); + xbt_dynar_reset(task->tasks_after); // = xbt_dynar_new(sizeof(SD_dependency_t), NULL); task->unsatisfied_dependencies = 0; task->is_not_ready = 0; @@ -67,14 +80,87 @@ SD_task_t SD_task_create(const char *name, void *data, double amount) task->communication_amount = NULL; task->rate = -1; - sd_global->task_number++; - #ifdef HAVE_TRACING TRACE_sd_task_create(task); #endif +} +void SD_task_free_f(void *t) { + SD_task_t task = (SD_task_t)t; + + __SD_task_remove_dependencies(task); + /* if the task was scheduled or runnable we have to free the scheduling parameters */ + if (__SD_task_is_scheduled_or_runnable(task)) + __SD_task_destroy_scheduling_data(task); + if (task->state_set != NULL) /* would be null if just created */ + xbt_swag_remove(task, task->state_set); + + xbt_swag_remove(task, sd_global->return_set); + + if (task->name != NULL) + xbt_free(task->name); + + if (task->surf_action != NULL) + surf_workstation_model->action_unref(task->surf_action); + + if (task->workstation_list != NULL) + xbt_free(task->workstation_list); + + if (task->communication_amount) + xbt_free(task->communication_amount); + + if (task->computation_amount) + xbt_free(task->computation_amount); +#ifdef HAVE_TRACING + TRACE_sd_task_destroy(task); +#endif + + xbt_dynar_free(&task->tasks_before); + xbt_dynar_free(&task->tasks_after); + xbt_free(task); +} + + +/** + * \brief Creates a new task. + * + * \param name the name of the task (can be \c NULL) + * \param data the user data you want to associate with the task (can be \c NULL) + * \param amount amount of the task + * \return the new task + * \see SD_task_destroy() + */ +SD_task_t SD_task_create(const char *name, void *data, double amount) +{ + SD_task_t task = xbt_mallocator_get(sd_global->task_mallocator); + + /* general information */ + task->data = data; /* user data */ + task->name = xbt_strdup(name); + task->amount = amount; + task->remains = amount; + + sd_global->task_number++; return task; } +/** + * \brief Destroys a task. + * + * The user data (if any) should have been destroyed first. + * + * \param task the task you want to destroy + * \see SD_task_create() + */ +void SD_task_destroy(SD_task_t task) +{ + XBT_DEBUG("Destroying task %s...", SD_task_get_name(task)); + + xbt_mallocator_release(sd_global->task_mallocator,task); + sd_global->task_number--; + + XBT_DEBUG("Task destroyed."); +} + /** * \brief Returns the user data of a task @@ -1236,57 +1322,6 @@ double SD_task_get_finish_time(SD_task_t task) return task->finish_time; } -/** - * \brief Destroys a task. - * - * The user data (if any) should have been destroyed first. - * - * \param task the task you want to destroy - * \see SD_task_create() - */ -void SD_task_destroy(SD_task_t task) -{ - SD_CHECK_INIT_DONE(); - xbt_assert(task != NULL, "Invalid parameter"); - - XBT_DEBUG("Destroying task %s...", SD_task_get_name(task)); - - __SD_task_remove_dependencies(task); - /* if the task was scheduled or runnable we have to free the scheduling parameters */ - if (__SD_task_is_scheduled_or_runnable(task)) - __SD_task_destroy_scheduling_data(task); - xbt_swag_remove(task, task->state_set); - xbt_swag_remove(task, sd_global->return_set); - - if (task->name != NULL) - xbt_free(task->name); - - if (task->surf_action != NULL) - surf_workstation_model->action_unref(task->surf_action); - - if (task->workstation_list != NULL) - xbt_free(task->workstation_list); - - if (task->communication_amount) - xbt_free(task->communication_amount); - - if (task->computation_amount) - xbt_free(task->computation_amount); - -#ifdef HAVE_TRACING - TRACE_sd_task_destroy(task); -#endif - - xbt_dynar_free(&task->tasks_before); - xbt_dynar_free(&task->tasks_after); - xbt_free(task); - - sd_global->task_number--; - - XBT_DEBUG("Task destroyed."); -} - - static XBT_INLINE SD_task_t SD_task_create_sized(const char *name, void *data, double amount, int ws_count) -- 2.20.1