Пример #1
0
ucs_status_t ucp_address_unpack(const void *buffer, uint64_t *remote_uuid_p,
                                char *remote_name, size_t max,
                                unsigned *address_count_p,
                                ucp_address_entry_t **address_list_p)
{
    ucp_address_entry_t *address_list, *address;
    const uct_device_addr_t *dev_addr;
    ucp_rsc_index_t dev_index;
    ucp_rsc_index_t md_index;
    unsigned address_count;
    int last_dev, last_tl, ep_addr_present;
    int empty_dev;
    uint64_t md_flags;
    size_t dev_addr_len;
    size_t iface_addr_len;
    size_t ep_addr_len;
    uint8_t md_byte;
    const void *ptr;
    const void *aptr;

    ptr = buffer;
    *remote_uuid_p = *(uint64_t*)ptr;
    ptr += sizeof(uint64_t);

    aptr = ucp_address_unpack_string(ptr, remote_name, max);

    address_count = 0;

    /* Count addresses */
    ptr = aptr;
    do {
        if (*(uint8_t*)ptr == UCP_NULL_RESOURCE) {
            break;
        }

        /* md_index */
        empty_dev    = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_EMPTY;
        ++ptr;

        /* device address length */
        dev_addr_len = (*(uint8_t*)ptr) & ~UCP_ADDRESS_FLAG_LAST;
        last_dev     = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_LAST;
        ++ptr;

        ptr += dev_addr_len;

        last_tl = empty_dev;
        while (!last_tl) {
            ptr += sizeof(uint16_t);                        /* tl_name_csum */
            ptr += sizeof(ucp_address_packed_iface_attr_t); /* iface attr */

            /* iface and ep address lengths */
            iface_addr_len  = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_LEN_MASK;
            last_tl         = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_LAST;
            ep_addr_present = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_EP_ADDR;
            ptr            += 1 + iface_addr_len;

            if (ep_addr_present) {
                ep_addr_len = *(uint8_t*)ptr;
                ptr        += 1 + ep_addr_len;
            }

            ++address_count;
            ucs_assert(address_count <= UCP_MAX_RESOURCES);
        }

    } while (!last_dev);


    /* Allocate address list */
    address_list = ucs_calloc(address_count, sizeof(*address_list),
                              "ucp_address_list");
    if (address_list == NULL) {
        return UCS_ERR_NO_MEMORY;
    }

    /* Unpack addresses */
    address = address_list;
    ptr     = aptr;
    dev_index = 0;
    do {
        if (*(uint8_t*)ptr == UCP_NULL_RESOURCE) {
            break;
        }

        /* md_index */
        md_byte      = (*(uint8_t*)ptr);
        md_index     = md_byte & UCP_ADDRESS_FLAG_MD_MASK;
        md_flags     = (md_byte & UCP_ADDRESS_FLAG_MD_ALLOC) ? UCT_MD_FLAG_ALLOC : 0;
        md_flags    |= (md_byte & UCP_ADDRESS_FLAG_MD_REG)   ? UCT_MD_FLAG_REG   : 0;
        empty_dev    = md_byte & UCP_ADDRESS_FLAG_EMPTY;
        ++ptr;

        /* device address length */
        dev_addr_len = (*(uint8_t*)ptr) & ~UCP_ADDRESS_FLAG_LAST;
        last_dev     = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_LAST;
        ++ptr;

        dev_addr = ptr;

        ptr += dev_addr_len;

        last_tl = empty_dev;
        while (!last_tl) {
            /* tl name */
            address->tl_name_csum = *(uint16_t*)ptr;
            ptr += sizeof(uint16_t);

            /* tl_name_csum */
            ucp_address_unpack_iface_attr(&address->iface_attr, ptr);
            ptr += sizeof(ucp_address_packed_iface_attr_t);

            /* tl address length */
            iface_addr_len  = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_LEN_MASK;
            last_tl         = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_LAST;
            ep_addr_present = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_EP_ADDR;
            ++ptr;

            address->dev_addr   = (dev_addr_len > 0) ? dev_addr : NULL;
            address->md_index   = md_index;
            address->dev_index  = dev_index;
            address->md_flags   = md_flags;
            address->iface_addr = (iface_addr_len > 0) ? ptr : NULL;
            ptr                += iface_addr_len;

            if (ep_addr_present) {
                ep_addr_len      = *(uint8_t*)ptr;
                address->ep_addr = (ep_addr_len > 0) ? ptr + 1 : NULL;
                ptr             += 1 + ep_addr_len;
            } else {
                address->ep_addr = NULL;
            }

            ucs_trace("unpack addr[%d] : md_flags 0x%"PRIx64" tl_flags 0x%"PRIx64" bw %e ovh %e "
                      "lat_ovh %e dev_priority %d",
                      (int)(address - address_list),
                      address->md_flags, address->iface_attr.cap_flags,
                      address->iface_attr.bandwidth, address->iface_attr.overhead,
                      address->iface_attr.lat_ovh,
                      address->iface_attr.priority);
            ++address;
        }

        ++dev_index;
    } while (!last_dev);

    *address_count_p = address_count;
    *address_list_p  = address_list;
    return UCS_OK;
}
Пример #2
0
ucs_status_t ucp_address_unpack(const void *buffer, uint64_t *remote_uuid_p,
                                char *remote_name, size_t max,
                                unsigned *address_count_p,
                                ucp_address_entry_t **address_list_p)
{
    ucp_address_entry_t *address_list, *address;
    const uct_device_addr_t *dev_addr;
    ucp_rsc_index_t pd_index;
    unsigned address_count;
    int last_dev, last_tl;
    int empty_dev;
    size_t dev_addr_len;
    size_t tl_addr_len;
    const void *ptr;
    const void *aptr;

    ptr = buffer;
    *remote_uuid_p = *(uint64_t*)ptr;
    ptr += sizeof(uint64_t);

    aptr = ucp_address_unpack_string(ptr, remote_name, max);

    address_count = 0;

    /* Count addresses */
    ptr = aptr;
    do {
        if (*(uint8_t*)ptr == UCP_NULL_RESOURCE) {
            break;
        }

        /* pd_index */
        pd_index     = (*(uint8_t*)ptr) & ~UCP_ADDRESS_FLAG_EMPTY;
        empty_dev    = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_EMPTY;
        ++ptr;

        /* device address length */
        dev_addr_len = (*(uint8_t*)ptr) & ~UCP_ADDRESS_FLAG_LAST;
        last_dev     = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_LAST;
        ++ptr;

        ptr += dev_addr_len;

        last_tl = empty_dev;
        while (!last_tl) {
            ptr = ucp_address_skip_string(ptr); /* tl_name */

            /* tl address length */
            tl_addr_len = (*(uint8_t*)ptr) & ~UCP_ADDRESS_FLAG_LAST;
            last_tl     = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_LAST;
            ++ptr;

            ++address_count;
            ucs_assert(address_count <= UCP_MAX_RESOURCES);

            ptr += tl_addr_len;
        }

    } while (!last_dev);


    /* Allocate address list */
    address_list = ucs_calloc(address_count, sizeof(*address_list),
                              "ucp_address_list");
    if (address_list == NULL) {
        return UCS_ERR_NO_MEMORY;
    }

    /* Unpack addresses */
    address = address_list;
    ptr     = aptr;
    do {
        if (*(uint8_t*)ptr == UCP_NULL_RESOURCE) {
            break;
        }

        /* pd_index */
        pd_index     = (*(uint8_t*)ptr) & ~UCP_ADDRESS_FLAG_EMPTY;
        empty_dev    = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_EMPTY;
        ++ptr;

        /* device address length */
        dev_addr_len = (*(uint8_t*)ptr) & ~UCP_ADDRESS_FLAG_LAST;
        last_dev     = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_LAST;
        ++ptr;

        dev_addr = ptr;

        ptr += dev_addr_len;

        last_tl = empty_dev;
        while (!last_tl) {
            /* tl name */
            ptr = ucp_address_unpack_string(ptr, address->tl_name,
                                            UCT_TL_NAME_MAX);

            /* tl address length */
            tl_addr_len = (*(uint8_t*)ptr) & ~UCP_ADDRESS_FLAG_LAST;
            last_tl     = (*(uint8_t*)ptr) & UCP_ADDRESS_FLAG_LAST;
            ++ptr;

            address->dev_addr     = dev_addr;
            address->dev_addr_len = dev_addr_len;
            address->pd_index     = pd_index;
            address->tl_addr      = ptr;
            address->tl_addr_len  = tl_addr_len;
            ++address;

            ptr += tl_addr_len;
        }
    } while (!last_dev);

    *address_count_p = address_count;
    *address_list_p  = address_list;
    return UCS_OK;
}