Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Memory Allocator

MaintenancePRs WelcomeBuild Status

Introduction

This memory allocator is akin to ptmalloc2, jemalloc, tcmalloc and many others. These allocators are the underlying code of malloc.

Heap allocators request chunks of memory from the operating system and place several (small) object inside these. Using the free call these memory objects can be freed up again, allowing for reuse by future malloc calls. Important performance considerations of a heap allocator not only include being fast but also to reduce memory fragmentation.

malloc, free and realloc have been implemented without using the standard library versions of these functions. brk(2) and sbrk(2) has been used for asking the kernel for more heap space.

(Normal heap allocators may also use mmap to request memory from the kernel.)

Implementation Details

  1. malloc, free and realloc behave exactly as specified by their man-page description, whilst the Notes sections have been skipped as these are implementation-specific.
  2. This allocator does not place any restrictions on the maximum amount of memory supported or the maximum number of objects allocated. For example, it will scale regardless of whether the maximum brk size is 64KB or 1TB.
  3. A region of memory can be reused after freeing it with free.
  4. realloc behaves as described on its man-page and only allocates a new object when needed.
  5. The allocator batches brk calls, i.e., it does not need to request memory from the kernel for every allocation.
  6. The amortized overhead per allocation is on average 8 bytes or less.
  7. The allocator tries to optimize for locality (reuse recently freed memory).
  8. The allocator gives back memory to the kernel (using brk) when a large portion of the allocated memory has been freed up.
  9. The allocation functions work correctly without the my prefix.

Execution

The file test/tests.c contains a number of (automated) test cases that evaluate the different aspects of your allocator. It can be invoked manually via ./test <test name>. Running make check will run all test cases.

Notes

  • If you want to add support for replacing the system allocator (i.e., by adding non my prefixed functions) you can use your allocator for any existing program on your system. You can do this by prefixing any command with LD_PRELOAD=/path/to/libmyalloc.so. For example, LD_PRELOAD=./libmyalloc.so ls will run ls with the allocator.
  • Naming the functions such as malloc instead of mymalloc not only redirects all calls inside the code to this malloc, but will also cause all internal libc calls to go to this allocator instead of the built-in libcmalloc. Many libc functions, such as printf, internally make calls to malloc, and as such using printf inside the allocation code would cause an infinite loop. Therefore I prefix the allocator functions with my, but you are free to remove it.
  • MacOS is currently not supported but you could set up a Linux environment if you do not already have one (e.g., with a VM using virtualbox).
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Memory Allocator

MaintenancePRs WelcomeBuild Status

Introduction

This memory allocator is akin to ptmalloc2, jemalloc, tcmalloc and many others. These allocators are the underlying code of malloc.

Heap allocators request chunks of memory from the operating system and place several (small) object inside these. Using the free call these memory objects can be freed up again, allowing for reuse by future malloc calls. Important performance considerations of a heap allocator not only include being fast but also to reduce memory fragmentation.

malloc, free and realloc have been implemented without using the standard library versions of these functions. brk(2) and sbrk(2) has been used for asking the kernel for more heap space.

(Normal heap allocators may also use mmap to request memory from the kernel.)

Implementation Details

  1. malloc, free and realloc behave exactly as specified by their man-page description, whilst the Notes sections have been skipped as these are implementation-specific.
  2. This allocator does not place any restrictions on the maximum amount of memory supported or the maximum number of objects allocated. For example, it will scale regardless of whether the maximum brk size is 64KB or 1TB.
  3. A region of memory can be reused after freeing it with free.
  4. realloc behaves as described on its man-page and only allocates a new object when needed.
  5. The allocator batches brk calls, i.e., it does not need to request memory from the kernel for every allocation.
  6. The amortized overhead per allocation is on average 8 bytes or less.
  7. The allocator tries to optimize for locality (reuse recently freed memory).
  8. The allocator gives back memory to the kernel (using brk) when a large portion of the allocated memory has been freed up.
  9. The allocation functions work correctly without the my prefix.

Execution

The file test/tests.c contains a number of (automated) test cases that evaluate the different aspects of your allocator. It can be invoked manually via ./test <test name>. Running make check will run all test cases.

Notes

  • If you want to add support for replacing the system allocator (i.e., by adding non my prefixed functions) you can use your allocator for any existing program on your system. You can do this by prefixing any command with LD_PRELOAD=/path/to/libmyalloc.so. For example, LD_PRELOAD=./libmyalloc.so ls will run ls with the allocator.
  • Naming the functions such as malloc instead of mymalloc not only redirects all calls inside the code to this malloc, but will also cause all internal libc calls to go to this allocator instead of the built-in libcmalloc. Many libc functions, such as printf, internally make calls to malloc, and as such using printf inside the allocation code would cause an infinite loop. Therefore I prefix the allocator functions with my, but you are free to remove it.
  • MacOS is currently not supported but you could set up a Linux environment if you do not already have one (e.g., with a VM using virtualbox).
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Memory Allocator

MaintenancePRs WelcomeBuild Status

Introduction

This memory allocator is akin to ptmalloc2, jemalloc, tcmalloc and many others. These allocators are the underlying code of malloc.

Heap allocators request chunks of memory from the operating system and place several (small) object inside these. Using the free call these memory objects can be freed up again, allowing for reuse by future malloc calls. Important performance considerations of a heap allocator not only include being fast but also to reduce memory fragmentation.

malloc, free and realloc have been implemented without using the standard library versions of these functions. brk(2) and sbrk(2) has been used for asking the kernel for more heap space.

(Normal heap allocators may also use mmap to request memory from the kernel.)

Implementation Details

  1. malloc, free and realloc behave exactly as specified by their man-page description, whilst the Notes sections have been skipped as these are implementation-specific.
  2. This allocator does not place any restrictions on the maximum amount of memory supported or the maximum number of objects allocated. For example, it will scale regardless of whether the maximum brk size is 64KB or 1TB.
  3. A region of memory can be reused after freeing it with free.
  4. realloc behaves as described on its man-page and only allocates a new object when needed.
  5. The allocator batches brk calls, i.e., it does not need to request memory from the kernel for every allocation.
  6. The amortized overhead per allocation is on average 8 bytes or less.
  7. The allocator tries to optimize for locality (reuse recently freed memory).
  8. The allocator gives back memory to the kernel (using brk) when a large portion of the allocated memory has been freed up.
  9. The allocation functions work correctly without the my prefix.

Execution

The file test/tests.c contains a number of (automated) test cases that evaluate the different aspects of your allocator. It can be invoked manually via ./test <test name>. Running make check will run all test cases.

Notes

  • If you want to add support for replacing the system allocator (i.e., by adding non my prefixed functions) you can use your allocator for any existing program on your system. You can do this by prefixing any command with LD_PRELOAD=/path/to/libmyalloc.so. For example, LD_PRELOAD=./libmyalloc.so ls will run ls with the allocator.
  • Naming the functions such as malloc instead of mymalloc not only redirects all calls inside the code to this malloc, but will also cause all internal libc calls to go to this allocator instead of the built-in libcmalloc. Many libc functions, such as printf, internally make calls to malloc, and as such using printf inside the allocation code would cause an infinite loop. Therefore I prefix the allocator functions with my, but you are free to remove it.
  • MacOS is currently not supported but you could set up a Linux environment if you do not already have one (e.g., with a VM using virtualbox).
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Memory Allocator

MaintenancePRs WelcomeBuild Status

Introduction

This memory allocator is akin to ptmalloc2, jemalloc, tcmalloc and many others. These allocators are the underlying code of malloc.

Heap allocators request chunks of memory from the operating system and place several (small) object inside these. Using the free call these memory objects can be freed up again, allowing for reuse by future malloc calls. Important performance considerations of a heap allocator not only include being fast but also to reduce memory fragmentation.

malloc, free and realloc have been implemented without using the standard library versions of these functions. brk(2) and sbrk(2) has been used for asking the kernel for more heap space.

(Normal heap allocators may also use mmap to request memory from the kernel.)

Implementation Details

  1. malloc, free and realloc behave exactly as specified by their man-page description, whilst the Notes sections have been skipped as these are implementation-specific.
  2. This allocator does not place any restrictions on the maximum amount of memory supported or the maximum number of objects allocated. For example, it will scale regardless of whether the maximum brk size is 64KB or 1TB.
  3. A region of memory can be reused after freeing it with free.
  4. realloc behaves as described on its man-page and only allocates a new object when needed.
  5. The allocator batches brk calls, i.e., it does not need to request memory from the kernel for every allocation.
  6. The amortized overhead per allocation is on average 8 bytes or less.
  7. The allocator tries to optimize for locality (reuse recently freed memory).
  8. The allocator gives back memory to the kernel (using brk) when a large portion of the allocated memory has been freed up.
  9. The allocation functions work correctly without the my prefix.

Execution

The file test/tests.c contains a number of (automated) test cases that evaluate the different aspects of your allocator. It can be invoked manually via ./test <test name>. Running make check will run all test cases.

Notes

  • If you want to add support for replacing the system allocator (i.e., by adding non my prefixed functions) you can use your allocator for any existing program on your system. You can do this by prefixing any command with LD_PRELOAD=/path/to/libmyalloc.so. For example, LD_PRELOAD=./libmyalloc.so ls will run ls with the allocator.
  • Naming the functions such as malloc instead of mymalloc not only redirects all calls inside the code to this malloc, but will also cause all internal libc calls to go to this allocator instead of the built-in libcmalloc. Many libc functions, such as printf, internally make calls to malloc, and as such using printf inside the allocation code would cause an infinite loop. Therefore I prefix the allocator functions with my, but you are free to remove it.
  • MacOS is currently not supported but you could set up a Linux environment if you do not already have one (e.g., with a VM using virtualbox).
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Memory Allocator

MaintenancePRs WelcomeBuild Status

Introduction

This memory allocator is akin to ptmalloc2, jemalloc, tcmalloc and many others. These allocators are the underlying code of malloc.

Heap allocators request chunks of memory from the operating system and place several (small) object inside these. Using the free call these memory objects can be freed up again, allowing for reuse by future malloc calls. Important performance considerations of a heap allocator not only include being fast but also to reduce memory fragmentation.

malloc, free and realloc have been implemented without using the standard library versions of these functions. brk(2) and sbrk(2) has been used for asking the kernel for more heap space.

(Normal heap allocators may also use mmap to request memory from the kernel.)

Implementation Details

  1. malloc, free and realloc behave exactly as specified by their man-page description, whilst the Notes sections have been skipped as these are implementation-specific.
  2. This allocator does not place any restrictions on the maximum amount of memory supported or the maximum number of objects allocated. For example, it will scale regardless of whether the maximum brk size is 64KB or 1TB.
  3. A region of memory can be reused after freeing it with free.
  4. realloc behaves as described on its man-page and only allocates a new object when needed.
  5. The allocator batches brk calls, i.e., it does not need to request memory from the kernel for every allocation.
  6. The amortized overhead per allocation is on average 8 bytes or less.
  7. The allocator tries to optimize for locality (reuse recently freed memory).
  8. The allocator gives back memory to the kernel (using brk) when a large portion of the allocated memory has been freed up.
  9. The allocation functions work correctly without the my prefix.

Execution

The file test/tests.c contains a number of (automated) test cases that evaluate the different aspects of your allocator. It can be invoked manually via ./test <test name>. Running make check will run all test cases.

Notes

  • If you want to add support for replacing the system allocator (i.e., by adding non my prefixed functions) you can use your allocator for any existing program on your system. You can do this by prefixing any command with LD_PRELOAD=/path/to/libmyalloc.so. For example, LD_PRELOAD=./libmyalloc.so ls will run ls with the allocator.
  • Naming the functions such as malloc instead of mymalloc not only redirects all calls inside the code to this malloc, but will also cause all internal libc calls to go to this allocator instead of the built-in libcmalloc. Many libc functions, such as printf, internally make calls to malloc, and as such using printf inside the allocation code would cause an infinite loop. Therefore I prefix the allocator functions with my, but you are free to remove it.
  • MacOS is currently not supported but you could set up a Linux environment if you do not already have one (e.g., with a VM using virtualbox).
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Memory Allocator

MaintenancePRs WelcomeBuild Status

Introduction

This memory allocator is akin to ptmalloc2, jemalloc, tcmalloc and many others. These allocators are the underlying code of malloc.

Heap allocators request chunks of memory from the operating system and place several (small) object inside these. Using the free call these memory objects can be freed up again, allowing for reuse by future malloc calls. Important performance considerations of a heap allocator not only include being fast but also to reduce memory fragmentation.

malloc, free and realloc have been implemented without using the standard library versions of these functions. brk(2) and sbrk(2) has been used for asking the kernel for more heap space.

(Normal heap allocators may also use mmap to request memory from the kernel.)

Implementation Details

  1. malloc, free and realloc behave exactly as specified by their man-page description, whilst the Notes sections have been skipped as these are implementation-specific.
  2. This allocator does not place any restrictions on the maximum amount of memory supported or the maximum number of objects allocated. For example, it will scale regardless of whether the maximum brk size is 64KB or 1TB.
  3. A region of memory can be reused after freeing it with free.
  4. realloc behaves as described on its man-page and only allocates a new object when needed.
  5. The allocator batches brk calls, i.e., it does not need to request memory from the kernel for every allocation.
  6. The amortized overhead per allocation is on average 8 bytes or less.
  7. The allocator tries to optimize for locality (reuse recently freed memory).
  8. The allocator gives back memory to the kernel (using brk) when a large portion of the allocated memory has been freed up.
  9. The allocation functions work correctly without the my prefix.

Execution

The file test/tests.c contains a number of (automated) test cases that evaluate the different aspects of your allocator. It can be invoked manually via ./test <test name>. Running make check will run all test cases.

Notes

  • If you want to add support for replacing the system allocator (i.e., by adding non my prefixed functions) you can use your allocator for any existing program on your system. You can do this by prefixing any command with LD_PRELOAD=/path/to/libmyalloc.so. For example, LD_PRELOAD=./libmyalloc.so ls will run ls with the allocator.
  • Naming the functions such as malloc instead of mymalloc not only redirects all calls inside the code to this malloc, but will also cause all internal libc calls to go to this allocator instead of the built-in libcmalloc. Many libc functions, such as printf, internally make calls to malloc, and as such using printf inside the allocation code would cause an infinite loop. Therefore I prefix the allocator functions with my, but you are free to remove it.
  • MacOS is currently not supported but you could set up a Linux environment if you do not already have one (e.g., with a VM using virtualbox).
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Memory Allocator

MaintenancePRs WelcomeBuild Status

Introduction

This memory allocator is akin to ptmalloc2, jemalloc, tcmalloc and many others. These allocators are the underlying code of malloc.

Heap allocators request chunks of memory from the operating system and place several (small) object inside these. Using the free call these memory objects can be freed up again, allowing for reuse by future malloc calls. Important performance considerations of a heap allocator not only include being fast but also to reduce memory fragmentation.

malloc, free and realloc have been implemented without using the standard library versions of these functions. brk(2) and sbrk(2) has been used for asking the kernel for more heap space.

(Normal heap allocators may also use mmap to request memory from the kernel.)

Implementation Details

  1. malloc, free and realloc behave exactly as specified by their man-page description, whilst the Notes sections have been skipped as these are implementation-specific.
  2. This allocator does not place any restrictions on the maximum amount of memory supported or the maximum number of objects allocated. For example, it will scale regardless of whether the maximum brk size is 64KB or 1TB.
  3. A region of memory can be reused after freeing it with free.
  4. realloc behaves as described on its man-page and only allocates a new object when needed.
  5. The allocator batches brk calls, i.e., it does not need to request memory from the kernel for every allocation.
  6. The amortized overhead per allocation is on average 8 bytes or less.
  7. The allocator tries to optimize for locality (reuse recently freed memory).
  8. The allocator gives back memory to the kernel (using brk) when a large portion of the allocated memory has been freed up.
  9. The allocation functions work correctly without the my prefix.

Execution

The file test/tests.c contains a number of (automated) test cases that evaluate the different aspects of your allocator. It can be invoked manually via ./test <test name>. Running make check will run all test cases.

Notes

  • If you want to add support for replacing the system allocator (i.e., by adding non my prefixed functions) you can use your allocator for any existing program on your system. You can do this by prefixing any command with LD_PRELOAD=/path/to/libmyalloc.so. For example, LD_PRELOAD=./libmyalloc.so ls will run ls with the allocator.
  • Naming the functions such as malloc instead of mymalloc not only redirects all calls inside the code to this malloc, but will also cause all internal libc calls to go to this allocator instead of the built-in libcmalloc. Many libc functions, such as printf, internally make calls to malloc, and as such using printf inside the allocation code would cause an infinite loop. Therefore I prefix the allocator functions with my, but you are free to remove it.
  • MacOS is currently not supported but you could set up a Linux environment if you do not already have one (e.g., with a VM using virtualbox).
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Memory Allocator

MaintenancePRs WelcomeBuild Status

Introduction

This memory allocator is akin to ptmalloc2, jemalloc, tcmalloc and many others. These allocators are the underlying code of malloc.

Heap allocators request chunks of memory from the operating system and place several (small) object inside these. Using the free call these memory objects can be freed up again, allowing for reuse by future malloc calls. Important performance considerations of a heap allocator not only include being fast but also to reduce memory fragmentation.

malloc, free and realloc have been implemented without using the standard library versions of these functions. brk(2) and sbrk(2) has been used for asking the kernel for more heap space.

(Normal heap allocators may also use mmap to request memory from the kernel.)

Implementation Details

  1. malloc, free and realloc behave exactly as specified by their man-page description, whilst the Notes sections have been skipped as these are implementation-specific.
  2. This allocator does not place any restrictions on the maximum amount of memory supported or the maximum number of objects allocated. For example, it will scale regardless of whether the maximum brk size is 64KB or 1TB.
  3. A region of memory can be reused after freeing it with free.
  4. realloc behaves as described on its man-page and only allocates a new object when needed.
  5. The allocator batches brk calls, i.e., it does not need to request memory from the kernel for every allocation.
  6. The amortized overhead per allocation is on average 8 bytes or less.
  7. The allocator tries to optimize for locality (reuse recently freed memory).
  8. The allocator gives back memory to the kernel (using brk) when a large portion of the allocated memory has been freed up.
  9. The allocation functions work correctly without the my prefix.

Execution

The file test/tests.c contains a number of (automated) test cases that evaluate the different aspects of your allocator. It can be invoked manually via ./test <test name>. Running make check will run all test cases.

Notes

  • If you want to add support for replacing the system allocator (i.e., by adding non my prefixed functions) you can use your allocator for any existing program on your system. You can do this by prefixing any command with LD_PRELOAD=/path/to/libmyalloc.so. For example, LD_PRELOAD=./libmyalloc.so ls will run ls with the allocator.
  • Naming the functions such as malloc instead of mymalloc not only redirects all calls inside the code to this malloc, but will also cause all internal libc calls to go to this allocator instead of the built-in libcmalloc. Many libc functions, such as printf, internally make calls to malloc, and as such using printf inside the allocation code would cause an infinite loop. Therefore I prefix the allocator functions with my, but you are free to remove it.
  • MacOS is currently not supported but you could set up a Linux environment if you do not already have one (e.g., with a VM using virtualbox).