Beispiel #1
0
int ompi_attr_delete(ompi_attribute_type_t type, void *object, 
                     opal_hash_table_t *attr_hash, int key,
                     bool predefined)
{
    ompi_attribute_keyval_t *keyval;
    int ret = OMPI_SUCCESS, err;
    attribute_value_t *attr;

    /* Check if the key is valid in the master keyval hash */
    OPAL_THREAD_LOCK(&keyval_hash_lock);
    ret = opal_hash_table_get_value_uint32(keyval_hash, key, 
                                           (void **) &keyval);
    OPAL_THREAD_UNLOCK(&keyval_hash_lock);

    if ((OMPI_SUCCESS != ret) || (NULL == keyval) ||
        (keyval->attr_type!= type) ||
        ((!predefined) && (keyval->attr_flag & OMPI_KEYVAL_PREDEFINED))) {
        ret = OMPI_ERR_BAD_PARAM;
	return ret;
    }

    OPAL_THREAD_LOCK(&attr_hash_lock);
    /* Ensure that we don't have an empty attr_hash */
    if (NULL == attr_hash) {
        ret = OMPI_ERR_BAD_PARAM;
	OPAL_THREAD_UNLOCK(&attr_hash_lock);
	return ret;
    }

    /* Check if the key is valid for the communicator/window/dtype. If
       yes, then delete the attribute and key entry from the object's
       hash */

    /* Note that this function can be invoked by
       ompi_attr_delete_all() to set attributes on the new object (in
       addition to the top-level MPI_* functions that set attributes). */

    ret = opal_hash_table_get_value_uint32(attr_hash, key, (void**) &attr);
    OPAL_THREAD_UNLOCK(&attr_hash_lock);

    if (OMPI_SUCCESS == ret) {
        switch (type) {
        case COMM_ATTR:
            DELETE_ATTR_CALLBACKS(communicator, attr, keyval, object);
            break;
                
        case WIN_ATTR:
            DELETE_ATTR_CALLBACKS(win, attr, keyval, object);
            break;
                
        case TYPE_ATTR:
            DELETE_ATTR_CALLBACKS(datatype, attr, keyval, object);
            break;
                
        default:
            ret = MPI_ERR_INTERN;
            goto exit;
        }
        OBJ_RELEASE(attr);
    
	OPAL_THREAD_LOCK(&attr_hash_lock);
        ret = opal_hash_table_remove_value_uint32(attr_hash, key);
	OPAL_THREAD_UNLOCK(&attr_hash_lock);

        if (OMPI_SUCCESS != ret) {
            goto exit;
        }
    }


 exit:
    /* Decrement the ref count for the keyval.  If ref count goes to
       0, destroy the keyval (the destructor deletes the key
       implicitly for this object).  The ref count will only go to 0
       here if MPI_*_FREE_KEYVAL was previously invoked and we just
       freed the last attribute that was using the keyval. */

    if (OMPI_SUCCESS == ret) {
        OPAL_THREAD_LOCK(&keyval_hash_lock);
        OBJ_RELEASE(keyval);
        OPAL_THREAD_UNLOCK(&keyval_hash_lock);
    }

    return ret;
}
Beispiel #2
0
/*
 * Back-end function to delete a single attribute.
 *
 * Assumes that you DO already have the attribute_lock.
 */
static int ompi_attr_delete_impl(ompi_attribute_type_t type, void *object,
                                 opal_hash_table_t *attr_hash, int key,
                                 bool predefined)
{
    ompi_attribute_keyval_t *keyval;
    int ret = OMPI_SUCCESS;
    attribute_value_t *attr;

    /* Check if the key is valid in the master keyval hash */
    ret = opal_hash_table_get_value_uint32(keyval_hash, key,
                                           (void **) &keyval);

    if ((OMPI_SUCCESS != ret) || (NULL == keyval) ||
        (keyval->attr_type!= type) ||
        ((!predefined) && (keyval->attr_flag & OMPI_KEYVAL_PREDEFINED))) {
        ret = OMPI_ERR_BAD_PARAM;
        goto exit;
    }

    /* Ensure that we don't have an empty attr_hash */
    if (NULL == attr_hash) {
        ret = OMPI_ERR_BAD_PARAM;
        goto exit;
    }

    /* Check if the key is valid for the communicator/window/dtype. If
       yes, then delete the attribute and key entry from the object's
       hash */
    ret = opal_hash_table_get_value_uint32(attr_hash, key, (void**) &attr);
    if (OMPI_SUCCESS == ret) {
        switch (type) {
        case COMM_ATTR:
            DELETE_ATTR_CALLBACKS(communicator, attr, keyval, object, ret);
            break;

        case WIN_ATTR:
            DELETE_ATTR_CALLBACKS(win, attr, keyval, object, ret);
            break;

        case TYPE_ATTR:
            DELETE_ATTR_CALLBACKS(datatype, attr, keyval, object, ret);
            break;

        default:
            /* This should not happen */
            assert(0);
            break;
        }
        if (MPI_SUCCESS != ret) {
            goto exit;
        }

        /* Ignore the return value at this point; it can't help any
           more */
        (void) opal_hash_table_remove_value_uint32(attr_hash, key);
        OBJ_RELEASE(attr);
    }

 exit:
    /* Decrement the ref count for the keyval.  If ref count goes to
       0, destroy the keyval (the destructor deletes the key
       implicitly for this object).  The ref count will only go to 0
       here if MPI_*_FREE_KEYVAL was previously invoked and we just
       freed the last attribute that was using the keyval. */
    if (OMPI_SUCCESS == ret) {
        OBJ_RELEASE(keyval);
    }

    return ret;
}
Beispiel #3
0
/*
 * Back-end function to set an attribute on an MPI object
 */
static int set_value(ompi_attribute_type_t type, void *object, 
                     opal_hash_table_t **attr_hash, int key, 
                     attribute_value_t *new_attr,
                     bool predefined)
{
    ompi_attribute_keyval_t *keyval;
    int ret, err;
    attribute_value_t *old_attr;
    bool had_old = false;

    /* Note that this function can be invoked by ompi_attr_copy_all()
       to set attributes on the new object (in addition to the
       top-level MPI_* functions that set attributes). */

    OPAL_THREAD_LOCK(&keyval_hash_lock);
    ret = opal_hash_table_get_value_uint32(keyval_hash, key, 
                                           (void **) &keyval);
    OPAL_THREAD_UNLOCK(&keyval_hash_lock);

    /* If key not found */

    if ((OMPI_SUCCESS != ret ) || (NULL == keyval) || 
        (keyval->attr_type != type) ||
        ((!predefined) && (keyval->attr_flag & OMPI_KEYVAL_PREDEFINED))) {
        return OMPI_ERR_BAD_PARAM;
    }

    /* Do we need to make a new attr_hash? */
    OPAL_THREAD_LOCK(&attr_hash_lock);
    if (NULL == *attr_hash) {
        ompi_attr_hash_init(attr_hash);
    }

    /* Now see if an attribute is already present in the object's hash
       on the old keyval. If so, delete the old attribute value. */

    ret = opal_hash_table_get_value_uint32(*attr_hash, key, (void**) &old_attr);
    OPAL_THREAD_UNLOCK(&attr_hash_lock);

    if (OMPI_SUCCESS == ret)  {
        switch (type) {
        case COMM_ATTR:
            DELETE_ATTR_CALLBACKS(communicator, old_attr, keyval, object);
            break;

        case WIN_ATTR:
            DELETE_ATTR_CALLBACKS(win, old_attr, keyval, object);
            break;

        case TYPE_ATTR:
            DELETE_ATTR_CALLBACKS(datatype, old_attr, keyval, object);
            break;

        default:
            return MPI_ERR_INTERN;
        }
        had_old = true;
        OBJ_RELEASE(old_attr);
    }

    OPAL_THREAD_LOCK(&keyval_hash_lock);
    ret = opal_hash_table_get_value_uint32(keyval_hash, key,
                                           (void **) &keyval);
    if ((OMPI_SUCCESS != ret ) || (NULL == keyval)) {
	/* Keyval has disappeared underneath us. Someone must have
	   called ompi_attr_free_keyval since we last looked it up
	   in the hash. We'll behave as if we never found it in the
	   first place */
	OPAL_THREAD_UNLOCK(&keyval_hash_lock);
	return OMPI_ERR_BAD_PARAM;
    }

    OPAL_THREAD_LOCK(&attr_hash_lock);
    ret = opal_hash_table_set_value_uint32(*attr_hash, key, new_attr);
    OPAL_THREAD_UNLOCK(&attr_hash_lock);
    OPAL_THREAD_UNLOCK(&keyval_hash_lock);

    /* Increase the reference count of the object, only if there was no
       old atribute/no old entry in the object's key hash */

    if (OMPI_SUCCESS == ret && !had_old) {
        OBJ_RETAIN(keyval);
    }

    if (OMPI_SUCCESS != ret) {
        return ret;
    }

    return MPI_SUCCESS;
}
Beispiel #4
0
/*
 * Back-end function to set an attribute on an MPI object.  Assumes
 * that you already hold the attribute_lock.
 */
static int set_value(ompi_attribute_type_t type, void *object,
                     opal_hash_table_t **attr_hash, int key,
                     attribute_value_t *new_attr,
                     bool predefined)
{
    ompi_attribute_keyval_t *keyval;
    int ret;
    attribute_value_t *old_attr;
    bool had_old = false;

    /* Note that this function can be invoked by ompi_attr_copy_all()
       to set attributes on the new object (in addition to the
       top-level MPI_* functions that set attributes). */
    ret = opal_hash_table_get_value_uint32(keyval_hash, key,
                                           (void **) &keyval);

    /* If key not found */
    if ((OMPI_SUCCESS != ret ) || (NULL == keyval) ||
        (keyval->attr_type != type) ||
        ((!predefined) && (keyval->attr_flag & OMPI_KEYVAL_PREDEFINED))) {
        return OMPI_ERR_BAD_PARAM;
    }

    /* Do we need to make a new attr_hash? */
    if (NULL == *attr_hash) {
        ompi_attr_hash_init(attr_hash);
    }

    /* Now see if an attribute is already present in the object's hash
       on the old keyval. If so, delete the old attribute value. */
    ret = opal_hash_table_get_value_uint32(*attr_hash, key, (void**) &old_attr);
    if (OMPI_SUCCESS == ret)  {
        switch (type) {
        case COMM_ATTR:
            DELETE_ATTR_CALLBACKS(communicator, old_attr, keyval, object, ret);
            break;

        case WIN_ATTR:
            DELETE_ATTR_CALLBACKS(win, old_attr, keyval, object, ret);
            break;

        case TYPE_ATTR:
            DELETE_ATTR_CALLBACKS(datatype, old_attr, keyval, object, ret);
            break;

        default:
            /* This should not happen */
            assert(0);
            break;
        }
        if (MPI_SUCCESS != ret) {
            return ret;
        }
        had_old = true;
    }

    ret = opal_hash_table_get_value_uint32(keyval_hash, key,
                                           (void **) &keyval);
    if ((OMPI_SUCCESS != ret ) || (NULL == keyval)) {
        /* Keyval has disappeared underneath us -- this shouldn't
           happen! */
        assert(0);
        return OMPI_ERR_BAD_PARAM;
    }

    new_attr->av_key = key;
    new_attr->av_sequence = attr_sequence++;

    ret = opal_hash_table_set_value_uint32(*attr_hash, key, new_attr);

    /* Increase the reference count of the object, only if there was no
       old atribute/no old entry in the object's key hash */
    if (OMPI_SUCCESS == ret && !had_old) {
        OBJ_RETAIN(keyval);
    }

    return ret;
}