1/** 2 * \file 3 * \brief API to use the bomp library 4 */ 5 6/* 7 * Copyright (c)2014 ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <bomp_internal.h> 16 17void bomp_start_processing(void (*fn)(void *), 18 void *data, 19 coreid_t tid_start, 20 coreid_t nthreads) 21{ 22 struct bomp_tls *tls = thread_get_tls(); 23 24 debug_printf("bomp_start_processing(%p, %p, %u, %u)\n", fn, data, tid_start, nthreads); 25 26 /* this function must only be called by the program and node masters */ 27 assert(tls->role == BOMP_THREAD_ROLE_MASTER || tls->role == BOMP_THREAD_ROLE_NODE); 28 29 /* add one to the tid_start as this will be our ID */ 30 coreid_t tid_current = tid_start + 1; 31 32 struct bomp_node *node; 33 34 if (tls->role == BOMP_THREAD_ROLE_MASTER) { 35 node = &tls->r.master.local; 36 37 if (nthreads > (node->threads_max + 1)) { 38 /* send the requests to the node masters */ 39 nthreads -= (node->threads_max + 1); 40 for (nodeid_t i = 0; i < tls->r.master.num_nodes; ++i) { 41 coreid_t num = bomp_node_exec(&tls->r.master.nodes[i], fn, data, tid_start, nthreads); 42 assert(num <= nthreads); 43 tls->r.master.nodes_active++; 44 nthreads -= num; 45 tid_current += num; 46 if (nthreads == 0) { 47 break; 48 } 49 } 50 nthreads += (node->threads_max); 51 } 52 } else if (tls->role == BOMP_THREAD_ROLE_NODE) { 53 node = &tls->r.node; 54 } 55 56 debug_printf("nthreads=%u, max_threads=%u\n", nthreads, node->threads_max); 57 58 assert((node->threads_max + 1)>= nthreads); 59 60 struct omp_icv_task *icv = bomp_icv_get()->task; 61 62 for (coreid_t i = 1; i < nthreads; ++i) { 63 node->threads[i].icvt = icv; 64 node->threads_active++; 65 bomp_thread_exec(&node->threads[i], fn, data, tid_current); 66 tid_current++; 67 } 68 69 /* set the local thread ID */ 70 tls->thread_id = 0; 71 72 return; 73#if 0 74 /* Create Threads and ask them to process the function specified */ 75 /* Let them die as soon as they are done */ 76 unsigned i; 77 struct bomp_work *xdata; 78 struct bomp_barrier *barrier; 79 80 g_bomp_state->num_threads = nthreads; 81 82 char *memory = calloc( 83 1, 84 nthreads * sizeof(struct bomp_thread_local_data *) 85 + sizeof(struct bomp_barrier) 86 + nthreads * sizeof(struct bomp_work)); 87 assert(memory != NULL); 88 89 g_bomp_state->tld = (struct bomp_thread_local_data **) memory; 90 memory += nthreads * sizeof(struct bomp_thread_local_data *); 91 92 /* Create a barier for the work that will be carried out by the threads */ 93 barrier = (struct bomp_barrier *) memory; 94 memory += sizeof(struct bomp_barrier); 95 bomp_barrier_init(barrier, nthreads); 96 97 /* For main thread */ 98 xdata = (struct bomp_work *) memory; 99 memory += sizeof(struct bomp_work); 100 101 xdata->fn = fn; 102 xdata->data = data; 103 xdata->thread_id = 0; 104 xdata->barrier = barrier; 105 bomp_set_tls(xdata); 106 107 for (i = 1; i < nthreads; i++) { 108 xdata = (struct bomp_work *) memory; 109 memory += sizeof(struct bomp_work); 110 111 xdata->fn = fn; 112 xdata->data = data; 113 xdata->thread_id = i; 114 xdata->barrier = barrier; 115 116 /* Create threads */ 117 bomp_run_on(i * BOMP_DEFAULT_CORE_STRIDE + THREAD_OFFSET, bomp_thread_fn, 118 xdata); 119 } 120#endif 121} 122 123void bomp_end_processing(void) 124{ 125 debug_printf("bomp_end_processing\n"); 126 struct bomp_tls *tls = thread_get_tls(); 127 struct waitset *ws = get_default_waitset(); 128 if (tls->role == BOMP_THREAD_ROLE_MASTER) { 129 struct bomp_node *node = &tls->r.master.local; 130 struct bomp_master *master = &tls->r.master; 131 while(master->nodes_active != 1 || node->threads_active != 1) { 132 event_dispatch(ws); 133 } 134 } else if (tls->role == BOMP_THREAD_ROLE_NODE) { 135 struct bomp_node *node = &tls->r.node; 136 while(node->threads_active != 0) { 137 event_dispatch(ws); 138 } 139 } 140 141 free(tls->icv.task); 142 tls->icv.task = NULL; 143 144 debug_printf("bomp_end_processing: done\n"); 145} 146