next up previous contents
Next: 2.4.9.1 The bitmap allocator Up: 2.4 System resources Previous: 2.4.8 Allocation statistics

2.4.9 Allocators used in the kernel

\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); }

};
Defines off_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;
};

Defines off_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. >
};
Defines off_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+ and operator- 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;
}

\label{sec:fixnblock}


 

Francisco J. Ballesteros
1998-05-25