/* binary search for insertion point */ static ompi_osc_rdma_region_t *find_insertion_point (ompi_osc_rdma_region_t *regions, int min_index, int max_index, intptr_t base, size_t region_size, int *region_index) { int mid_index = (max_index + min_index) >> 1; ompi_osc_rdma_region_t *region = (ompi_osc_rdma_region_t *)((intptr_t) regions + mid_index * region_size); if (max_index < min_index) { *region_index = mid_index; return region; } if (region->base > base) { return find_insertion_point (regions, min_index, mid_index-1, base, region_size, region_index); } else { return find_insertion_point (regions, mid_index+1, max_index, base, region_size, region_index); } }
/* binary search for insertion point */ static ompi_osc_rdma_region_t *find_insertion_point (ompi_osc_rdma_region_t *regions, int min_index, int max_index, intptr_t base, size_t region_size, int *region_index) { int mid_index = (max_index + min_index) >> 1; ompi_osc_rdma_region_t *region = (ompi_osc_rdma_region_t *)((intptr_t) regions + mid_index * region_size); OSC_RDMA_VERBOSE(MCA_BASE_VERBOSE_TRACE, "find_insertion_point (%d, %d, %lx, %lu)\n", min_index, max_index, base, region_size); if (max_index < min_index) { *region_index = min_index; return (ompi_osc_rdma_region_t *)((intptr_t) regions + min_index * region_size); } if (region->base > base) { return find_insertion_point (regions, min_index, mid_index-1, base, region_size, region_index); } else { return find_insertion_point (regions, mid_index+1, max_index, base, region_size, region_index); } }
int ompi_osc_rdma_attach (struct ompi_win_t *win, void *base, size_t len) { ompi_osc_rdma_module_t *module = GET_MODULE(win); const int my_rank = ompi_comm_rank (module->comm); ompi_osc_rdma_peer_t *my_peer = ompi_osc_rdma_module_peer (module, my_rank); ompi_osc_rdma_region_t *region; osc_rdma_counter_t region_count; osc_rdma_counter_t region_id; void *bound; intptr_t page_size = getpagesize (); int region_index; int ret; if (module->flavor != MPI_WIN_FLAVOR_DYNAMIC) { return OMPI_ERR_RMA_FLAVOR; } if (0 == len) { /* shot-circuit 0-byte case */ return OMPI_SUCCESS; } OSC_RDMA_VERBOSE(MCA_BASE_VERBOSE_TRACE, "attach: %s, %p, %lu", win->w_name, base, (unsigned long) len); OPAL_THREAD_LOCK(&module->lock); region_count = module->state->region_count & 0xffffffffL; region_id = module->state->region_count >> 32; if (region_count == mca_osc_rdma_component.max_attach) { OPAL_THREAD_UNLOCK(&module->lock); return OMPI_ERR_RMA_ATTACH; } /* it is wasteful to register less than a page. this may allow the remote side to access more * memory but the MPI standard covers this with calling the calling behavior erroneous */ bound = (void *)OPAL_ALIGN((intptr_t) base + len, page_size, intptr_t); base = (void *)((intptr_t) base & ~(page_size - 1)); len = (size_t)((intptr_t) bound - (intptr_t) base); /* see if a matching region already exists */ region = ompi_osc_rdma_find_region_containing ((ompi_osc_rdma_region_t *) module->state->regions, 0, region_count - 1, (intptr_t) base, (intptr_t) bound, module->region_size, ®ion_index); if (NULL != region) { ++module->dynamic_handles[region_index].refcnt; OPAL_THREAD_UNLOCK(&module->lock); /* no need to invalidate remote caches */ return OMPI_SUCCESS; } /* region is in flux */ module->state->region_count = -1; opal_atomic_wmb (); ompi_osc_rdma_lock_acquire_exclusive (module, my_peer, offsetof (ompi_osc_rdma_state_t, regions_lock)); /* do a binary seach for where the region should be inserted */ if (region_count) { region = find_insertion_point ((ompi_osc_rdma_region_t *) module->state->regions, 0, region_count - 1, (intptr_t) base, module->region_size, ®ion_index); if (region_index < region_count) { memmove ((void *) ((intptr_t) region + module->region_size), region, (region_count - region_index) * module->region_size); if (module->selected_btl->btl_register_mem) { memmove (module->dynamic_handles + region_index + 1, module->dynamic_handles + region_index, (region_count - region_index) * sizeof (module->dynamic_handles[0])); } } } else { region_index = 0; region = (ompi_osc_rdma_region_t *) module->state->regions; } region->base = (intptr_t) base; region->len = len; OSC_RDMA_VERBOSE(MCA_BASE_VERBOSE_DEBUG, "attaching dynamic memory region {%p, %p} at index %d", base, (void *)((intptr_t) base + len), region_index); if (module->selected_btl->btl_register_mem) { mca_btl_base_registration_handle_t *handle; ret = ompi_osc_rdma_register (module, MCA_BTL_ENDPOINT_ANY, (void *) region->base, region->len, MCA_BTL_REG_FLAG_ACCESS_ANY, &handle); if (OPAL_UNLIKELY(OMPI_SUCCESS != ret)) { OPAL_THREAD_UNLOCK(&module->lock); return OMPI_ERR_RMA_ATTACH; } memcpy (region->btl_handle_data, handle, module->selected_btl->btl_registration_handle_size); module->dynamic_handles[region_index].btl_handle = handle; } else { module->dynamic_handles[region_index].btl_handle = NULL; } module->dynamic_handles[region_index].refcnt = 1; #if OPAL_ENABLE_DEBUG for (int i = 0 ; i < region_count + 1 ; ++i) { region = (ompi_osc_rdma_region_t *) ((intptr_t) module->state->regions + i * module->region_size); OSC_RDMA_VERBOSE(MCA_BASE_VERBOSE_DEBUG, " dynamic region %d: {%p, %lu}", i, (void *) region->base, (unsigned long) region->len); } #endif opal_atomic_mb (); /* the region state has changed */ module->state->region_count = ((region_id + 1) << 32) | (region_count + 1); ompi_osc_rdma_lock_release_exclusive (module, my_peer, offsetof (ompi_osc_rdma_state_t, regions_lock)); OPAL_THREAD_UNLOCK(&module->lock); OSC_RDMA_VERBOSE(MCA_BASE_VERBOSE_TRACE, "attach complete"); return OMPI_SUCCESS; }
struct work_task *set_task( enum work_type type, long event_id, /* I - based on type can be time of event */ void (*func)(), void *parm, int get_lock) { work_task *pnew; work_task *pold; if ((pnew = (struct work_task *)calloc(1, sizeof(struct work_task))) == NULL) { return(NULL); } pnew->wt_event = event_id; pnew->wt_type = type; pnew->wt_func = func; pnew->wt_parm1 = parm; if (type == WORK_Immed) { enqueue_threadpool_request((void *(*)(void *))func,pnew); } else { if (pnew->wt_mutex == NULL) { if ((pnew->wt_mutex = calloc(1, sizeof(pthread_mutex_t))) == NULL) { free(pnew); return(NULL); } } pthread_mutex_init(pnew->wt_mutex,NULL); pthread_mutex_lock(pnew->wt_mutex); if (type == WORK_Timed) { unsigned char inserted = FALSE; while (inserted != TRUE) { pold = find_insertion_point(&task_list_timed, pnew); if (pold != NULL) { if (insert_task_before(&task_list_timed, pnew, pold) == AFTER_IS_BEING_RECYCLED) continue; pthread_mutex_unlock(pold->wt_mutex); } else { insert_task(&task_list_timed, pnew); } inserted = TRUE; } } else { insert_task(&task_list_event, pnew); } /* only keep the lock if they want it */ if (get_lock == FALSE) pthread_mutex_unlock(pnew->wt_mutex); } return(pnew); } /* END set_task() */