static void memkind_hbw_closest_numanode_init(void)
{
    struct memkind_hbw_closest_numanode_t *g =
            &memkind_hbw_closest_numanode_g;
    int *bandwidth = NULL;
    int num_unique = 0;
    int high_bandwidth = 0;
    int i;

    struct bandwidth_nodes_t *bandwidth_nodes = NULL;

    g->num_cpu = numa_num_configured_cpus();
    g->closest_numanode = (int *)jemk_malloc(sizeof(int) * g->num_cpu);
    bandwidth = (int *)jemk_malloc(sizeof(int) * NUMA_NUM_NODES);

    if (!(g->closest_numanode && bandwidth)) {
        g->init_err = MEMKIND_ERROR_MALLOC;
        log_err("jemk_malloc() failed.");
        goto exit;
    }

    g->init_err = fill_nodes_bandwidth(bandwidth, NUMA_NUM_NODES);
    if (g->init_err)
        goto exit;

    g->init_err = create_bandwidth_nodes(NUMA_NUM_NODES, bandwidth,
                                             &num_unique, &bandwidth_nodes);
    if (g->init_err)
        goto exit;

    if (num_unique == 1) {
       g->init_err = MEMKIND_ERROR_UNAVAILABLE;
       goto exit;
    }

    high_bandwidth = bandwidth_nodes[num_unique-1].bandwidth;
    g->init_err = set_closest_numanode(num_unique, bandwidth_nodes,
                                       high_bandwidth, g->num_cpu,
                                       g->closest_numanode);

    for(i=0; i<bandwidth_nodes[num_unique-1].num_numanodes; i++) {
        log_info("NUMA node %d is high-bandwidth memory.",
                 bandwidth_nodes[num_unique-1].numanodes[i]);
    }

exit:

    jemk_free(bandwidth_nodes);
    jemk_free(bandwidth);

    if (g->init_err) {
        jemk_free(g->closest_numanode);
        g->closest_numanode = NULL;
    }
}
Beispiel #2
0
int memkind_thread_get_arena(struct memkind *kind, unsigned int *arena, size_t size)
{
    int err = 0;
    unsigned int *arena_tsd;

    arena_tsd = pthread_getspecific(kind->arena_key);
    if (arena_tsd == NULL) {
        arena_tsd = jemk_malloc(sizeof(unsigned int));
        if (arena_tsd == NULL) {
            err = MEMKIND_ERROR_MALLOC;
        }
        if (!err) {
            *arena_tsd = _mm_crc32_u64(0, (uint64_t)pthread_self()) %
                         kind->arena_map_len;
            err = pthread_setspecific(kind->arena_key, arena_tsd) ?
                  MEMKIND_ERROR_PTHREAD : 0;
        }
    }
    if (!err) {
        *arena = kind->arena_map[*arena_tsd];
        if (*arena == UINT_MAX) {
            err = MEMKIND_ERROR_MALLCTL;
        }
    }
    return err;
}
Beispiel #3
0
MEMKIND_EXPORT void *memkind_default_malloc(struct memkind *kind, size_t size)
{
    if(MEMKIND_UNLIKELY(size_out_of_bounds(size))) {
        return NULL;
    }
    return jemk_malloc(size);
}
Beispiel #4
0
int memkind_arena_create_map(struct memkind *kind)
{
    int err = 0;
    int i;
    size_t unsigned_size = sizeof(unsigned int);

    if (kind->arena_map_len == 0) {
        err = memkind_set_arena_map_len(kind);
    }
#ifndef MEMKIND_TLS
    if (kind->ops->get_arena == memkind_thread_get_arena) {
        pthread_key_create(&(kind->arena_key), jemk_free);
    }
#endif

    if (kind->arena_map_len) {
        kind->arena_map = (unsigned int *)jemk_malloc(sizeof(unsigned int) * kind->arena_map_len);
        if (kind->arena_map == NULL) {
            err = MEMKIND_ERROR_MALLOC;
        }
    }
    if (!err) {
        for (i = 0; i < kind->arena_map_len; ++i) {
            kind->arena_map[i] = UINT_MAX;
        }
        for (i = 0; !err && i < kind->arena_map_len; ++i) {
            err = jemk_mallctl("arenas.extendk", kind->arena_map + i,
                               &unsigned_size, &(kind->partition),
                               unsigned_size);
        }
        if (err) {
            if (kind->arena_map) {
                jemk_free(kind->arena_map);
            }
            err = MEMKIND_ERROR_MALLCTL;
        }
    }
    return err;
}
static int create_bandwidth_nodes(int num_bandwidth, const int *bandwidth,
                                  int *num_unique, struct bandwidth_nodes_t **bandwidth_nodes)
{
    /***************************************************************************
    *   num_bandwidth (IN):                                                    *
    *       number of numa nodes and length of bandwidth vector.               *
    *   bandwidth (IN):                                                        *
    *       A vector of length num_bandwidth that gives bandwidth for          *
    *       each numa node, zero if numa node has unknown bandwidth.           *
    *   num_unique (OUT):                                                      *
    *       number of unique non-zero bandwidth values in bandwidth            *
    *       vector.                                                            *
    *   bandwidth_nodes (OUT):                                                 *
    *       A list of length num_unique sorted by bandwidth value where        *
    *       each element gives a list of the numa nodes that have the          *
    *       given bandwidth.                                                   *
    *   RETURNS zero on success, error code on failure                         *
    ***************************************************************************/
    int err = 0;
    int i, j, k, l, last_bandwidth;
    struct numanode_bandwidth_t *numanode_bandwidth = NULL;
    *bandwidth_nodes = NULL;
    /* allocate space for sorting array */
    numanode_bandwidth = jemk_malloc(sizeof(struct numanode_bandwidth_t) *
                                     num_bandwidth);
    if (!numanode_bandwidth) {
        err = MEMKIND_ERROR_MALLOC;
        log_err("jemk_malloc() failed.");
    }
    if (!err) {
        /* set sorting array */
        j = 0;
        for (i = 0; i < num_bandwidth; ++i) {
            if (bandwidth[i] != 0) {
                numanode_bandwidth[j].numanode = i;
                numanode_bandwidth[j].bandwidth = bandwidth[i];
                ++j;
            }
        }
        /* ignore zero bandwidths */
        num_bandwidth = j;
        if (num_bandwidth == 0) {
            err = MEMKIND_ERROR_UNAVAILABLE;
        }
    }
    if (!err) {
        qsort(numanode_bandwidth, num_bandwidth,
              sizeof(struct numanode_bandwidth_t), numanode_bandwidth_compare);
        /* calculate the number of unique bandwidths */
        *num_unique = 1;
        last_bandwidth = numanode_bandwidth[0].bandwidth;
        for (i = 1; i < num_bandwidth; ++i) {
            if (numanode_bandwidth[i].bandwidth != last_bandwidth) {
                last_bandwidth = numanode_bandwidth[i].bandwidth;
                ++*num_unique;
            }
        }
        /* allocate output array */
        *bandwidth_nodes = (struct bandwidth_nodes_t*)jemk_malloc(
                               sizeof(struct bandwidth_nodes_t) * (*num_unique) +
                               sizeof(int) * num_bandwidth);
        if (!*bandwidth_nodes) {
            err = MEMKIND_ERROR_MALLOC;
            log_err("jemk_malloc() failed.");
        }
    }
    if (!err) {
        /* populate output */
        (*bandwidth_nodes)[0].numanodes = (int*)(*bandwidth_nodes + *num_unique);
        last_bandwidth = numanode_bandwidth[0].bandwidth;
        k = 0;
        l = 0;
        for (i = 0; i < num_bandwidth; ++i, ++l) {
            (*bandwidth_nodes)[0].numanodes[i] = numanode_bandwidth[i].numanode;
            if (numanode_bandwidth[i].bandwidth != last_bandwidth) {
                (*bandwidth_nodes)[k].num_numanodes = l;
                (*bandwidth_nodes)[k].bandwidth = last_bandwidth;
                l = 0;
                ++k;
                (*bandwidth_nodes)[k].numanodes = (*bandwidth_nodes)[0].numanodes + i;
                last_bandwidth = numanode_bandwidth[i].bandwidth;
            }
        }
        (*bandwidth_nodes)[k].num_numanodes = l;
        (*bandwidth_nodes)[k].bandwidth = last_bandwidth;
    }
    if (numanode_bandwidth) {
        jemk_free(numanode_bandwidth);
    }
    if (err) {
        if (*bandwidth_nodes) {
            jemk_free(*bandwidth_nodes);
        }
    }
    return err;
}
Beispiel #6
0
void *memkind_default_malloc(struct memkind *kind, size_t size)
{
    return jemk_malloc(size);
}
Beispiel #7
0
static int memkind_store(void *memptr, void **mmapptr, struct memkind **kind,
                         size_t *req_size, size_t *size, int mode)
{
    static int table_len = 0;
    static int is_init = 0;
    static memkind_table_node_t *table = NULL;
    static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
    int err = 0;
    int hash, i;
    memkind_list_node_t *storeptr, *lastptr;

    if (!is_init && *mmapptr == NULL) {
        return -1;
    }

    if (!is_init) {
        pthread_mutex_lock(&init_mutex);
        if (!is_init) {
            table_len = numa_num_configured_cpus();
            table = jemk_malloc(sizeof(memkind_table_node_t) * table_len);
            if (table == NULL) {
                err = MEMKIND_ERROR_MALLOC;
            }
            else {
                for (i = 0; i < table_len; ++i) {
                    pthread_mutex_init(&(table[i].mutex), NULL);
                    table[i].list = NULL;
                }
                is_init = 1;
            }
        }
        pthread_mutex_unlock(&init_mutex);
    }
    if (is_init) {
        hash = ptr_hash(memptr, table_len);
        pthread_mutex_lock(&(table[hash].mutex));
        if (mode == GBTLB_STORE_REMOVE || mode == GBTLB_STORE_QUERY) {
            /*
               memkind_store() call is a query
               GBTLB_STORE_REMOVE -> Query if found remove and
               return the address and size;
               GBTLB_STORE_QUERTY -> Query if found and return;
            */
            storeptr = table[hash].list;
            lastptr = NULL;
            while (storeptr && storeptr->ptr != memptr) {
                lastptr = storeptr;
                storeptr = storeptr->next;
            }
            if (storeptr == NULL) {
                err = MEMKIND_ERROR_RUNTIME;
            }
            if (!err) {
                *mmapptr = storeptr->mmapptr;
                *size = storeptr->size;
                *req_size = storeptr->requested_size;
                *kind = storeptr->kind;
            }
            if (!err && mode == GBTLB_STORE_REMOVE) {
                if (lastptr) {
                    lastptr->next = storeptr->next;
                }
                else {
                    table[hash].list = storeptr->next;
                }
                jemk_free(storeptr);
            }
        }
        else { /* memkind_store() call is a store */
            storeptr = table[hash].list;
            table[hash].list = (memkind_list_node_t*)jemk_malloc(sizeof(memkind_list_node_t));
            table[hash].list->ptr = memptr;
            table[hash].list->mmapptr = *mmapptr;
            table[hash].list->size = *size;
            table[hash].list->requested_size = *req_size;
            table[hash].list->kind = *kind;
            table[hash].list->next = storeptr;
        }
        pthread_mutex_unlock(&(table[hash].mutex));
    }
    else {
        err = MEMKIND_ERROR_MALLOC;
    }
    return err;
}