Beispiel #1
0
static void sched_run(ABT_sched sched)
{
    uint32_t work_count = 0;
    sched_data *p_data;
    int num_pools;
    ABT_pool *p_pools;
    ABT_unit unit;
    int target;
    unsigned seed = time(NULL);
    CNT_DECL(run_cnt);

    ABTI_xstream *p_xstream = ABTI_local_get_xstream();
    ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);

    ABT_sched_get_data(sched, (void **)&p_data);
    ABT_sched_get_num_pools(sched, &num_pools);
    p_pools = (ABT_pool *)ABTU_malloc(num_pools * sizeof(ABT_pool));
    ABT_sched_get_pools(sched, num_pools, 0, p_pools);

    while (1) {
        CNT_INIT(run_cnt, 0);

        /* Execute one work unit from the scheduler's pool */
        ABT_pool pool = p_pools[0];
        ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
        size_t size = ABTI_pool_get_size(p_pool);
        if (size > 0) {
            unit = ABTI_pool_pop(p_pool);
            if (unit != ABT_UNIT_NULL) {
                ABTI_xstream_run_unit(p_xstream, unit, p_pool);
                CNT_INC(run_cnt);
            }
        } else if (num_pools > 1) {
            /* Steal a work unit from other pools */
            target = (num_pools == 2) ? 1 : (rand_r(&seed) % (num_pools-1) + 1);
            pool = p_pools[target];
            p_pool = ABTI_pool_get_ptr(pool);
            size = ABTI_pool_get_size(p_pool);
            if (size > 0) {
                unit = ABTI_pool_pop(p_pool);
                LOG_EVENT_POOL_POP(p_pool, unit);
                if (unit != ABT_UNIT_NULL) {
                    ABT_unit_set_associated_pool(unit, pool);
                    ABTI_xstream_run_unit(p_xstream, unit, p_pool);
                    CNT_INC(run_cnt);
                }
            }
        }

        if (++work_count >= p_data->event_freq) {
            ABT_bool stop = ABTI_sched_has_to_stop(p_sched, p_xstream);
            if (stop == ABT_TRUE) break;
            work_count = 0;
            ABTI_xstream_check_events(p_xstream, sched);
            SCHED_SLEEP(run_cnt, p_data->sleep_time);
        }
    }

    ABTU_free(p_pools);
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    ABT_xstream xstreams[NUM_XSTREAMS];
    ABT_sched   scheds[NUM_XSTREAMS];
    int         num_pools[NUM_XSTREAMS];
    ABT_pool   *pools[NUM_XSTREAMS];
    int i, k;

    ABT_init(argc, argv);

    /* Create schedulers */
    for (i = 0; i < NUM_XSTREAMS; i++) {
        ABT_sched_predef predef;
        predef = (i % 2) ? ABT_SCHED_BASIC : ABT_SCHED_PRIO;
        ABT_sched_create_basic(predef, 0, NULL, ABT_SCHED_CONFIG_NULL,
                               &scheds[i]);
    }

    /* Create ESs */
    ABT_xstream_self(&xstreams[0]);
    ABT_xstream_set_main_sched(xstreams[0], scheds[0]);
    for (i = 1; i < NUM_XSTREAMS; i++) {
        ABT_xstream_create(scheds[i], &xstreams[i]);
    }

    /* Get the pools associated with each scheduler */
    for (i = 0; i < NUM_XSTREAMS; i++) {
        ABT_sched_get_num_pools(scheds[i], &num_pools[i]);
        pools[i] = (ABT_pool *)malloc(num_pools[i] * sizeof(ABT_pool));
        ABT_sched_get_pools(scheds[i], num_pools[i], 0, pools[i]);
    }

    /* Create ULTs */
    for (i = 0; i < NUM_XSTREAMS; i++) {
        for (k = num_pools[i] - 1; k >= 0; k--) {
            size_t tid = (i + 1) * 10 + k;
            ABT_thread_create(pools[i][k], thread_hello, (void *)tid,
                              ABT_THREAD_ATTR_NULL, NULL);
        }
    }

    /* Join & Free */
    for (i = 1; i < NUM_XSTREAMS; i++) {
        ABT_xstream_join(xstreams[i]);
        ABT_xstream_free(&xstreams[i]);
    }

    for (i = 0; i < NUM_XSTREAMS; i++) {
        free(pools[i]);
    }

    ABT_finalize();

    return 0;
}
Beispiel #3
0
static void sched_run(ABT_sched sched)
{
    uint32_t work_count = 0;
    void *data;
    sched_data_t *p_data;
    ABT_pool my_pool;
    size_t size;
    ABT_unit unit;
    uint32_t event_freq;
    int num_pools;
    ABT_pool *pools;

    ABT_sched_get_data(sched, &data);
    p_data = sched_data_get_ptr(data);
    event_freq = p_data->event_freq;

    ABT_sched_get_num_pools(sched, &num_pools);

    pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_pools);
    ABT_sched_get_pools(sched, num_pools, 0, pools);
    my_pool = pools[0];

    while (1) {
        /* Execute one work unit from the scheduler's pool */
        ABT_pool_pop(my_pool, &unit);
        if (unit != ABT_UNIT_NULL) {
            ABT_xstream_run_unit(unit, my_pool);
        } else if (num_pools > 1) {
            /* Steal a work unit from other pools */
            int target = (num_pools == 2) ? 1 : (rand() % (num_pools - 1) + 1);
            ABT_pool tar_pool = pools[target];
            ABT_pool_get_size(tar_pool, &size);
            if (size > 0) {
                /* Pop one work unit */
                ABT_pool_pop(tar_pool, &unit);
                if (unit != ABT_UNIT_NULL) {
                    ABT_xstream_run_unit(unit, tar_pool);
                }
            }
        }

        if (++work_count >= event_freq) {
            abt_check_events(p_data->idx);

            ABT_bool stop;
            ABT_sched_has_to_stop(sched, &stop);
            if (stop == ABT_TRUE) break;
            work_count = 0;
            ABT_xstream_check_events(sched);
        }
    }

    free(pools);
}
Beispiel #4
0
static void sched_run(ABT_sched sched)
{
    uint32_t work_count = 0;
    sched_data_t *p_data;
    ABT_pool my_pool;
    int num_pools;
    ABT_pool *pools;
    ABT_unit unit;
    int target;
    ABT_bool stop;
    unsigned seed = time(NULL);

    ABT_sched_get_data(sched, (void **)&p_data);
    ABT_sched_get_num_pools(sched, &num_pools);
    pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_pools);
    ABT_sched_get_pools(sched, num_pools, 0, pools);
    my_pool = pools[0];

    while (1) {
        /* Execute one work unit from the scheduler's pool */
        ABT_pool_pop(my_pool, &unit);
        if (unit != ABT_UNIT_NULL) {
            ABT_xstream_run_unit(unit, my_pool);
        } else if (num_pools > 1) {
            /* Steal a work unit from other pools */
            target = (num_pools == 2) ? 1 : (rand_r(&seed) % (num_pools-1) + 1);
            ABT_pool_pop(pools[target], &unit);
            if (unit != ABT_UNIT_NULL) {
                ABT_xstream_run_unit(unit, pools[target]);
            }
        }

        if (++work_count >= p_data->event_freq) {
            work_count = 0;
            ABT_xstream_check_events(sched);
            ABT_sched_has_to_stop(sched, &stop);
            if (stop == ABT_TRUE) {
                /* TODO: Migrate work units if we have private pools */
                break;
            }
        }
    }

    free(pools);
}
Beispiel #5
0
static void create_scheds_and_xstreams(void)
{
    int i, k, ret;
    int num_scheds = g_data.num_scheds;
    ABT_sched *scheds = g_data.scheds;
    int *num_pools = g_data.num_pools;
    ABT_pool **pools = g_data.pools;
    ABT_xstream *xstreams = g_data.xstreams;

    for (i = 0; i < num_scheds; i++) {
        if (i == num_scheds-1) {
            /* Create pools and then create a scheduler */
            num_pools[i] = 2;
            pools[i] = (ABT_pool *)malloc(num_pools[i] * sizeof(ABT_pool));
            pools[i][0] = ABT_POOL_NULL;
            for (k = 1; k < num_pools[i]; k++) {
                ret = ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPSC,
                                            ABT_TRUE, &pools[i][k]);
                ABT_TEST_ERROR(ret, "ABT_pool_create_basic");
            }

            ret = ABT_sched_create_basic(ABT_SCHED_PRIO, num_pools[i], pools[i],
                                         ABT_SCHED_CONFIG_NULL,
                                         &scheds[i]);
            ABT_TEST_ERROR(ret, "ABT_sched_create_basic");
        } else {
            /* Create a scheduler and then get the list of pools */
            ABT_sched_config config;
            ret = ABT_sched_config_create(&config,
                                          ABT_sched_config_access, accesses[i],
                                          ABT_sched_config_var_end);
            ABT_TEST_ERROR(ret, "ABT_sched_config_create");
            ret = ABT_sched_create_basic(ABT_SCHED_PRIO, 0, NULL, config,
                                         &scheds[i]);
            ABT_TEST_ERROR(ret, "ABT_sched_create_basic");
            ret = ABT_sched_config_free(&config);
            ABT_TEST_ERROR(ret, "ABT_sched_config_free");

            ret = ABT_sched_get_num_pools(scheds[i], &num_pools[i]);
            ABT_TEST_ERROR(ret, "ABT_sched_get_num_pools");
            pools[i] = (ABT_pool *)malloc(num_pools[i] * sizeof(ABT_pool));
        }
        ret = ABT_sched_get_pools(scheds[i], num_pools[i], 0, pools[i]);
        ABT_TEST_ERROR(ret, "ABT_sched_get_pools");

        /* Create ES */
        if (i == 0) {
            ret = ABT_xstream_self(&xstreams[i]);
            ABT_TEST_ERROR(ret, "ABT_xstream_self");
            ret = ABT_xstream_set_main_sched(xstreams[i], scheds[i]);
            ABT_TEST_ERROR(ret, "ABT_xstream_set_main_sched");
        } else {
            /* If the predefined scheduler is associated with PW pools,
               we will stack it so that the primary ULT can add the initial
               work unit. */
            if (accesses[i] == ABT_POOL_ACCESS_PRIV ||
                accesses[i] == ABT_POOL_ACCESS_SPSC ||
                accesses[i] == ABT_POOL_ACCESS_SPMC) {
                ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]);
                ABT_TEST_ERROR(ret, "ABT_xstream_create");
            } else {
                ret = ABT_xstream_create(scheds[i], &xstreams[i]);
                ABT_TEST_ERROR(ret, "ABT_xstream_create");
            }
        }
    }
}