diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2019-02-09 12:45:38 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2019-02-09 12:45:38 +0100 |
| commit | 4c0830ffbc045290c167e482855cb25a639df0e0 (patch) | |
| tree | e66c2e0cbb209e5ab4442dfd7897cec23c8c5ff3 /src | |
| parent | cd9264be5594a7715dde29b3c0be82a00baf5fd1 (diff) | |
| download | allocbench-4c0830ffbc045290c167e482855cb25a639df0e0.tar.gz allocbench-4c0830ffbc045290c167e482855cb25a639df0e0.zip | |
add allocators build support and two allocator definitions
The allocators created by the file allocators/BA_allocators.py
are those used in my BA thesis available at: https://muhq.space/ba.html.
allocators/no_falsesharing.py builds patched versions of tcmalloc and
glibc without any allocator inroduced falsesharing.
Diffstat (limited to 'src')
| -rw-r--r-- | src/allocator.py | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/allocator.py b/src/allocator.py new file mode 100644 index 0000000..a163b14 --- /dev/null +++ b/src/allocator.py @@ -0,0 +1,150 @@ +import copy +import os +import shutil +import subprocess +import sys + +library_path = "" +for l in subprocess.run(["ldconfig", "-v"], stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True).stdout.splitlines(): + if not l.startswith('\t'): + library_path += l + +builddir = os.path.join(os.getcwd(), "build", "allocators") +srcdir = os.path.join(builddir, "src") + +if not os.path.isdir(srcdir): + os.makedirs(srcdir) + + +class Allocator_Sources (object): + # indicate if this source was patched + available = False + clean = True + + def __init__(self, name, retrieve_cmds=[], prepare_cmds=[], reset_cmds=[]): + self.name = name + self.dir = os.path.join(srcdir, self.name) + self.retrieve_cmds = retrieve_cmds + self.prepare_cmds = prepare_cmds + self.reset_cmds = reset_cmds + + def run_cmds(self, function, verbose, cwd=srcdir): + print(function, self.name, "...") + cmds = getattr(self, function+"_cmds") + for cmd in cmds: + stdout = subprocess.PIPE if not verbose else None + stderr = subprocess.PIPE if not verbose else None + p = subprocess.run(cmd, shell=True, cwd=cwd, stderr=stderr, + stdout=stdout) + + if p.returncode: + print(function, self.name, "failed with", p.returncode, + file=sys.stderr) + print(p.stderr, file=sys.stderr) + return False + return True + + def prepare(self, verbose): + if not os.path.isdir(self.dir): + if (not self.run_cmds("retrieve", verbose) or + not self.run_cmds("prepare", verbose, cwd=self.dir)): + + shutil.rmtree(self.dir, ignore_errors=True) + exit(1) + + self.available = True + return True + + def reset(self, verbose): + if not self.run_cmds("reset", verbose, cwd=self.dir): + exit(1) + self.clean = True + + def patch(self, patches, verbose): + self.prepare(verbose) + stdout = subprocess.PIPE if not verbose else None + stderr = subprocess.PIPE + cwd = os.path.join(srcdir, self.name) + + print("Patching", self.name, "...") + for patch in patches: + with open(patch, "rb") as f: + p = subprocess.run("patch -p1", shell=True, cwd=cwd, stderr=stderr, + stdout=stdout, input=f.read()) + + if p.returncode: + print("Patching of", self.name, "failed.", file=sys.stderr) + exit(1) + + +class Allocator (object): + allowed_attributes = ["binary_suffix", "version", "sources", "build_cmds", + "LD_PRELOAD", "cmd_prefix", "color"] + + def __init__(self, name, **kwargs): + self.name = name + self.dir = os.path.join(builddir, self.name) + # Update attributes + self.__dict__.update((k, v) for k, v in kwargs.items() if k in self.allowed_attributes) + + # create all unset attributes + for attr in self.allowed_attributes: + if not hasattr(self, attr): + setattr(self, attr, None) + + def build(self, verbose=False): + if not os.path.isdir(self.dir): + if self.sources: + if not self.sources.available: + self.sources.prepare(verbose) + if not self.sources.clean: + self.sources.reset(verbose) + + if self.build_cmds: + print("Building", self.name, "...") + for cmd in self.build_cmds: + cmd = cmd.format(**{"dir": self.dir, + "srcdir": self.sources.dir}) + stdout = subprocess.PIPE if not verbose else None + stderr = subprocess.PIPE + p = subprocess.run(cmd, cwd=builddir, shell=True, + stderr=stderr, stdout=stdout) + if p.returncode: + print(cmd) + print(p.stderr) + print("Building", self.name, "failed ...") + shutil.rmtree(self.dir, ignore_errors=True) + exit(1) + + for attr in ["LD_PRELOAD", "cmd_prefix"]: + try: + value = getattr(self, attr) + setattr(self, attr, value.format(**{"dir": self.dir, + "srcdir": self.sources.dir})) + except AttributeError: + setattr(self, attr, "") + + return {"cmd_prefix": self.cmd_prefix, + "binary_suffix": self.binary_suffix or "", + "LD_PRELOAD": self.LD_PRELOAD, + "color": self.color} + + +class Allocator_Patched (object): + def __init__(self, name, alloc, patches, **kwargs): + self.name = name + self.patches = patches + + self.alloc = copy.deepcopy(alloc) + self.alloc.name = self.name + self.alloc.dir = os.path.join(builddir, self.name) + self.alloc.__dict__.update((k, v) for k, v in kwargs.items() if k in self.alloc.allowed_attributes) + + def build(self, verbose=False): + + if not os.path.isdir(self.alloc.dir): + self.alloc.sources.patch(self.patches, verbose) + + return self.alloc.build(verbose=verbose) |
