Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Nov 2013 04:31:33 +0100
From:      dt71@gmx.com
To:        freebsd-current <freebsd-current@freebsd.org>
Subject:   Re: [RFC] how to get the size of a malloc(9) block ?
Message-ID:  <52995C15.7010903@gmx.com>
In-Reply-To: <CA%2BhQ2%2BiCjnxUMP0v6d5ez=n07MBT5hLXzoa%2B1wTff3Wrtm=SHQ@mail.gmail.com>
References:  <CA%2BhQ2%2BgK1pc_aS1LEKp29Bi=MHFtJCkw2uOrib_9wQ-7AziH=w@mail.gmail.com> <loom.20131130T002152-608@post.gmane.org> <CA%2BhQ2%2Bj0cYW0dfhEtMGRXWhXhS=VF_N_ZB=JmcqRUofFKWXFiQ@mail.gmail.com> <loom.20131130T012034-966@post.gmane.org> <CA%2BhQ2%2BiCjnxUMP0v6d5ez=n07MBT5hLXzoa%2B1wTff3Wrtm=SHQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
What is the supposed definition of malloc_usable_size(p) in a hypothetical, upcoming C standard? With the rest of the C standard remaining the same, one could try:

Definition: The value of malloc_usable_size(p) is the amount of space allocated for object p, plus the amount of space after object p that can currently be written without messing up other objects or memory-management areas.

This definition is practically useless, because data written to the slack space after the object could be claimed by calls to alloc()ish function -- perhaps by other threads. Another attempt at the defining something useful:

Definition: The value of malloc_usable_size(p) is the amount of space allocated for object p, plus the amount of space after object p that can be written without messing up other objects or memory-management areas, while alloc()ish functions are not called on p.

With this, one asks the question: How much is usually overallocated? In some implementations, usually just a few bytes (say, when the minimal allocation unit is 8 bytes); where not, it can be said that the memory manager is quite space-leaky.

It appears that it's not possible to make a proper API with malloc_usable_size() included, at least when multi-threading is involved (ie., in the modern world).

However, it is still useful to create an API that supports the following cases:

- A program knows how to adapt to memory fragmentation without moving an ever-growing, but chainable array of data.
- A program would become faster, if it knew when moving is required; then, the program could update various pointer-based (as opposed to arrayindex-based) references to the object being moved. (Just like when memory is defragmentated in a garbage-collected programming language.)
- A program requires more memory in real-time, which means to either receive more memory immediately and do something, or to signal a real-time failure.

So new flags could be [1]:
- realloc_flags(p, s, REALLOCF_NO_MOVE): Resize object p, without moving it, to size s. With this restriction, when requesting more memory, and the specified amount isn't available, don't do anything (when requesting less memory, always succeed).
- realloc_flags(p, s, REALLOCF_NO_MOVE | REALLOCF_ELASTIC): Resize object p, without moving it, to size s. With this restriction, when requesting more memory, and the specified amount isn't available, reserve as much as possible (when requesting less memory, always succeed).

On the other hand, be advised of a hypothetical scenario, in which realloc() would like to jump at the opportunity to move the object to a different space, say, for the purpose of condensing slack space, when statistics show that allocated areas have plenty of holes. This means that the design of the new API can have more goals:

- The allocator implementation should be able to shape the workings of a program at quick-realloc points, for example, by coaxing it to call realloc() when memory is very scattered.
- The program should always be able to take advantage of a quick-realloc functionality, for example, to support certain real-time requirements of applications, to the extent reasonably possible within the implementation.

For this, there could be a REALLOCF_FORCE flag, to be used in real-time scenarios. Without the flag, the call can be expected to be rejected on the basis of some implementation-specific preference, such as anti-fragmentation.

Is there any insufficiency in this API, in anyone's mind?

[1] When such a distinction makes sense and is supported (not stubbed) in the current architecture, environment, implementation, etc.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?52995C15.7010903>