// Allocations are done in 'quantas' of header size.
// The search for a free block of adequate size begins at the point 'freep'
// where the last block was found.
// If a too-big block is found, it is split and the tail is returned (this
// way the header of the original needs only to have its size adjusted).
// The pointer returned to the user points to the free space within the block,
// which begins one quanta after the header.
//
void *memmgr_alloc(ulong nbytes, int *err) {
  mem_header_t *p;
  mem_header_t *prevp;

  *err = 0;

  // Calculate how many quantas are required: we need enough to house all
  // the requested bytes, plus the header. The -1 and +1 are there to make sure
  // that if nbytes is a multiple of nquantas, we don't allocate too much
  //
  ulong nquantas =
      (nbytes + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1;

  // First alloc call, and no free list yet ? Use 'base' for an initial
  // denegerate block of size 0, which points to itself
  //
  if ((prevp = freep) == 0) {
    base.s.next = freep = prevp = &base;
    base.s.size = 0;
  }

  for (p = prevp->s.next;; prevp = p, p = p->s.next) {
    // big enough ?
    if (p->s.size >= nquantas) {
      // exactly ?
      if (p->s.size == nquantas) {
        // just eliminate this block from the free list by pointing
        // its prev's next to its next
        //
        prevp->s.next = p->s.next;
      } else // too big
      {
        p->s.size -= nquantas;
        p += p->s.size;
        p->s.size = nquantas;
      }

      freep = prevp;
      return (void *)(p + 1);
    }
    // Reached end of free list ?
    // Try to allocate the block from the pool. If that succeeds,
    // get_mem_from_pool adds the new block to the free list and
    // it will be found in the following iterations. If the call
    // to get_mem_from_pool doesn't succeed, we've run out of
    // memory
    //
    else if (p == freep) {
      if ((p = get_mem_from_pool(nquantas)) == 0) {
        *err = 1;
        return 0;
      }
    }
  }
}
Exemple #2
0
// Allocations are done in 'quantas' of header size.
// The search for a free block of adequate size begins at the point 'memmgr.freep'
// where the last block was found.
// If a too-big block is found, it is split and the tail is returned (this
// way the header of the original needs only to have its size adjusted).
// The pointer returned to the user points to the free space within the block,
// which begins one quanta after the header.
//
void* memmgr_alloc(size_t nuint8_ts)
{
    MemMgrState& memmgr = get_local_memmgr();
    mem_header_t* p;
    mem_header_t* prevp;

    // Calculate how many quantas are required: we need enough to house all
    // the requested uint8_ts, plus the header. The -1 and +1 are there to make sure
    // that if nuint8_ts is a multiple of nquantas, we don't allocate too much
    //
    size_t nquantas = (nuint8_ts + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1;

    // First alloc call, and no free list yet ? Use 'base' for an initial
    // degenerate block of size 0, which points to itself
    //
    if ((prevp = memmgr.freep) == 0)
    {
        memmgr.base.s.next = memmgr.freep = prevp = &memmgr.base;
        memmgr.base.s.size = 0;
    }

    for (p = prevp->s.next; ; prevp = p, p = p->s.next)
    {
        // big enough ?
        if (p->s.size >= nquantas)
        {
            // exactly ?
            if (p->s.size == nquantas)
            {
                // just eliminate this block from the free list by pointing
                // its prev's next to its next
                //
                prevp->s.next = p->s.next;
            }
            else // too big
            {
                p->s.size -= nquantas;
                p += p->s.size;
                p->s.size = nquantas;
            }

            memmgr.freep = prevp;
            return (void*) (p + 1);
        }
        // Reached end of free list ?
        // Try to allocate the block from the memmgr.pool. If that succeeds,
        // get_mem_from_pool adds the new block to the free list and
        // it will be found in the following iterations. If the call
        // to get_mem_from_pool doesn't succeed, we've run out of
        // memory
        //
        else if (p == memmgr.freep)
        {
            if ((p = get_mem_from_pool(memmgr, nquantas)) == 0)
            {
                #ifdef DEBUG_MEMMGR_FATAL
                printf("!! Memory allocation failed !!\n");
                #endif
#ifdef MEMMGR_EXIT_OOM
                exit(38);
#endif

                return 0;
            }
        }
    }
}
Exemple #3
0
// Allocations are done in 'quantas' of header size.
// The search for a free block of adequate size begins at the point 'freep'
// where the last block was found.
// If a too-big block is found, it is split and the tail is returned (this
// way the header of the original needs only to have its size adjusted).
// The pointer returned to the user points to the free space within the block,
// which begins one quanta after the header.
//
void * s16mem_alloc (unsigned long nbytes)
{
    void * m;
    mem_header_t * p;
    mem_header_t * prevp;

    /* We first try to use the system malloc. */
    if ((m = malloc (nbytes)))
        return m;

    // Calculate how many quantas are required: we need enough to house all
    // the requested bytes, plus the header. The -1 and +1 are there to make
    // sure
    // that if nbytes is a multiple of nquantas, we don't allocate too much
    //
    unsigned long nquantas =
        (nbytes + sizeof (mem_header_t) - 1) / sizeof (mem_header_t) + 1;

    // First alloc call, and no free list yet ? Use 'base' for an initial
    // denegerate block of size 0, which points to itself
    //
    if ((prevp = freep) == 0)
    {
        base.s.next = freep = prevp = &base;
        base.s.size = 0;
    }

    for (p = prevp->s.next;; prevp = p, p = p->s.next)
    {
        // big enough ?
        if (p->s.size >= nquantas)
        {
            // exactly ?
            if (p->s.size == nquantas)
            {
                // just eliminate this block from the free list by pointing
                // its prev's next to its next
                //
                prevp->s.next = p->s.next;
            }
            else // too big
            {
                p->s.size -= nquantas;
                p += p->s.size;
                p->s.size = nquantas;
            }

            freep = prevp;
            return (void *)(p + 1);
        }
        // Reached end of free list ?
        // Try to allocate the block from the pool. If that succeeds,
        // get_mem_from_pool adds the new block to the free list and
        // it will be found in the following iterations.
        else if (p == freep)
        {
            if ((p = get_mem_from_pool (nquantas)) == 0)
            {
                /* now we really are in trouble. this should NEVER happen. */
                exit (1);
                fprintf (stderr, "!! Memory allocation failed !!\n");
                return 0;
            }
        }
    }
}