Esempio n. 1
0
static int bomp_thread_fn(void *xdata)
{
    struct bomp_work *work_data = xdata;

    backend_set_numa(work_data->thread_id);

    bomp_set_tls(work_data);
    work_data->fn(work_data->data);

    /* Wait for the Barrier */
    bomp_barrier_wait(work_data->barrier);
    return 0;
}
Esempio n. 2
0
void bomp_start_processing(void (*fn) (void *), void *data, unsigned nthreads)
{
    /* Create Threads and ask them to process the function specified */
    /* Let them die as soon as they are done */
    unsigned i;
    struct bomp_work *xdata;
    struct bomp_barrier *barrier;

    g_thread_numbers = nthreads;

    char *memory = calloc(1, nthreads * sizeof(struct bomp_thread_local_data *)
                            + sizeof(struct bomp_barrier)
                            + nthreads * sizeof(struct bomp_work));
    assert(memory != NULL);

    g_array_thread_local_data = (struct bomp_thread_local_data **)memory;
    memory += nthreads * sizeof(struct bomp_thread_local_data *);


    /* Create a barier for the work that will be carried out by the threads */
    barrier = (struct bomp_barrier *)memory;
    memory += sizeof(struct bomp_barrier);
    bomp_barrier_init(barrier, nthreads);

    /* For main thread */
    xdata = (struct bomp_work * )memory;
    memory += sizeof(struct bomp_work);

    xdata->fn = fn;
    xdata->data = data;
    xdata->thread_id = 0;
    xdata->barrier = barrier;
    bomp_set_tls(xdata);

    for (i = 1; i < nthreads; i++) {
        xdata = (struct bomp_work *)memory;
        memory += sizeof(struct bomp_work);

        xdata->fn = fn;
        xdata->data = data;
        xdata->thread_id = i;
        xdata->barrier = barrier;

        /* Create threads */
        backend_run_func_on(i + THREAD_OFFSET, bomp_thread_fn, xdata);
    }
}
Esempio n. 3
0
void bomp_start_processing(void (*fn)(void *),
                           void *data,
                           coreid_t tid_start,
                           coreid_t nthreads)
{
    struct bomp_tls *tls = thread_get_tls();

    debug_printf("bomp_start_processing(%p, %p, %u, %u)\n", fn, data, tid_start, nthreads);

    /* this function must only be called by the program and node masters */
    assert(tls->role == BOMP_THREAD_ROLE_MASTER || tls->role == BOMP_THREAD_ROLE_NODE);

    /* add one to the tid_start as this will be our ID */
    coreid_t tid_current = tid_start + 1;

    struct bomp_node *node;

    if (tls->role == BOMP_THREAD_ROLE_MASTER) {
        node = &tls->r.master.local;

        if (nthreads > (node->threads_max + 1)) {
            /* send the requests to the node masters */
            nthreads -= (node->threads_max + 1);
            for (nodeid_t i = 0; i < tls->r.master.num_nodes; ++i) {
                coreid_t num = bomp_node_exec(&tls->r.master.nodes[i], fn, data, tid_start, nthreads);
                assert(num <= nthreads);
                tls->r.master.nodes_active++;
                nthreads -= num;
                tid_current += num;
                if (nthreads == 0) {
                    break;
                }
            }
            nthreads += (node->threads_max);
        }
    } else if (tls->role == BOMP_THREAD_ROLE_NODE) {
        node = &tls->r.node;
    }

    debug_printf("nthreads=%u, max_threads=%u\n", nthreads, node->threads_max);

    assert((node->threads_max + 1)>= nthreads);

    struct omp_icv_task *icv = bomp_icv_get()->task;

    for (coreid_t i = 1; i < nthreads; ++i) {
        node->threads[i].icvt = icv;
        node->threads_active++;
        bomp_thread_exec(&node->threads[i], fn, data, tid_current);
        tid_current++;
    }

    /* set the local thread ID */
    tls->thread_id = 0;

    return;
#if 0
    /* Create Threads and ask them to process the function specified */
    /* Let them die as soon as they are done */
    unsigned i;
    struct bomp_work *xdata;
    struct bomp_barrier *barrier;

    g_bomp_state->num_threads = nthreads;

    char *memory = calloc(
                    1,
                    nthreads * sizeof(struct bomp_thread_local_data *)
                                    + sizeof(struct bomp_barrier)
                                    + nthreads * sizeof(struct bomp_work));
    assert(memory != NULL);

    g_bomp_state->tld = (struct bomp_thread_local_data **) memory;
    memory += nthreads * sizeof(struct bomp_thread_local_data *);

    /* Create a barier for the work that will be carried out by the threads */
    barrier = (struct bomp_barrier *) memory;
    memory += sizeof(struct bomp_barrier);
    bomp_barrier_init(barrier, nthreads);

    /* For main thread */
    xdata = (struct bomp_work *) memory;
    memory += sizeof(struct bomp_work);

    xdata->fn = fn;
    xdata->data = data;
    xdata->thread_id = 0;
    xdata->barrier = barrier;
    bomp_set_tls(xdata);

    for (i = 1; i < nthreads; i++) {
        xdata = (struct bomp_work *) memory;
        memory += sizeof(struct bomp_work);

        xdata->fn = fn;
        xdata->data = data;
        xdata->thread_id = i;
        xdata->barrier = barrier;

        /* Create threads */
        bomp_run_on(i * BOMP_DEFAULT_CORE_STRIDE + THREAD_OFFSET, bomp_thread_fn,
                    xdata);
    }
#endif
}