예제 #1
0
파일: randws.c 프로젝트: dsugiyama/argobots
static int sched_init(ABT_sched sched, ABT_sched_config config)
{
    int abt_errno = ABT_SUCCESS;

    /* Default settings */
    sched_data *p_data = (sched_data *)ABTU_malloc(sizeof(sched_data));
    p_data->event_freq = ABTI_global_get_sched_event_freq();
#ifdef ABT_CONFIG_USE_SCHED_SLEEP
    p_data->sleep_time.tv_sec = 0;
    p_data->sleep_time.tv_nsec = ABTI_global_get_sched_sleep_nsec();
#endif

    /* Set the variables from the config */
    ABT_sched_config_read(config, 1, &p_data->event_freq);

    abt_errno = ABT_sched_set_data(sched, (void *)p_data);
    ABTI_CHECK_ERROR(abt_errno);

  fn_exit:
    return abt_errno;

  fn_fail:
    HANDLE_ERROR_WITH_CODE("randws: sched_init", abt_errno);
    goto fn_exit;
}
예제 #2
0
int ABTI_sched_free(ABTI_sched *p_sched)
{
    int abt_errno = ABT_SUCCESS;
    int p;

    /* If sched is currently used, free is not allowed. */
    if (p_sched->used != ABTI_SCHED_NOT_USED) {
        abt_errno = ABT_ERR_SCHED;
        goto fn_fail;
    }

    /* If sched is a default provided one, it should free its pool here.
     * Otherwise, freeing the pool is the user's reponsibility. */
    for (p = 0; p < p_sched->num_pools; p++) {
        ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
        int32_t num_scheds = ABTI_pool_release(p_pool);
        if (p_pool->automatic == ABT_TRUE && num_scheds == 0) {
            abt_errno = ABT_pool_free(p_sched->pools+p);
            ABTI_CHECK_ERROR(abt_errno);
        }
    }
    ABTU_free(p_sched->pools);

    /* Free the associated work unit */
    if (p_sched->type == ABT_SCHED_TYPE_ULT) {
        if (p_sched->p_thread) {
            if (p_sched->p_thread->type == ABTI_THREAD_TYPE_MAIN_SCHED) {
                ABTI_thread_free_main_sched(p_sched->p_thread);
            } else {
                ABTI_thread_free(p_sched->p_thread);
            }
        }
    } else if (p_sched->type == ABT_SCHED_TYPE_TASK) {
        if (p_sched->p_task) {
            ABTI_task_free(p_sched->p_task);
        }
    }

    LOG_EVENT("[S%" PRIu64 "] freed\n", p_sched->id);

    p_sched->free(ABTI_sched_get_handle(p_sched));
    p_sched->data = NULL;

    ABTU_free(p_sched);

  fn_exit:
    return abt_errno;

  fn_fail:
    HANDLE_ERROR_FUNC_WITH_CODE(abt_errno);
    goto fn_exit;
}
예제 #3
0
/**
 * @ingroup SCHED
 * @brief   Release the scheduler object associated with sched handle.
 *
 * If this routine successfully returns, sched is set as ABT_SCHED_NULL. The
 * scheduler will be automatically freed.
 * If \c sched is currently being used by an ES or in a pool, freeing \c sched
 * is not allowed. In this case, this routine fails and returns \c
 * ABT_ERR_SCHED.
 *
 * @param[in,out] sched  handle to the target scheduler
 * @return Error code
 * @retval ABT_SUCCESS on success
 */
int ABT_sched_free(ABT_sched *sched)
{
    int abt_errno = ABT_SUCCESS;
    ABTI_sched *p_sched = ABTI_sched_get_ptr(*sched);
    ABTI_CHECK_NULL_SCHED_PTR(p_sched);

    /* Free the scheduler */
    abt_errno = ABTI_sched_free(p_sched);
    ABTI_CHECK_ERROR(abt_errno);

    /* Return value */
    *sched = ABT_SCHED_NULL;

  fn_exit:
    return abt_errno;

  fn_fail:
    HANDLE_ERROR_FUNC_WITH_CODE(abt_errno);
    goto fn_exit;
}
예제 #4
0
/**
 * @ingroup SCHED
 * @brief   Create a new user-defined scheduler and return its handle through
 * newsched.
 *
 * The pools used by the new scheduler are provided by \c pools. The contents
 * of this array is copied, so it can be freed. If a pool in the array is
 * ABT_POOL_NULL, the corresponding pool is automatically created.
 * The config must have been created by ABT_sched_config_create, and will be
 * used as argument in the initialization. If no specific configuration is
 * required, the parameter will be ABT_CONFIG_NULL.
 *
 * @param[in]  def       definition required for scheduler creation
 * @param[in]  num_pools number of pools associated with this scheduler
 * @param[in]  pools     pools associated with this scheduler
 * @param[in]  config    specific config used during the scheduler creation
 * @param[out] newsched handle to a new scheduler
 * @return Error code
 * @retval ABT_SUCCESS on success
 */
int ABT_sched_create(ABT_sched_def *def, int num_pools, ABT_pool *pools,
                     ABT_sched_config config, ABT_sched *newsched)
{
    int abt_errno = ABT_SUCCESS;
    ABTI_sched *p_sched;
    int p;

    ABTI_CHECK_TRUE(newsched != NULL, ABT_ERR_SCHED);

    p_sched = (ABTI_sched *)ABTU_malloc(sizeof(ABTI_sched));

    /* Copy of the contents of pools */
    ABT_pool *pool_list;
    pool_list = (ABT_pool *)ABTU_malloc(num_pools*sizeof(ABT_pool));
    for (p = 0; p < num_pools; p++) {
        if (pools[p] == ABT_POOL_NULL) {
            abt_errno = ABT_pool_create_basic(ABT_POOL_FIFO,
                                              ABT_POOL_ACCESS_MPSC,
                                              ABT_TRUE, &pool_list[p]);
            ABTI_CHECK_ERROR(abt_errno);
        } else {
            pool_list[p] = pools[p];
        }
    }

    /* Check if the pools are available */
    for (p = 0; p < num_pools; p++) {
        ABTI_pool_retain(ABTI_pool_get_ptr(pool_list[p]));
    }

    p_sched->used          = ABTI_SCHED_NOT_USED;
    p_sched->automatic     = ABT_FALSE;
    p_sched->kind          = ABTI_sched_get_kind(def);
    p_sched->state         = ABT_SCHED_STATE_READY;
    p_sched->request       = 0;
    p_sched->pools         = pool_list;
    p_sched->num_pools     = num_pools;
    p_sched->type          = def->type;
    p_sched->p_thread      = NULL;
    p_sched->p_task        = NULL;
    p_sched->p_ctx         = NULL;

    p_sched->init          = def->init;
    p_sched->run           = def->run;
    p_sched->free          = def->free;
    p_sched->get_migr_pool = def->get_migr_pool;

#ifdef ABT_CONFIG_USE_DEBUG_LOG
    p_sched->id            = ABTI_sched_get_new_id();
#endif
    LOG_EVENT("[S%" PRIu64 "] created\n", p_sched->id);

    /* Return value */
    *newsched = ABTI_sched_get_handle(p_sched);

    /* Specific initialization */
    p_sched->init(*newsched, config);

  fn_exit:
    return abt_errno;

  fn_fail:
    *newsched = ABT_SCHED_NULL;
    HANDLE_ERROR_FUNC_WITH_CODE(abt_errno);
    goto fn_exit;
}
예제 #5
0
/**
 * @ingroup SCHED
 * @brief   Create a predefined scheduler.
 *
 * \c ABT_sched_create_basic() creates a predefined scheduler and returns its
 * handle through \c newsched.  The pools used by the new scheduler are
 * provided by \c pools.  The contents of this array is copied, so it can be
 * freed. If a pool in the array is \c ABT_POOL_NULL, the corresponding pool is
 * automatically created.  The pool array can be \c NULL.  In this case, all
 * the pools will be created automatically.  The config must have been created
 * by \c ABT_sched_config_create(), and will be used as argument in the
 * initialization. If no specific configuration is required, the parameter can
 * be \c ABT_CONFIG_NULL.
 *
 * NOTE: The new scheduler will be automatically freed when it is not used
 * anymore or its associated ES is terminated.  Accordingly, the pools
 * associated with the new scheduler will be automatically freed if they are
 * exclusive to the scheduler and are not user-defined ones (i.e., created by
 * \c ABT_pool_create_basic() or implicitly created because \c pools is \c NULL
 * or a pool in the \c pools array is \c ABT_POOL_NULL).  If the pools were
 * created using \c ABT_pool_create() by the user, they have to be freed
 * explicitly with \c ABT_pool_free().
 *
 * @param[in]  predef    predefined scheduler
 * @param[in]  num_pools number of pools associated with this scheduler
 * @param[in]  pools     pools associated with this scheduler
 * @param[in]  config    specific config used during the scheduler creation
 * @param[out] newsched  handle to a new scheduler
 * @return Error code
 * @retval ABT_SUCCESS on success
 */
int ABT_sched_create_basic(ABT_sched_predef predef, int num_pools,
                           ABT_pool *pools, ABT_sched_config config,
                           ABT_sched *newsched)
{
    int abt_errno = ABT_SUCCESS;
    ABT_pool_access access;
    ABT_bool automatic;
    int p;

    /* We set the access to the default one */
    access = ABT_POOL_ACCESS_MPSC;
    automatic = ABT_TRUE;;
    /* We read the config and set the configured parameters */
    abt_errno = ABTI_sched_config_read_global(config, &access, &automatic);
    ABTI_CHECK_ERROR(abt_errno);

    /* A pool array is provided, predef has to be compatible */
    if (pools != NULL) {
        /* Copy of the contents of pools */
        ABT_pool *pool_list;
        pool_list = (ABT_pool *)ABTU_malloc(num_pools*sizeof(ABT_pool));
        for (p = 0; p < num_pools; p++) {
            if (pools[p] == ABT_POOL_NULL) {
                abt_errno = ABT_pool_create_basic(ABT_POOL_FIFO, access,
                                                  ABT_TRUE, &pool_list[p]);
                ABTI_CHECK_ERROR(abt_errno);
            } else {
                pool_list[p] = pools[p];
            }
        }

        /* Creation of the scheduler */
        switch (predef) {
            case ABT_SCHED_DEFAULT:
            case ABT_SCHED_BASIC:
                abt_errno = ABT_sched_create(ABTI_sched_get_basic_def(),
                                             num_pools, pool_list,
                                             ABT_SCHED_CONFIG_NULL,
                                             newsched);
                break;
            case ABT_SCHED_PRIO:
                abt_errno = ABT_sched_create(ABTI_sched_get_prio_def(),
                                             num_pools, pool_list,
                                             ABT_SCHED_CONFIG_NULL,
                                             newsched);
                break;
            case ABT_SCHED_RANDWS:
                abt_errno = ABT_sched_create(ABTI_sched_get_randws_def(),
                                             num_pools, pool_list,
                                             ABT_SCHED_CONFIG_NULL,
                                             newsched);
                break;
            default:
                abt_errno = ABT_ERR_INV_SCHED_PREDEF;
                break;
        }
        ABTI_CHECK_ERROR(abt_errno);
        ABTU_free(pool_list);
    }

    /* No pool array is provided, predef has to be compatible */
    else {
        /* Set the number of pools */
        switch (predef) {
            case ABT_SCHED_DEFAULT:
            case ABT_SCHED_BASIC:
                num_pools = 1;
                break;
            case ABT_SCHED_PRIO:
                num_pools = ABTI_SCHED_NUM_PRIO;
                break;
            case ABT_SCHED_RANDWS:
                num_pools = 1;
                break;
            default:
                abt_errno = ABT_ERR_INV_SCHED_PREDEF;
                ABTI_CHECK_ERROR(abt_errno);
                break;
        }

        /* Creation of the pools */
        /* To avoid the malloc overhead, we use a stack array. */
        ABT_pool pool_list[ABTI_SCHED_NUM_PRIO];
        int p;
        for (p = 0; p < num_pools; p++) {
            abt_errno = ABT_pool_create_basic(ABT_POOL_FIFO, access, ABT_TRUE,
                                              pool_list+p);
            ABTI_CHECK_ERROR(abt_errno);
        }

        /* Creation of the scheduler */
        switch (predef) {
            case ABT_SCHED_DEFAULT:
            case ABT_SCHED_BASIC:
                abt_errno = ABT_sched_create(ABTI_sched_get_basic_def(),
                                             num_pools, pool_list,
                                             config, newsched);
                break;
            case ABT_SCHED_PRIO:
                abt_errno = ABT_sched_create(ABTI_sched_get_prio_def(),
                                             num_pools, pool_list,
                                             config, newsched);
                break;
            case ABT_SCHED_RANDWS:
                abt_errno = ABT_sched_create(ABTI_sched_get_randws_def(),
                                             num_pools, pool_list,
                                             config, newsched);
                break;
            default:
                abt_errno = ABT_ERR_INV_SCHED_PREDEF;
                ABTI_CHECK_ERROR(abt_errno);
                break;
        }
    }
    ABTI_CHECK_ERROR(abt_errno);

    ABTI_sched *p_sched = ABTI_sched_get_ptr(*newsched);
    p_sched->automatic = automatic;

  fn_exit:
    return abt_errno;

  fn_fail:
    HANDLE_ERROR_FUNC_WITH_CODE(abt_errno);
    *newsched = ABT_SCHED_NULL;
    goto fn_exit;
}