diff options
Diffstat (limited to 'usr/src/uts/sun4u/io/wrsm/wrsm_barrier.c')
| -rw-r--r-- | usr/src/uts/sun4u/io/wrsm/wrsm_barrier.c | 811 |
1 files changed, 811 insertions, 0 deletions
diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_barrier.c b/usr/src/uts/sun4u/io/wrsm/wrsm_barrier.c new file mode 100644 index 0000000000..40586b6556 --- /dev/null +++ b/usr/src/uts/sun4u/io/wrsm/wrsm_barrier.c @@ -0,0 +1,811 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2001 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This file implements RSMPI barriers in the Wildcat RSM driver. + */ + +#include <sys/types.h> + +#include <sys/conf.h> +#include <sys/kmem.h> +#include <sys/ddi.h> +#include <sys/sunddi.h> +#include <sys/errno.h> +#include <sys/debug.h> +#include <sys/promif.h> + +#include <sys/wrsm_barrier.h> +#include <sys/wrsm_common.h> +#include <sys/wrsm_session.h> +#include <sys/wrsm_nc.h> +#include <sys/wrsm_memseg_impl.h> +#include <sys/wci_regs.h> + +/* + * The following macros define a DPRINTF macro which can be used to enable + * or disable various levels of logging for this module. + */ +#ifdef DEBUG + +#define BARDBG 0x1 +#define BARWARN 0x2 +#define BARERR 0x4 +#define BARTRACE 0x8 +static uint_t wrsm_bar_debug = BARERR; + +#define DPRINTF(a, b) { if (wrsm_bar_debug & a) wrsmdprintf b; } +#define PRINT_BAR(a, b) { if (wrsm_bar_debug & a) wrsm_print_barrier(b); } + +#else /* DEBUG */ + +#define DPRINTF(a, b) { } +#define PRINT_BAR(a, b) { } + +#endif /* DEBUG */ + +#define DTRC(s) DPRINTF(BARTRACE, (CE_CONT, s)) +#define WARN(s) DPRINTF(BARWARN, (CE_WARN, s)) +#define NOTE(s) DPRINTF(BARDBG, (CE_NOTE, s)) +#define ERR(s) DPRINTF(BARERR, (CE_WARN, s)) + +/* + * Local types + */ +#define BARRIER_TIME_REGION 0 +#define BARRIER_TIME_REGIONS 1 +#define BARRIER_TIME_NODE 2 +#define BARRIER_TIME_CONTROLLER 3 +#define BARRIER_THREAD_REGION 4 +#define BARRIER_THREAD_REGIONS 5 +#define BARRIER_THREAD_NODE 6 +#define BARRIER_THREAD_CONTROLLER 7 +typedef unsigned char wrsm_barrier_scope_t; + +#ifdef DEBUG +/* The following array is used in wrsm_print_barrier, for debug only */ +static const char *scope_txt[] = { + "BARRIER_TIME_REGION", + "BARRIER_TIME_REGIONS", + "BARRIER_TIME_NODE", + "BARRIER_TIME_CONTROLLER", + "BARRIER_THREAD_REGION", + "BARRIER_THREAD_REGIONS", + "BARRIER_THREAD_NODE", + "BARRIER_THREAD_CONTROLLER"}; +#endif /* DEBUG */ + +/* Define state flags to help ensure that barrier is really initialized */ +typedef unsigned char wrsm_barrier_state_t; +#define BARRIER_CLOSED ((wrsm_barrier_state_t)0xff) +#define BARRIER_OPENED ((wrsm_barrier_state_t)0xfe) + +/* This struct is an overlay for rsm_barrier_t */ +typedef struct { + void *parent; /* network, importseg or array of importsegs */ + uint64_t init_err_count; + uint32_t reroute_counter; + uint32_t transfer_errors; + int num_regions; /* if multiple importsegs */ + wrsm_barrier_scope_t scope; + wrsm_barrier_state_t state; + cnodeid_t cnodeid; /* if node barrier */ +} wrsm_barrier_t; + +/* + * Local Functions + */ + +/* + * This function sums the wci_cluster_error_count register for all WCIs + * routing to the given ncslice (i.e., remote node). It does this by + * reading the wci_cluster_error_count mapped into the stripes of page 0 + * of the nslice. + */ +static uint64_t +sum_errors_node(caddr_t ncslice_base, int link_stripes) +{ + uint64_t total = 0; + int stripes; + caddr_t err_addr = ncslice_base + WCI_ERRPAGE_CLUSTER_ERROR_OFFSET; + + for (stripes = link_stripes; stripes; stripes = stripes >> 1) { + if (stripes & 1) { + /* Sum in errors for this stripe */ + total += *((uint64_t *)err_addr); + } + err_addr += WCI_CLUSTER_STRIPE_STRIDE; + } + return (total); +} + +/* Sums wci_cluster_error_counts for all nodes in nodes bitmask */ +static int +sum_errors_nodes(wrsm_network_t *net, wrsm_cnode_bitmask_t cnodes, + uint64_t *sum) +{ + wrsm_node_t *node; + int i; + + /* If we're in the process of rerouting, return MAX INT */ + if (*net->reroutingp) { + *sum = UINT64_MAX; + return (RSM_SUCCESS); + } + + *sum = 0; + mutex_enter(&net->lock); + /* Loop for each node in the set. Exit early once set is empty */ + for (i = 0; i < WRSM_MAX_CNODES && !WRSMSET_ISNULL(cnodes); i++) { + if (WRSM_IN_SET(cnodes, i)) { + node = net->nodes[i]; + if (node == NULL) { + mutex_exit(&net->lock); + return (RSMERR_CONN_ABORTED); + } + *sum += sum_errors_node(node->cesr_vaddr, + *node->link_stripesp); + } + /* Remove this node from the list, hoping for early exit */ + WRSMSET_DEL(cnodes, i); + } + mutex_exit(&net->lock); + return (RSM_SUCCESS); +} + +/* + * RSMPI Functions + */ +/* ARGSUSED */ +int +wrsm_open_barrier_ctrl(rsm_controller_handle_t ctrl, rsm_barrier_t *barrier) +{ + DTRC("wrsm_open_barrier_ctrl"); + /* LINTED: E_TRUE_LOGICAL_EXPR */ + ASSERT(sizeof (wrsm_barrier_t) <= sizeof (rsm_barrier_t)); + return (RSMERR_UNSUPPORTED_OPERATION); +} + +int +wrsm_open_barrier_node(rsm_controller_handle_t ctrl, rsm_addr_t addr, + rsm_barrier_t *barrier) +{ + wrsm_node_t *node; + wrsm_network_t *net = (wrsm_network_t *)ctrl; + wrsm_barrier_t *bar = (wrsm_barrier_t *)barrier; + + DPRINTF(BARTRACE, (CE_CONT, "wrsm_open_barrier_node(addr=%d)", addr)); + /* LINTED: E_TRUE_LOGICAL_EXPR */ + ASSERT(sizeof (wrsm_barrier_t) <= sizeof (rsm_barrier_t)); + + if (bar == NULL) { + return (RSMERR_BAD_BARRIER_PTR); + } + if (net == NULL) { + return (RSMERR_BAD_CTLR_HNDL); + } + if (addr >= WRSM_MAX_CNODES) { + return (RSMERR_UNKNOWN_RSM_ADDR); + } + bar->state = BARRIER_CLOSED; /* Mark as closed until we're done */ + bar->scope = BARRIER_TIME_NODE; + + mutex_enter(&net->lock); + node = net->nodes[addr]; + if (!node) { + mutex_exit(&net->lock); + return (RSMERR_UNKNOWN_RSM_ADDR); + } + /* Read route counter */ + bar->reroute_counter = *net->route_counterp; + bar->init_err_count = sum_errors_node(node->cesr_vaddr, + *node->link_stripesp); + bar->parent = (void *)net; + bar->cnodeid = (cnodeid_t)addr; + bar->transfer_errors = node->memseg->transfer_errors; + bar->state = BARRIER_OPENED; + mutex_exit(&net->lock); + + /* Make sure a session is established with the remote node */ + (void) wrsm_sess_establish(net, addr); + + PRINT_BAR(BARDBG, barrier); + return (RSM_SUCCESS); +} + +int +wrsm_open_barrier_region(rsm_memseg_import_handle_t im_memseg, + rsm_barrier_t *barrier) +{ + importseg_t *importseg; + wrsm_barrier_t *bar = (wrsm_barrier_t *)barrier; + int err; + + DTRC("wrsm_open_barrier_region"); + /* LINTED: E_TRUE_LOGICAL_EXPR */ + ASSERT(sizeof (wrsm_barrier_t) <= sizeof (rsm_barrier_t)); + + if (im_memseg == NULL) { + return (RSMERR_BAD_SEG_HNDL); + } + if (bar == NULL) { + return (RSMERR_BAD_BARRIER_PTR); + } + + /* we assume importseg will not be removed during barrier */ + importseg = (importseg_t *)im_memseg; + err = wrsm_open_barrier_node(importseg->iseginfo->network, + importseg->iseginfo->cnodeid, barrier); + bar->scope = BARRIER_TIME_REGION; + bar->parent = (void *)importseg; + bar->transfer_errors = importseg->iseginfo->transfer_errors; + bar->cnodeid = importseg->iseginfo->cnodeid; + + PRINT_BAR(BARDBG, barrier); + return (err); +} + +int +wrsm_open_barrier_regions(rsm_memseg_import_handle_t im_memseg[], + uint_t num_regions, rsm_barrier_t *barrier) +{ + importseg_t **importseg_list; + wrsm_barrier_t *bar = (wrsm_barrier_t *)barrier; + wrsm_network_t *net; + wrsm_cnode_bitmask_t cnodes; + uint_t i; + int err; + + DTRC("wrsm_open_barrier_regions"); + /* LINTED: E_TRUE_LOGICAL_EXPR */ + ASSERT(sizeof (wrsm_barrier_t) <= sizeof (rsm_barrier_t)); + + if (bar == NULL) { + return (RSMERR_BAD_BARRIER_PTR); + } + bar->state = BARRIER_CLOSED; /* Mark as closed until we're done */ + + if (num_regions == 0) { + return (RSMERR_BAD_SEG_HNDL); + } + + WRSMSET_ZERO(cnodes); + for (i = 0; i < num_regions; i++) { + if (im_memseg[i] == NULL) { + return (RSMERR_BAD_SEG_HNDL); + } + WRSMSET_ADD(cnodes, im_memseg[i]->iseginfo->cnodeid); + } + + /* we assume importsegs will not be removed during barrier */ + net = ((importseg_t *)im_memseg[0])->iseginfo->network; + bar->scope = BARRIER_TIME_REGIONS; + bar->reroute_counter = *net->route_counterp; + err = sum_errors_nodes(net, cnodes, &bar->init_err_count); + if (!err) { + bar->parent = (void *)kmem_alloc( + (num_regions * sizeof (importseg_t *)), KM_SLEEP); + bcopy(im_memseg, bar->parent, + (num_regions * sizeof (importseg_t *))); + bar->num_regions = num_regions; + importseg_list = (importseg_t **)bar->parent; + bar->transfer_errors = 0; + for (i = 0; i < num_regions; i++) { + bar->transfer_errors += + importseg_list[i]->iseginfo->transfer_errors; + } + bar->state = BARRIER_OPENED; + } + + PRINT_BAR(BARDBG, barrier); + return (err); +} + +int +wrsm_open_barrier_ctrl_thr(rsm_controller_handle_t ctrl, + rsm_barrier_t *barrier) +{ + DTRC("wrsm_open_barrier_ctrl_thr"); + return (wrsm_open_barrier_ctrl(ctrl, barrier)); +} + +int +wrsm_open_barrier_node_thr(rsm_controller_handle_t ctrl, rsm_addr_t addr, + rsm_barrier_t *barrier) +{ + DTRC("wrsm_open_barrier_node_thr"); + return (wrsm_open_barrier_node(ctrl, addr, barrier)); +} + +int +wrsm_open_barrier_region_thr(rsm_memseg_import_handle_t im_memseg, + rsm_barrier_t *barrier) +{ + DTRC("wrsm_open_barrier_region_thr"); + return (wrsm_open_barrier_region(im_memseg, barrier)); +} + +int +wrsm_open_barrier_regions_thr(rsm_memseg_import_handle_t im_memseg[], + uint_t num_regions, rsm_barrier_t *barrier) +{ + DTRC("wrsm_open_barrier_regions_thr"); + return (wrsm_open_barrier_regions(im_memseg, num_regions, barrier)); +} + +static int +close_barrier_time_node(wrsm_network_t *net, wrsm_barrier_t *bar) +{ + uint64_t error_sum; + wrsm_node_t *node; + DTRC("close_barrier_time_node"); + + /* Check to see if there were any errors */ + if (bar->init_err_count == UINT64_MAX) { + WARN("Barrier failed: error reading wci cluster error count"); + return (RSMERR_BARRIER_FAILURE); + } + mutex_enter(&net->lock); + node = net->nodes[bar->cnodeid]; + error_sum = sum_errors_node(node->cesr_vaddr, *node->link_stripesp); + mutex_exit(&net->lock); + if (bar->init_err_count != error_sum) { + WARN("Barrier failed: wci errors detected"); + return (RSMERR_BARRIER_FAILURE); + } + /* Make sure route hasn't changed */ + if (*net->reroutingp || bar->reroute_counter != *net->route_counterp) { + WARN("Barrier failed: route changed"); + return (RSMERR_BARRIER_FAILURE); + } + + return (RSM_SUCCESS); +} + +static int +close_barrier_time_nodes(wrsm_network_t *net, wrsm_barrier_t *bar, + wrsm_cnode_bitmask_t cnodes) +{ + uint64_t error_sum; + int err; + DTRC("close_barrier_time_nodes"); + + /* Check to see if there were any errors */ + if (bar->init_err_count == UINT64_MAX) { + WARN("Barrier failed: error reading wci cluster error count"); + return (RSMERR_BARRIER_FAILURE); + } + /* Sum errors for those remote nodes */ + err = sum_errors_nodes(net, cnodes, &error_sum); + if (err) { + return (err); + } + if (bar->init_err_count != error_sum) { + WARN("Barrier failed: wci errors detected"); + return (RSMERR_BARRIER_FAILURE); + } + /* Make sure route hasn't changed */ + if (*net->reroutingp || bar->reroute_counter != *net->route_counterp) { + WARN("Barrier failed: route changed"); + return (RSMERR_BARRIER_FAILURE); + } + + return (RSM_SUCCESS); +} + + +int +wrsm_close_barrier(rsm_barrier_t *barrier) +{ + wrsm_barrier_t *bar; + wrsm_network_t *net; + wrsm_node_t *node; + importseg_t *importseg; + importseg_t **importseg_list; + uint_t sum_transfer_errors = 0; + wrsm_cnode_bitmask_t cnodes; + int i; + int err = 0; + int retval = 0; + + DTRC("wrsm_close_barrier"); + PRINT_BAR(BARDBG, barrier); + + bar = (wrsm_barrier_t *)barrier; + if (bar == NULL) { + WARN("Barrier failed: barrier pointer is NULL"); + return (RSMERR_BAD_BARRIER_PTR); + } + if (bar->state != BARRIER_OPENED) { + WARN("Barrier failed: Barrier not open"); + return (RSMERR_BARRIER_NOT_OPENED); + } + bar->state = BARRIER_CLOSED; + + switch (bar->scope) { + case BARRIER_TIME_REGION: + importseg = (importseg_t *)bar->parent; + if (importseg->unpublished) { + WARN("Barrier failed: importseg was unpublished"); + return (RSMERR_CONN_ABORTED); + } + if (bar->transfer_errors != + importseg->iseginfo->transfer_errors) { + DPRINTF(BARWARN, (CE_WARN, + "Barrier failed: transfer errors; last err %d", + importseg->iseginfo->last_transfer_error)); + return (importseg->iseginfo->last_transfer_error); + } + net = importseg->iseginfo->network; + mutex_enter(&net->lock); + node = net->nodes[bar->cnodeid]; + if (node == NULL) { + WARN("Barrier failed: unknown node"); + retval = RSMERR_CONN_ABORTED; + } else { + /* Flush links to remote node */ + retval = wrsm_sess_touch_node(net, bar->cnodeid, + *node->link_stripesp); + } + mutex_exit(&net->lock); + if (retval == RSM_SUCCESS) { + retval = close_barrier_time_node(net, bar); + } + break; + + case BARRIER_TIME_REGIONS: + WRSMSET_ZERO(cnodes); + importseg_list = (importseg_t **)bar->parent; + ASSERT(importseg_list); + + /* get net from first importseg */ + net = importseg_list[0]->iseginfo->network; + + mutex_enter(&net->lock); + for (i = 0; i < bar->num_regions; i++) { + importseg = importseg_list[i]; + WRSMSET_ADD(cnodes, importseg->iseginfo->cnodeid); + if (importseg->unpublished) { + kmem_free(bar->parent, (bar->num_regions * + sizeof (importseg_t *))); + WARN("Barrier failed: importseg unpublished"); + mutex_exit(&net->lock); + return (RSMERR_CONN_ABORTED); + } + sum_transfer_errors += + importseg->iseginfo->transfer_errors; + /* Remember the first error encountered */ + if (err == 0) { + err = importseg->iseginfo->last_transfer_error; + } + if (retval == RSM_SUCCESS) { + node = net->nodes[importseg->iseginfo->cnodeid]; + if (node == NULL) { + WARN("Barrier failed: unknown node"); + retval = RSMERR_CONN_ABORTED; + } else { + /* Flush links to remote node */ + retval = wrsm_sess_touch_node(net, + importseg->iseginfo->cnodeid, + *node->link_stripesp); + } + } + } + mutex_exit(&net->lock); + kmem_free(bar->parent, + (bar->num_regions * sizeof (importseg_t *))); + if (bar->transfer_errors != sum_transfer_errors) { + DPRINTF(BARWARN, (CE_WARN, + "Barrier failed: transfer errors, last error %d", + err)); + return (err); + } + if (retval == RSM_SUCCESS) { + retval = close_barrier_time_nodes(net, bar, cnodes); + } + break; + + case BARRIER_TIME_NODE: + net = (wrsm_network_t *)bar->parent; + mutex_enter(&net->lock); + node = net->nodes[bar->cnodeid]; + if (!node) { + mutex_exit(&net->lock); + WARN("Barrier failed: node doesn't exist"); + return (RSMERR_CONN_ABORTED); + } + if (node->memseg->removing_session || + (wrsm_sess_get(net, node->config->cnodeid) == + SESS_ID_INVALID)) { + mutex_exit(&net->lock); + WARN("Barrier failed: no session to remote node"); + return (RSMERR_CONN_ABORTED); + } + if (bar->transfer_errors != node->memseg->transfer_errors) { + err = node->memseg->last_transfer_error; + DPRINTF(BARWARN, (CE_WARN, + "Barrier failed: transfer error; last err %d", + err)); + mutex_exit(&net->lock); + return (err); + } + /* Flush links to remote node */ + retval = wrsm_sess_touch_node(net, bar->cnodeid, + *node->link_stripesp); + mutex_exit(&net->lock); + if (retval == RSM_SUCCESS) { + retval = close_barrier_time_node(net, bar); + } + break; + + case BARRIER_TIME_CONTROLLER: + retval = RSMERR_UNSUPPORTED_OPERATION; + break; + + default: + ERR("Invalid barrier data"); + retval = RSMERR_BAD_BARRIER_HNDL; + } + +#ifdef DEBUG + if (retval) { + DPRINTF(BARWARN, (CE_WARN, "Barrier failed: %d", retval)); + } +#endif + return (retval); +} + +int +wrsm_reopen_barrier(rsm_barrier_t *barrier) +{ + rsm_controller_handle_t ctrl; + rsm_addr_t addr; + rsm_memseg_import_handle_t im_memseg; + rsm_memseg_import_handle_t *im_memsegp; + uint_t num_regions; + wrsm_barrier_t *bar = (wrsm_barrier_t *)barrier; + int retval; + + DTRC("wrsm_reopen_barrier"); + if (barrier == NULL) { + WARN("Barrier failed: barrier pointer is NULL"); + return (RSMERR_BAD_BARRIER_PTR); + } + switch (bar->scope) { + case BARRIER_TIME_NODE: + ctrl = bar->parent; + addr = bar->cnodeid; + retval = wrsm_close_barrier(barrier); + (void) wrsm_open_barrier_node(ctrl, addr, barrier); + break; + case BARRIER_TIME_REGION: + im_memseg = bar->parent; + retval = wrsm_close_barrier(barrier); + (void) wrsm_open_barrier_region(im_memseg, barrier); + break; + case BARRIER_TIME_REGIONS: + num_regions = bar->num_regions; + im_memsegp = (rsm_memseg_import_handle_t *)kmem_alloc( + num_regions * + sizeof (rsm_memseg_import_handle_t *), KM_SLEEP); + bcopy(bar->parent, im_memsegp, + num_regions * sizeof (rsm_memseg_import_handle_t *)); + retval = wrsm_close_barrier(barrier); + (void) wrsm_open_barrier_regions(im_memsegp, num_regions, + barrier); + kmem_free(im_memsegp, + num_regions * sizeof (rsm_memseg_import_handle_t *)); + break; + default: + retval = RSMERR_UNSUPPORTED_OPERATION; + } + return (retval); +} + +int +wrsm_order_barrier(rsm_barrier_t *barrier) +{ + wrsm_barrier_t *bar; + int i; + wrsm_network_t *net; + wrsm_node_t *node; + importseg_t *importseg; + importseg_t **importseg_list; + int retval = 0; + + DTRC("wrsm_order_barrier"); + PRINT_BAR(BARDBG, barrier); + + bar = (wrsm_barrier_t *)barrier; + if (bar == NULL) { + WARN("Barrier failed: barrier pointer is NULL"); + return (RSMERR_BAD_BARRIER_PTR); + } + if (bar->state != BARRIER_OPENED) { + WARN("Barrier failed: Barrier not open"); + return (RSMERR_BARRIER_NOT_OPENED); + } + + /* Figure out which remote cnode(s) we need to flush */ + switch (bar->scope) { + case BARRIER_TIME_REGION: + importseg = (importseg_t *)bar->parent; + net = importseg->iseginfo->network; + mutex_enter(&net->lock); + node = net->nodes[bar->cnodeid]; + if (node) { + retval = wrsm_sess_touch_node(net, bar->cnodeid, + *node->link_stripesp); + } else { + retval = RSMERR_CONN_ABORTED; + } + mutex_exit(&net->lock); + break; + + case BARRIER_TIME_REGIONS: + importseg_list = (importseg_t **)bar->parent; + ASSERT(importseg_list); + + /* get net from first importseg */ + net = importseg_list[0]->iseginfo->network; + + mutex_enter(&net->lock); + for (i = 0; i < bar->num_regions; i++) { + cnodeid_t cnode = importseg_list[i]->iseginfo->cnodeid; + node = net->nodes[cnode]; + if (node) { + int err = wrsm_sess_touch_node(net, cnode, + *node->link_stripesp); + retval = retval ? retval : err; + } else { + retval = RSMERR_CONN_ABORTED; + } + } + mutex_exit(&net->lock); + break; + + case BARRIER_TIME_NODE: + net = (wrsm_network_t *)bar->parent; + mutex_enter(&net->lock); + node = net->nodes[bar->cnodeid]; + if (node) { + retval = wrsm_sess_touch_node(net, bar->cnodeid, + *node->link_stripesp); + } else { + retval = RSMERR_CONN_ABORTED; + } + mutex_exit(&net->lock); + break; + + case BARRIER_TIME_CONTROLLER: + retval = RSMERR_UNSUPPORTED_OPERATION; + break; + + default: + ERR("Invalid barrier data"); + retval = RSMERR_BAD_BARRIER_HNDL; + } + return (retval); +} + +int +wrsm_thread_init(rsm_controller_handle_t ctrl) +{ + wrsm_network_t *net; + DTRC("wrsm_thread_init"); + + net = (wrsm_network_t *)ctrl; + if (net == NULL) { + return (RSMERR_BAD_CTLR_HNDL); + } + /* Thread Barriers not yet implemented, so nothing to do */ + return (RSM_SUCCESS); +} + +int +wrsm_thread_fini(rsm_controller_handle_t ctrl) +{ + wrsm_network_t *net; + DTRC("wrsm_thread_fini"); + + net = (wrsm_network_t *)ctrl; + if (net == NULL) { + return (RSMERR_BAD_CTLR_HNDL); + } + /* Thread Barriers not yet implemented, so nothing to do */ + return (RSM_SUCCESS); +} + +int +wrsm_get_barrier_mode(rsm_memseg_import_handle_t mem, rsm_barrier_mode_t *mode) +{ + importseg_t *importseg = (importseg_t *)mem; + int err; + + DTRC("wrsm_get_barrier_mode"); + + if ((err = wrsm_lock_importseg(importseg, RW_READER)) != RSM_SUCCESS) { + return (err); + } + + *mode = importseg->barrier_mode; + + rw_exit(&importseg->rw_lock); + return (RSM_SUCCESS); +} + +int +wrsm_set_barrier_mode(rsm_memseg_import_handle_t mem, rsm_barrier_mode_t mode) +{ + importseg_t *importseg = (importseg_t *)mem; + int err; + + DPRINTF(BARTRACE, (CE_CONT, + "wrsm_set_barrier_mode: importseg 0x%p mode %d", + (void *)importseg, mode)); + + if ((mode != RSM_BARRIER_MODE_EXPLICIT) && + mode != RSM_BARRIER_MODE_IMPLICIT) { + return (RSMERR_BAD_MODE); + } + + if ((err = wrsm_lock_importseg(importseg, RW_WRITER)) != RSM_SUCCESS) { + return (err); + } + + importseg->barrier_mode = mode; + + rw_exit(&importseg->rw_lock); + return (RSM_SUCCESS); +} + +#ifdef DEBUG +void +wrsm_print_barrier(rsm_barrier_t *barrier) +{ + wrsm_barrier_t *bar = (wrsm_barrier_t *)barrier; + + cmn_err(CE_CONT, "Barrier {"); + cmn_err(CE_CONT, " scope = %s", scope_txt[bar->scope]); + cmn_err(CE_CONT, " state = %s", + (bar->state == BARRIER_OPENED) ? "OPENED" : "CLOSED"); + cmn_err(CE_CONT, " reroute_counter = %u", bar->reroute_counter); + cmn_err(CE_CONT, " parent = 0x%p", bar->parent); + cmn_err(CE_CONT, " init_err_count = %lu", bar->init_err_count); + cmn_err(CE_CONT, " transfer_errors = %u", bar->transfer_errors); + if ((bar->scope == BARRIER_TIME_REGIONS) || + (bar->scope == BARRIER_THREAD_REGIONS)) { + cmn_err(CE_CONT, " num_regions = %u", bar->num_regions); + } + if ((bar->scope == BARRIER_TIME_NODE) || + (bar->scope == BARRIER_THREAD_NODE)) { + cmn_err(CE_CONT, " cnodeid = %u", bar->cnodeid); + } + cmn_err(CE_CONT, "}"); +} +#endif /* DEBUG */ |
