Thursday, June 20, 2013

A custom C++ allocator

Custom standard C++ allocators can be very useful.
Unfortunately, C++ allocators may be a less known or misunderstood feature.

Important references are:
  
A possibly associated reference is:
  

Particularly, there may be excellent libraries out there, for instance, Boost, but at the same time, I think those libraries are too complex. Not that an industrial approach isn't a must, but I think that a negative aspect of them are the considerably verbose coding imposed by the artifacts, beyond the burden of headers and libraries, not counting the their build process.

I believe in a simpler interface surface, yet industrial implementation, specially in terms of algorithms and strategies, but not so much in terms of multi-platform specific detail, which is often conveniently complemented by vendors.

I'll now start an "ambitious attempt" (at least to me) to implement some C++ artifacts around memory allocation for leveraging Solaris (D)ISM. It's not my intention to reinvent the wheel, but simply provide an implementation that can be used in Solaris.

While I was delving into the challenge, inspired by Bjarne Stroustrup's example found on Section 19.4 of the The C++ Programming Language and browsing Solaris man pages , I soon realized that the need to devise memory alignment artifacts is a must. I've gladly found another useful example by Tomasz Müldner & Peter W. Steele on sections 7.3.2.1 on page 149,  9.2 on page 277 and 13.3 on page 390 of the C as a Second Language for Native Speakers of Pascal.

As one thing leads to another, I also realized that memory page size could play a role in the implementation as to the memory chunks of an allocation pool. To further complicate matters, Solaris, at least, may support different system memory page sizes despite the hardware page size as indicated in getpagesize(3C). According to getpagesizes(3C), "not all processors support all page sizes or combinations of page sizes with equal efficiency." Fortunately, by means of memcntl(2) we can advice the system, MC_HAT_ADVICE (Hardware Address Translation), to set the page size of a segment "based on the size and alignment of the memory region, type of processor, and other considerations". By using meminfo(2) we can obtain the page size, MEMINFO_VPAGESIZE, of a segment.

Smart pointers seems very useful for implementing underlying storage pools in order to support efficient allocator copy and assignment while maintaining the required semantics.

With respect to rebinding semantics, another standard requirement, I tend to follow the most basic concept of SLAB allocation: a per object cache. Of course I'm not going mad for that, but if you want to know about SLAB see: