Blame memkind-1.10.0/test/check.cpp

Packit Service 724aca
/*
Packit Service 724aca
 * Copyright (C) 2014 - 2018 Intel Corporation.
Packit Service 724aca
 * All rights reserved.
Packit Service 724aca
 *
Packit Service 724aca
 * Redistribution and use in source and binary forms, with or without
Packit Service 724aca
 * modification, are permitted provided that the following conditions are met:
Packit Service 724aca
 * 1. Redistributions of source code must retain the above copyright notice(s),
Packit Service 724aca
 *    this list of conditions and the following disclaimer.
Packit Service 724aca
 * 2. Redistributions in binary form must reproduce the above copyright notice(s),
Packit Service 724aca
 *    this list of conditions and the following disclaimer in the documentation
Packit Service 724aca
 *    and/or other materials provided with the distribution.
Packit Service 724aca
 *
Packit Service 724aca
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
Packit Service 724aca
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
Packit Service 724aca
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
Packit Service 724aca
 * EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
Packit Service 724aca
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit Service 724aca
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit Service 724aca
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit Service 724aca
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
Packit Service 724aca
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
Packit Service 724aca
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 724aca
 */
Packit Service 724aca
Packit Service 724aca
#include <memkind/internal/memkind_hbw.h>
Packit Service 724aca
Packit Service 724aca
#include <stdlib.h>
Packit Service 724aca
#include <stdio.h>
Packit Service 724aca
#include <sys/types.h>
Packit Service 724aca
#include <sys/stat.h>
Packit Service 724aca
#include <unistd.h>
Packit Service 724aca
#include <fcntl.h>
Packit Service 724aca
#include <numaif.h>
Packit Service 724aca
#include <errno.h>
Packit Service 724aca
#include <fstream>
Packit Service 724aca
#include <sstream>
Packit Service 724aca
#include <iostream>
Packit Service 724aca
#include <fstream>
Packit Service 724aca
#include <string>
Packit Service 724aca
#include <cstring>
Packit Service 724aca
#include <numa.h>
Packit Service 724aca
#include <errno.h>
Packit Service 724aca
Packit Service 724aca
#include "check.h"
Packit Service 724aca
Packit Service 724aca
Packit Service 724aca
using namespace std;
Packit Service 724aca
Packit Service 724aca
Packit Service 724aca
/*Check each page between the start
Packit Service 724aca
and the end address additionally also
Packit Service 724aca
check the end address for pagesize*/
Packit Service 724aca
Check::Check(const void *p, const trial_t &trial): Check(p, trial.size,
Packit Service 724aca
                                                             trial.page_size)
Packit Service 724aca
{
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
Check::Check(const void *p, const size_t size, const size_t page_size)
Packit Service 724aca
{
Packit Service 724aca
    const size_t min_page_size = 4096;
Packit Service 724aca
    this->ptr = p;
Packit Service 724aca
    this->size = size;
Packit Service 724aca
    size_t psize = (page_size >= min_page_size ? page_size : min_page_size);
Packit Service 724aca
    if (p && size && psize) {
Packit Service 724aca
        num_address = size / psize;
Packit Service 724aca
        num_address += size % psize ? 1 : 0;
Packit Service 724aca
Packit Service 724aca
        address = new void *[num_address];
Packit Service 724aca
        size_t i;
Packit Service 724aca
        for (i = 0; i < num_address - 1; ++i) {
Packit Service 724aca
            address[i] = (char *)ptr + i * psize;
Packit Service 724aca
        }
Packit Service 724aca
        address[i] = (char *)p + size - 1;
Packit Service 724aca
    } else {
Packit Service 724aca
        address = NULL;
Packit Service 724aca
        num_address = 0;
Packit Service 724aca
    }
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
Check::~Check()
Packit Service 724aca
{
Packit Service 724aca
    delete[] address;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
Check::Check(const Check &other)
Packit Service 724aca
{
Packit Service 724aca
    num_address = other.num_address;
Packit Service 724aca
Packit Service 724aca
    address = new void *[num_address];
Packit Service 724aca
    for (size_t i = 0; i < num_address; ++i) {
Packit Service 724aca
        address[i] = other.address[i];
Packit Service 724aca
    }
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
int Check::check_zero(void)
Packit Service 724aca
{
Packit Service 724aca
    size_t i;
Packit Service 724aca
    const char *cptr = (char *)ptr;
Packit Service 724aca
    for (i = 0; i < size; ++i) {
Packit Service 724aca
        if (cptr[i] != '\0') {
Packit Service 724aca
            return -1;
Packit Service 724aca
        }
Packit Service 724aca
    }
Packit Service 724aca
    return 0;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
int Check::check_align(size_t align)
Packit Service 724aca
{
Packit Service 724aca
    return (size_t)ptr % align;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
string Check::skip_to_next_entry (ifstream &ip)
Packit Service 724aca
{
Packit Service 724aca
    string temp, token;
Packit Service 724aca
    size_t found = 0;
Packit Service 724aca
    string empty ="";
Packit Service 724aca
Packit Service 724aca
    while (!ip.eof()) {
Packit Service 724aca
        getline (ip, temp);
Packit Service 724aca
        found = temp.find("-");
Packit Service 724aca
        if (found != string::npos) {
Packit Service 724aca
            istringstream iss(temp);
Packit Service 724aca
            getline(iss, token, ' ');
Packit Service 724aca
            return token;
Packit Service 724aca
        }
Packit Service 724aca
    }
Packit Service 724aca
    return empty;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
string Check::skip_to_next_kpage(ifstream &ip)
Packit Service 724aca
{
Packit Service 724aca
    string temp, token;
Packit Service 724aca
    size_t found = 0;
Packit Service 724aca
    string empty ="";
Packit Service 724aca
Packit Service 724aca
    while (!ip.eof()) {
Packit Service 724aca
        getline (ip, temp);
Packit Service 724aca
        found = temp.find("KernelPageSize:");
Packit Service 724aca
        if (found != string::npos) {
Packit Service 724aca
            return temp;
Packit Service 724aca
        }
Packit Service 724aca
    }
Packit Service 724aca
    return empty;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
Packit Service 724aca
void Check::get_address_range(string &line,
Packit Service 724aca
                              unsigned long long *start_addr,
Packit Service 724aca
                              unsigned long long *end_addr)
Packit Service 724aca
{
Packit Service 724aca
    stringstream ss(line);
Packit Service 724aca
    string token;
Packit Service 724aca
Packit Service 724aca
    getline(ss, token, '-');
Packit Service 724aca
    *start_addr = strtoul(token.c_str(),
Packit Service 724aca
                          NULL,
Packit Service 724aca
                          16);
Packit Service 724aca
    getline(ss, token, '-');
Packit Service 724aca
    *end_addr = strtoul(token.c_str(),
Packit Service 724aca
                        NULL,
Packit Service 724aca
                        16);
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
size_t Check::get_kpagesize(string line)
Packit Service 724aca
{
Packit Service 724aca
    stringstream ss(line);
Packit Service 724aca
    string token;
Packit Service 724aca
    size_t pagesize;
Packit Service 724aca
Packit Service 724aca
Packit Service 724aca
    ss  >> token;
Packit Service 724aca
    ss  >> token;
Packit Service 724aca
Packit Service 724aca
    pagesize = atol(token.c_str());
Packit Service 724aca
Packit Service 724aca
    return (size_t)pagesize;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
int Check::check_page_size(size_t page_size)
Packit Service 724aca
{
Packit Service 724aca
    int err = 0;
Packit Service 724aca
    size_t i;
Packit Service 724aca
Packit Service 724aca
    ip.open ("/proc/self/smaps");
Packit Service 724aca
Packit Service 724aca
    populate_smaps_table();
Packit Service 724aca
    if (check_page_size(page_size, address[0])) {
Packit Service 724aca
        err = -1;
Packit Service 724aca
    }
Packit Service 724aca
    for (i = 1; i < num_address && !err; ++i) {
Packit Service 724aca
        if (check_page_size(page_size, address[i])) {
Packit Service 724aca
            err = i;
Packit Service 724aca
        }
Packit Service 724aca
    }
Packit Service 724aca
    return err;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
int Check::populate_smaps_table ()
Packit Service 724aca
{
Packit Service 724aca
    string read;
Packit Service 724aca
    size_t lpagesize;
Packit Service 724aca
    smaps_entry_t lentry;
Packit Service 724aca
    unsigned long long start_addr;
Packit Service 724aca
    unsigned long long end_addr;
Packit Service 724aca
Packit Service 724aca
    ip >> read;
Packit Service 724aca
    while (!ip.eof()) {
Packit Service 724aca
Packit Service 724aca
        start_addr = end_addr = 0;
Packit Service 724aca
        get_address_range (read,
Packit Service 724aca
                           &start_addr,
Packit Service 724aca
                           &end_addr);
Packit Service 724aca
        read = skip_to_next_kpage(ip);
Packit Service 724aca
        getline(ip, read);
Packit Service 724aca
        lpagesize = get_kpagesize(read);
Packit Service 724aca
        lpagesize *= 1024;
Packit Service 724aca
        lentry.start_addr = start_addr;
Packit Service 724aca
        lentry.end_addr = end_addr;
Packit Service 724aca
        lentry.pagesize = lpagesize;
Packit Service 724aca
        smaps_table.push_back(lentry);
Packit Service 724aca
        read = skip_to_next_entry(ip);
Packit Service 724aca
        if (read.empty()) {
Packit Service 724aca
            break;
Packit Service 724aca
        }
Packit Service 724aca
    }
Packit Service 724aca
Packit Service 724aca
    if (0 == smaps_table.size()) {
Packit Service 724aca
        fprintf(stderr,"Empty smaps table\n");
Packit Service 724aca
        return -1;
Packit Service 724aca
    } else {
Packit Service 724aca
        return 0;
Packit Service 724aca
    }
Packit Service 724aca
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
int Check::check_page_size(size_t page_size, void *vaddr)
Packit Service 724aca
{
Packit Service 724aca
    string read;
Packit Service 724aca
    unsigned long long virt_addr;
Packit Service 724aca
    size_t lpagesize;
Packit Service 724aca
    list<smaps_entry_t>::iterator it;
Packit Service 724aca
    unsigned long long start_addr;
Packit Service 724aca
    unsigned long long end_addr;
Packit Service 724aca
Packit Service 724aca
    virt_addr = (unsigned long long)(vaddr);
Packit Service 724aca
Packit Service 724aca
    for (it = smaps_table.begin();
Packit Service 724aca
         it != smaps_table.end();
Packit Service 724aca
         it++) {
Packit Service 724aca
Packit Service 724aca
        start_addr = it->start_addr;
Packit Service 724aca
        end_addr = it->end_addr;
Packit Service 724aca
Packit Service 724aca
        if ((virt_addr >= start_addr) &&
Packit Service 724aca
            (virt_addr < end_addr)) {
Packit Service 724aca
            lpagesize = it->pagesize;
Packit Service 724aca
            if (lpagesize == page_size) {
Packit Service 724aca
                return 0;
Packit Service 724aca
            } else {
Packit Service 724aca
                /*The pagesize of allocation and req don't match*/
Packit Service 724aca
                fprintf(stderr,"%zd does not match entry in SMAPS (%zd)\n",
Packit Service 724aca
                        page_size, lpagesize);
Packit Service 724aca
                return -1;
Packit Service 724aca
            }
Packit Service 724aca
        }
Packit Service 724aca
    }
Packit Service 724aca
    /*Never found a match!*/
Packit Service 724aca
    return 1;
Packit Service 724aca
}