All Projects โ†’ mulle-c โ†’ mulle-allocator

mulle-c / mulle-allocator

Licence: other
๐Ÿ”„ Flexible C memory allocation scheme

Programming Languages

c
50402 projects - #5 most used programming language
CMake
9771 projects

Projects that are alternatives of or similar to mulle-allocator

MemoryAllocator.KanameShiki
Fast multi-threaded memory allocator
Stars: โœญ 73 (-5.19%)
Mutual labels:  allocator, memory-allocation
buddy alloc
A single header buddy memory allocator for C
Stars: โœญ 46 (-40.26%)
Mutual labels:  allocator, memory-allocation
Wagon
ๅ…ๅฎ‰่ฃๅฏๆ”œ็š„ Laravel ้–‹็™ผ็’ฐๅขƒ
Stars: โœญ 189 (+145.45%)
Mutual labels:  portable
tgc
A Tiny, portable, precise, incremental mark-sweep GC designed for C++.
Stars: โœญ 36 (-53.25%)
Mutual labels:  portable
Boost.simd
Boost SIMD
Stars: โœญ 238 (+209.09%)
Mutual labels:  portable
Pockint
A portable OSINT Swiss Army Knife for DFIR/OSINT professionals ๐Ÿ•ต๏ธ ๐Ÿ•ต๏ธ ๐Ÿ•ต๏ธ
Stars: โœญ 196 (+154.55%)
Mutual labels:  portable
osmid
osmid is a tool to bridge MIDI and OSC. It is currently in use in Sonic Pi
Stars: โœญ 63 (-18.18%)
Mutual labels:  portable
Fast Ide
๐Ÿ•บFast Integrated Development Environment ๐Ÿ˜ป
Stars: โœญ 181 (+135.06%)
Mutual labels:  portable
portabledevops
A portable devops tool set on windows, easy customization of cmder/console+msys2/cygwin/wsl
Stars: โœญ 53 (-31.17%)
Mutual labels:  portable
Postgresql Portable
Portable version of the PostgreSQL Database Server, for Windows
Stars: โœญ 237 (+207.79%)
Mutual labels:  portable
duma
duma: Detect Unintended Memory Access (D.U.M.A.) - A Red-Zone memory allocator
Stars: โœญ 63 (-18.18%)
Mutual labels:  allocator
Mlibc
Portable C standard library
Stars: โœญ 225 (+192.21%)
Mutual labels:  portable
Libagar
Cross-Platform GUI Toolkit (stable)
Stars: โœญ 212 (+175.32%)
Mutual labels:  portable
Messenger For Desktop
This is not an official Facebook product, and is not affiliated with, or sponsored or endorsed by, Facebook.
Stars: โœญ 2,180 (+2731.17%)
Mutual labels:  portable
wic
WebSockets in C for Embedded Applications
Stars: โœญ 60 (-22.08%)
Mutual labels:  portable
Atom Portable
Portable version of the Atom text editor
Stars: โœญ 187 (+142.86%)
Mutual labels:  portable
Libonnx
A lightweight, portable pure C99 onnx inference engine for embedded devices with hardware acceleration support.
Stars: โœญ 217 (+181.82%)
Mutual labels:  portable
Mipp
MIPP is a portable wrapper for SIMD instructions written in C++11. It supports NEON, SSE, AVX and AVX-512.
Stars: โœญ 253 (+228.57%)
Mutual labels:  portable
oracle-jdk-portable
๐Ÿš€ Oracle JDK portable for Windows
Stars: โœญ 24 (-68.83%)
Mutual labels:  portable
nitroml
NitroML is a modular, portable, and scalable model-quality benchmarking framework for Machine Learning and Automated Machine Learning (AutoML) pipelines.
Stars: โœญ 40 (-48.05%)
Mutual labels:  portable

mulle-allocator

๐Ÿ”„ Flexible C memory allocation scheme

... provides a way to pass around the memory scheme du jour

... has identical API to malloc, realloc, free

... frees your code from having to check for errors when allocating memory

mulle-allocator has a companion project: mulle-testallocator. mulle-testallocator provides the error and leak detection, that was formerly a part of mulle-allocator..

Release Version
Mulle kybernetiK tag Build Status

Use mulle_malloc instead of malloc to reduce code size

Instead of:

   if( ! malloc( 1848))
   {
      perror( "malloc:");
      exit( 1);
   }
   if( ! calloc( 18, 48))
   {
      perror( "calloc:");
      exit( 1);
   }
   s = strdup( "VfL Bochum 1848");
   if( ! s)
   {
      perror( "strdup:");
      exit( 1);
   }
   if( ! realloc( s, 18);
   {
      perror( "realloc:");
      exit( 1);
   }
   free( s);

write

   mulle_malloc( 1848);
   mulle_calloc( 18, 48);
   s = mulle_strdup( "VfL Bochum 1848");
   mulle_realloc( s, 18);
   mulle_free( s);

You don't have to check for out of memory error conditions anymore. Otherwise your code will run the same and a possible performance degradation because of the indirection will be hardly measurable.

How mulle-allocator deals with memory shortage

By the C standard malloc returns NULL and sets errno to ENOMEM, if it can't satisfy the memory request. Here are the two most likely scenarios why this happens:

The caller specified a huge amount of memory, that the OS can't give you. Typically (size_t) -1 can never work. This is considered to be a bug on the callers part.

Or the program has exhausted all memory space available to the process. Here is what happens on various OS:

OS malloc fate
FreeBSD malloc hangs, probably waiting for memory to become available
MacOS X malloc slowly brings the system to a crawl, no error observed
Linux malloc returns an error
Windows unknown

The gist is, that in portable programs it doesn't really make sense to rely on malloc returning NULL and doing something clever based on it.

If we define the mulle-allocator malloc to always return a valid memory block - discounting erroneous parameters as programmers error, to be caught during development - then memory calling code simplifies from:

p = malloc( size);
if( ! p)
   return( -1);
memcpy( p, q, size);

to

p = mulle_malloc( size);
memcpy( p, q, size);

Use mulle_allocator to make your code more flexible

You can make your code, and especially your data structures, more flexible by using a mulle_allocator. This decouples your data structure from stdlib. It enables your data structure to reside in shared or wired memory with no additional code. Your API consumers just have to pass their own allocators.

Also it can be helpful to isolate your data structure memory allocation during tests. This way, other, possibly benign, code leaks, do not obscure the test.

What is an allocator ?

The mulle_allocator struct is a collection of function pointers, with one added pointer for aba and looks like this:

struct mulle_allocator
{
   void   *(*calloc)( size_t n, size_t size, struct mulle_allocator *p);
   void   *(*realloc)( void *block, size_t size, struct mulle_allocator *p);
   void   (*free)( void *block, struct mulle_allocator *p);
   void   (*fail)( struct mulle_allocator *p, void *block, size_t size) MULLE_C_NO_RETURN;
   int    (*abafree)( void *aba, void (*free)( void *), void *block);
   void   *aba;
};

By default .aba and .abafree are not available. If you need ABA safe freeing, it is recommended to use mulle-aba.

You should not jump through the vectors directly, but use supplied inline functions like mulle_allocator_malloc, as they perform the necessary return value checks (see below: Dealing with memory shortage).

The shortcut functions mulle_malloc use the mulle_default_allocator by default and save you some typework. You can also use NULL as the allocator for mulle_allocator_malloc with the same effect of choosing the mulle_default_allocator.

Embedding the allocator in your data structure

A pointer to the allocator could be kept in your data structure. This simplifies your API, as the allocator is only needed during creation. Here is an example how to use the allocator in this fashion:

struct my_string
{
   struct mulle_allocator   *allocator;
   char                     s[ 1];
};


struct my_string   *my_string_alloc( char *s, struct mulle_allocator *allocator)
{
   size_t              len;
   struct my_string    *p;

   len = s ? strlen( s) : 0;
   p   = mulle_allocator_malloc( allocator, sizeof( struct my_string) + len);
   dst->allocator = allocator;
   memcpy( p->s, s, len);
   p->s[ len] = 0;
   return( p);
}


static inline void   my_string_free( struct my_string *p)
{
   mulle_allocator_free( p->allocator, p);
}

Not embedding the allocator in your data structure

But if you don't want to store the allocator inside the data structure, you can pass it in again:

struct my_other_string
{
   char   s[ 1];
};


struct my_other_string   *my_other_string_alloc( char *s, struct mulle_allocator *allocator)
{
   size_t                    len;
   struct my_other_string    *p;

   len = s ? strlen( s) : 0;
   p   = mulle_allocator_malloc( allocator, sizeof( struct my_other_string) + len);
   memcpy( p->s, s, len);
   p->s[ len] = 0;
   return( p);
}


static inline void   my_other_string_free( struct my_other_string *p,
                                           struct mulle_allocator *allocator)
{
   mulle_allocator_free( allocator, p);
}

The disadvantage is, that this opens the door for bugs, as you may be using different allocators accidentally.

Caveats

The mulle_default_allocator and mulle_stdlib_allocator never return, if the allocation went bad. If an allocator function detects, that an allocation can not be satisfied, it jumps through its fail vector. This will print an error message and exit the program.

You can not pass a zero size to either mulle_realloc or mulle_malloc without getting a failure. If you want to free memory with realloc - by passing a zero block size - you need to use mulle_realloc_strict. If you pass a zero block size and a zero block to mulle_realloc_strict, it will return NULL.

API

You are here

Overview

Add

Use mulle-sde to add mulle-allocator to your project:

mulle-sde dependency add --c --github mulle-c mulle-allocator

Install

mulle-sde

Use mulle-sde to build and install mulle-allocator and all dependencies:

mulle-sde install --prefix /usr/local \
   https://github.com/mulle-c/mulle-allocator/archive/latest.tar.gz

Manual Installation

Install the requirements:

Requirements Description
mulle-c11 Compiler glue

Install into /usr/local:

cmake -B build \
      -DCMAKE_INSTALL_PREFIX=/usr/local \
      -DCMAKE_PREFIX_PATH=/usr/local \
      -DCMAKE_BUILD_TYPE=Release &&
cmake --build build --config Release &&
cmake --install build --config Release

Author

Nat! for Mulle kybernetiK and Codeon GmbH

Platforms and Compilers

All platforms and compilers supported by mulle-c11.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].