\subsubsection{A raw allocator}
To provide a uniform interface to allocation without dynamic binding
we use indexers. They are simply arrays interfacing with the outside
world by means of void pointers. Their use is safe because they
are later wrapped by type-safe interfaces.
<Off indexer. >= (U->)
template <class T>
class off_Indexer {
public:
void *add(const void *p, int i) const { return (void*)((T*)p+i); }
void *sub(const void *p, int i) const { return (void*)((T*)p-i); }
natural_t sub(const void *p, const void *q) const{
return (T*)p - (T*)q;
}
natural_t sub_unaligned(const void *p, const void *q) const {
return ((char*)p - (char*)q)/sizeof(T);
}
void *inc(void *&p) const { return p=(void*)((T*)p+1); }
void *dec(void *&p) const { return p=(void*)((T*)p-1); }
size_t sz(void) const { return sizeof(T); }
};
Definesoff_Indexer(links are to index).
<Off indexer dependencies. >= (U->) #include <flux/types.h> // for boolean_t natural_t et al.
Allocator users will access to Indexer instantiations by means of
the Indexable interface.
<Off indexable. >= (U->)
signature off_Indexable {
void *add(const void *p, int i) const;
void *sub(const void *p, int i) const;
natural_t sub(const void *p, const void *q) const;
natural_t sub_unaligned(const void *p, const void *q) const;
void *inc(void *&p) const;
void *dec(void *&p) const;
size_t sz(void) const;
};
Definesoff_Indexable(links are to index).
\subsubsection{The basic kernel allocator}
Every kernel allocator uses an Indexable as the means for resource
allocation and provides statistics by deriving from BKAllocator.
<Off basic kernel allocator. >= (U->)
class off_KernAllocator : public off_BKAllocator {
protected:
const off_Indexable *k_idx; // Resource indexer.
void *k_first; // First resource unit.
void *k_last; // Last resource unit.
public:
// To declare uninitialized allocators.
off_KernAllocator(void){;}
// Creates a basic kernel allocator.
off_KernAllocator(off_Exhausted *r, const off_Indexable *idx,
void *first, natural_t len) :
off_BKAllocator(r,len), k_idx(idx),
k_first(first), k_last(k_idx->add(first,len))
{ ; }
<Other public methods of off_KernAllocator. >
};
Definesoff_KernAllocator(links are to index).
<Off basic kernel allocator dependencies. >= (U->) #include <flux/types.h> // for boolean_t natural_t et al. #include <klib/BKAllocator.h> // for off_BKAllocator #include <klib/Indexer.h> // for off_Indexable
Some simple methods are provide as a support for pointer arithmetic.
<Other public methods of off_KernAllocator. >= (<-U) [D->]
void *operator+(natural_t at) const;
natural_t pos(const void*p) const;
<off_KernAllocator::operator+andoperator-implementation. >= (U->) void *off_KernAllocator::operator+(natural_t at) const { return k_idx->add(k_first,at); } natural_t off_KernAllocator::pos(const void*p) const { assert(p > k_first && p < k_last); return k_idx->sub(p,k_first); }
Besides, any pointer given to the user must be in that range.
<Other public methods of off_KernAllocator. >+= (<-U) [<-D]
boolean_t ptr_valid(const void *p) const {
return k_first <= p && p <= k_last;
}