/*! \brief Converts a Data object pointer to an Handle. \note This function assumes the Handle in the Data object was stored using the dmz::DataConverterHandle::to_data function. \param[in] Value Pointer to the Data object containing the Handle as an attribute. */ dmz::Handle dmz::DataConverterHandle::to_handle (const Data *Value) { Handle result (0); if (Value) { result = to_handle (*Value); } return result; }
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags) { uint32_t i; odp_shm_block_t *block; void *addr; int fd = -1; int map_flag = MAP_SHARED; /* If already exists: O_EXCL: error, O_TRUNC: truncate to zero */ int oflag = O_RDWR | O_CREAT | O_TRUNC; uint64_t alloc_size; uint64_t page_sz; #ifdef MAP_HUGETLB uint64_t huge_sz; int need_huge_page = 0; uint64_t alloc_hp_size; #endif const struct odp_mm_district *zone = NULL; char memdistrict_name[ODP_SHM_NAME_LEN + 8]; page_sz = odp_sys_page_size(); alloc_size = size + align; #ifdef MAP_HUGETLB huge_sz = odp_sys_huge_page_size(); need_huge_page = (huge_sz && alloc_size > page_sz); /* munmap for huge pages requires sizes round up by page */ alloc_hp_size = (size + align + (huge_sz - 1)) & (-huge_sz); #endif if (flags & ODP_SHM_PROC) { /* Creates a file to /dev/shm */ fd = shm_open(name, oflag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd == -1) { ODP_DBG("%s: shm_open failed.\n", name); return ODP_SHM_INVALID; } } else if (flags & ODP_SHM_MONOPOLIZE_CNTNUS_PHY) { int pid = getpid(); snprintf(memdistrict_name, sizeof(memdistrict_name), "%s_%d", name, pid); zone = odp_mm_district_reserve(memdistrict_name, name, alloc_size, 0, ODP_MEMZONE_2MB | ODP_MEMZONE_SIZE_HINT_ONLY); if (zone == NULL) { ODP_DBG("odp_mm_district_reseve %s failed.\n", name); return ODP_SHM_INVALID; } } else if (flags & ODP_SHM_SHARE_CNTNUS_PHY) { zone = odp_mm_district_reserve(name, name, alloc_size, 0, ODP_MEMZONE_2MB | ODP_MEMZONE_SIZE_HINT_ONLY); if (zone == NULL) { ODP_DBG("odp_mm_district_reseve %s failed.\n", name); return ODP_SHM_INVALID; } } else { map_flag |= MAP_ANONYMOUS; } odp_spinlock_lock(&odp_shm_tbl->lock); if (find_block(name, NULL)) { /* Found a block with the same name */ odp_spinlock_unlock(&odp_shm_tbl->lock); ODP_DBG("name %s already used.\n", name); return ODP_SHM_INVALID; } for (i = 0; i < ODP_CONFIG_SHM_BLOCKS; i++) if (odp_shm_tbl->block[i].addr == NULL) /* Found free block */ break; if (i > ODP_CONFIG_SHM_BLOCKS - 1) { /* Table full */ odp_spinlock_unlock(&odp_shm_tbl->lock); ODP_DBG("%s: no more blocks.\n", name); return ODP_SHM_INVALID; } block = &odp_shm_tbl->block[i]; block->hdl = to_handle(i); addr = MAP_FAILED; #ifdef MAP_HUGETLB /* Try first huge pages */ if (need_huge_page) { if ((flags & ODP_SHM_PROC) && (ftruncate(fd, alloc_hp_size) == -1)) { odp_spinlock_unlock(&odp_shm_tbl->lock); ODP_DBG("%s: ftruncate huge pages failed.\n", name); return ODP_SHM_INVALID; } addr = mmap(NULL, alloc_hp_size, PROT_READ | PROT_WRITE, map_flag | MAP_HUGETLB, fd, 0); if (addr == MAP_FAILED) { ODP_DBG(" %s: No huge pages, fall back to normal pages," "check: /proc/sys/vm/nr_hugepages.\n", name); } else { block->alloc_size = alloc_hp_size; block->huge = 1; block->page_sz = huge_sz; } } #endif if (flags & ODP_SHM_MONOPOLIZE_CNTNUS_PHY || flags & ODP_SHM_SHARE_CNTNUS_PHY) addr = zone->addr; /* Use normal pages for small or failed huge page allocations */ if (addr == MAP_FAILED) { if ((flags & ODP_SHM_PROC) && (ftruncate(fd, alloc_size) == -1)) { odp_spinlock_unlock(&odp_shm_tbl->lock); ODP_ERR("%s: ftruncate failed.\n", name); return ODP_SHM_INVALID; } addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, map_flag, fd, 0); if (addr == MAP_FAILED) { odp_spinlock_unlock(&odp_shm_tbl->lock); ODP_DBG("%s mmap failed.\n", name); return ODP_SHM_INVALID; } block->alloc_size = alloc_size; block->huge = 0; block->page_sz = page_sz; } if (flags & ODP_SHM_MONOPOLIZE_CNTNUS_PHY || flags & ODP_SHM_SHARE_CNTNUS_PHY) { block->alloc_size = alloc_size; block->huge = 1; block->page_sz = ODP_MEMZONE_2MB; block->addr_orig = addr; /* move to correct alignment */ addr = ODP_ALIGN_ROUNDUP_PTR(zone->addr, align); strncpy(block->name, name, ODP_SHM_NAME_LEN - 1); block->name[ODP_SHM_NAME_LEN - 1] = 0; block->size = size; block->align = align; block->flags = flags; block->fd = -1; block->addr = addr; } else { block->addr_orig = addr; /* move to correct alignment */ addr = ODP_ALIGN_ROUNDUP_PTR(addr, align); strncpy(block->name, name, ODP_SHM_NAME_LEN - 1); block->name[ODP_SHM_NAME_LEN - 1] = 0; block->size = size; block->align = align; block->flags = flags; block->fd = fd; block->addr = addr; } odp_spinlock_unlock(&odp_shm_tbl->lock); return block->hdl; }