Skip to content

Commit 75e19cc

Browse files
authored
Refactored and optimized implementation
2 parents 5ffaa23 + 9ebe0ce commit 75e19cc

File tree

14 files changed

+1908
-1340
lines changed

14 files changed

+1908
-1340
lines changed

CHANGELOG

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
1.4.0
2+
3+
Improved cross thread deallocations by using per-span atomic free list to minimize thread
4+
contention and localize free list processing to actual span
5+
6+
Change span free list to a linked list, conditionally initialized one memory page at a time
7+
8+
Reduce number of conditionals in the fast path allocation and avoid touching heap structure
9+
at all in best case
10+
11+
Avoid realigning block in deallocation unless span marked as used by alignment > 32 bytes
12+
13+
Revert block granularity and natural alignment to 16 bytes to reduce memory waste
14+
15+
Bugfix for preserving data when reallocating a previously aligned (>32 bytes) block
16+
17+
Use compile time span size by default for improved performance, added build time RPMALLOC_CONFIGURABLE
18+
preprocessor directive to reenable configurability of span and page size
19+
20+
More detailed statistics
21+
22+
Disabled adaptive thread cache by default
23+
24+
Fixed an issue where reallocations of large blocks could read outsize of memory page boundaries
25+
26+
Tag mmap requests on macOS with tag 240 for identification with vmmap tool
27+
28+
129
1.3.2
230

331
Support for alignment equal or larger than memory page size, up to span size

README.md

Lines changed: 25 additions & 20 deletions
Large diffs are not rendered by default.

build/ninja/clang.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ def initialize(self, project, archs, configs, includepaths, dependlibs, libpaths
4040

4141
#Base flags
4242
self.cflags = ['-D' + project.upper() + '_COMPILE=1',
43-
'-funit-at-a-time', '-fstrict-aliasing',
44-
'-fno-math-errno','-ffinite-math-only', '-funsafe-math-optimizations',
43+
'-funit-at-a-time', '-fstrict-aliasing', '-fvisibility=hidden', '-fno-stack-protector',
44+
'-fomit-frame-pointer', '-fno-math-errno','-ffinite-math-only', '-funsafe-math-optimizations',
4545
'-fno-trapping-math', '-ffast-math']
4646
self.cwarnflags = ['-W', '-Werror', '-pedantic', '-Wall', '-Weverything',
47-
'-Wno-padded', '-Wno-documentation-unknown-command']
47+
'-Wno-padded', '-Wno-documentation-unknown-command', '-Wno-static-in-inline']
4848
self.cmoreflags = []
4949
self.mflags = []
5050
self.arflags = []
51-
self.linkflags = []
51+
self.linkflags = ['-fomit-frame-pointer']
5252
self.oslibs = []
5353
self.frameworks = []
5454

@@ -65,7 +65,6 @@ def initialize(self, project, archs, configs, includepaths, dependlibs, libpaths
6565
if self.target.is_linux() or self.target.is_bsd() or self.target.is_raspberrypi():
6666
self.cflags += ['-D_GNU_SOURCE=1']
6767
self.linkflags += ['-pthread']
68-
self.oslibs += ['m']
6968
if self.target.is_linux() or self.target.is_raspberrypi():
7069
self.oslibs += ['dl']
7170
if self.target.is_bsd():
@@ -85,7 +84,7 @@ def initialize(self, project, archs, configs, includepaths, dependlibs, libpaths
8584
self.cflags += ['-w']
8685
self.cxxflags = list(self.cflags)
8786

88-
self.cflags += ['-std=c11']
87+
self.cflags += ['-std=gnu11']
8988
if self.target.is_macos() or self.target.is_ios():
9089
self.cxxflags += ['-std=c++14', '-stdlib=libc++']
9190
else:
@@ -311,7 +310,7 @@ def make_carchflags(self, arch, targettype):
311310
flags = []
312311
if targettype == 'sharedlib':
313312
flags += ['-DBUILD_DYNAMIC_LINK=1']
314-
if self.target.is_linux():
313+
if self.target.is_linux() or self.target.is_bsd():
315314
flags += ['-fPIC']
316315
flags += self.make_targetarchflags(arch, targettype)
317316
return flags
@@ -321,11 +320,11 @@ def make_cconfigflags(self, config, targettype):
321320
if config == 'debug':
322321
flags += ['-DBUILD_DEBUG=1', '-g']
323322
elif config == 'release':
324-
flags += ['-DBUILD_RELEASE=1', '-O3', '-g', '-funroll-loops']
323+
flags += ['-DBUILD_RELEASE=1', '-DNDEBUG', '-O3', '-g', '-funroll-loops']
325324
elif config == 'profile':
326-
flags += ['-DBUILD_PROFILE=1', '-O3', '-g', '-funroll-loops']
325+
flags += ['-DBUILD_PROFILE=1', '-DNDEBUG', '-O3', '-g', '-funroll-loops']
327326
elif config == 'deploy':
328-
flags += ['-DBUILD_DEPLOY=1', '-O3', '-g', '-funroll-loops']
327+
flags += ['-DBUILD_DEPLOY=1', '-DNDEBUG', '-O3', '-g', '-funroll-loops']
329328
return flags
330329

331330
def make_ararchflags(self, arch, targettype):
@@ -363,7 +362,9 @@ def make_linkconfigflags(self, config, targettype, variables):
363362
flags += ['-dynamiclib']
364363
else:
365364
if targettype == 'sharedlib':
366-
flags += ['-shared']
365+
flags += ['-shared', '-fPIC']
366+
if config == 'release':
367+
flags += ['-DNDEBUG', '-O3']
367368
return flags
368369

369370
def make_linkarchlibs(self, arch, targettype):

build/ninja/gcc.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ def initialize(self, project, archs, configs, includepaths, dependlibs, libpaths
5252
if self.target.is_linux() or self.target.is_bsd() or self.target.is_raspberrypi():
5353
self.cflags += ['-D_GNU_SOURCE=1']
5454
self.linkflags += ['-pthread']
55-
self.oslibs += ['m']
5655
if self.target.is_linux() or self.target.is_raspberrypi():
5756
self.oslibs += ['dl']
5857
if self.target.is_bsd():
@@ -183,7 +182,7 @@ def make_carchflags(self, arch, targettype):
183182
flags = []
184183
if targettype == 'sharedlib':
185184
flags += ['-DBUILD_DYNAMIC_LINK=1']
186-
if self.target.is_linux():
185+
if self.target.is_linux() or self.target.is_bsd():
187186
flags += ['-fPIC']
188187
flags += self.make_targetarchflags(arch, targettype)
189188
return flags

build/ninja/msvc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def initialize(self, project, archs, configs, includepaths, dependlibs, libpaths
2222
self.linker = 'link'
2323
self.dller = 'dll'
2424

25-
#Command definitions
25+
#Command definitions (to generate assembly, add "/FAs /Fa$out.asm")
2626
self.cccmd = '$toolchain$cc /showIncludes /I. $includepaths $moreincludepaths $cflags $carchflags $cconfigflags $cmoreflags /c $in /Fo$out /Fd$pdbpath /FS /nologo'
2727
self.cxxcmd = '$toolchain$cxx /showIncludes /I. $includepaths $moreincludepaths $cxxflags $carchflags $cconfigflags $cmoreflags /c $in /Fo$out /Fd$pdbpath /FS /nologo'
2828
self.ccdepfile = None

configure.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,14 @@
1010
import generator
1111

1212
generator = generator.Generator(project = 'rpmalloc', variables = [('bundleidentifier', 'com.rampantpixels.rpmalloc.$(binname)')])
13-
target = generator.target
14-
writer = generator.writer
15-
toolchain = generator.toolchain
1613

1714
rpmalloc_lib = generator.lib(module = 'rpmalloc', libname = 'rpmalloc', sources = ['rpmalloc.c'])
1815

19-
if not target.is_android() and not target.is_ios():
16+
if not generator.target.is_android() and not generator.target.is_ios():
2017
rpmalloc_so = generator.sharedlib(module = 'rpmalloc', libname = 'rpmalloc', sources = ['rpmalloc.c'])
2118

22-
if not target.is_windows():
23-
if not target.is_android() and not target.is_ios():
24-
rpmallocwrap_lib = generator.lib(module = 'rpmalloc', libname = 'rpmallocwrap', sources = ['rpmalloc.c', 'malloc.c', 'new.cc'], variables = {'defines': ['ENABLE_PRELOAD=1']})
19+
rpmallocwrap_so = generator.sharedlib(module = 'rpmalloc', libname = 'rpmallocwrap', sources = ['rpmalloc.c'], variables = {'defines': ['ENABLE_PRELOAD=1', 'ENABLE_OVERRIDE=1']})
20+
rpmallocwrap_lib = generator.lib(module = 'rpmalloc', libname = 'rpmallocwrap', sources = ['rpmalloc.c'], variables = {'defines': ['ENABLE_PRELOAD=1', 'ENABLE_OVERRIDE=1']})
2521

26-
if not target.is_windows() and not target.is_android() and not target.is_ios():
27-
rpmallocwrap_so = generator.sharedlib(module = 'rpmalloc', libname = 'rpmallocwrap', sources = ['rpmalloc.c', 'malloc.c', 'new.cc'], variables = {'runtime': 'c++', 'defines': ['ENABLE_PRELOAD=1']})
28-
29-
if not target.is_ios() and not target.is_android():
3022
generator.bin(module = 'test', sources = ['thread.c', 'main.c'], binname = 'rpmalloc-test', implicit_deps = [rpmalloc_lib], libs = ['rpmalloc'], includepaths = ['rpmalloc', 'test'], variables = {'defines': ['ENABLE_ASSERTS=1', 'ENABLE_STATISTICS=1']})
23+
generator.bin(module = 'test', sources = ['thread.c', 'main-override.cc'], binname = 'rpmallocwrap-test', implicit_deps = [rpmallocwrap_lib], libs = ['rpmallocwrap'], includepaths = ['rpmalloc', 'test'], variables = {'runtime': 'c++', 'defines': ['ENABLE_ASSERTS=1', 'ENABLE_STATISTICS=1']})

0 commit comments

Comments
 (0)