malloc

#include <cruntime.h>
#include <assert.h>
#include <heap.h>
#include <malloc.h>
#include <os2dll.h>
#include <stddef.h>

#ifndef _POSIX_
#include <new.h>
_PNH _pnhHeap = NULL; /* pointer to new() handler */
#endif

#ifdef MTHREAD

void * _CALLTYPE1 malloc (
 size_t size
 )
{
 void *pret;

#ifndef _POSIX_
    for (;;)
    {
#endif
       /* lock the heap
 */
 _mlock(_HEAP_LOCK);

 /* do the allocation
  */
 pret = _malloc_lk(size);

 /* unlock the heap
  */
 _munlock(_HEAP_LOCK);

#ifndef _POSIX_
    if (pret || _pnhHeap == NULL || (*_pnhHeap)(size) == 0)
#endif
 return(pret);

#ifndef _POSIX_
    }
#endif  /* ndef _POSIX_ */
}


void * _CALLTYPE1 _malloc_lk (
 size_t size
 )

#else /* ndef MTHREAD */

void * _CALLTYPE1 malloc (
 size_t size
 )

#endif /* MTHREAD */

#ifdef _CRUISER_

{
 char *pblck;
 _PBLKDESC pdesc;
 size_t dist;

 /* round size up to the nearest whole number of dwords
  */
 size = _ROUND2(size, 4);

 /* first try allocating a block of size bytes
  */
 if ( ((pblck = _flat_malloc(size)) == NULL) || (size > _SEGSIZE_) ||
 (_DISTTOBNDRY(pblck) >= size) )
  /* all done!
   */
  goto done;
 else

  _free_lk(pblck);


 if ( (pblck = _flat_malloc(2*size)) == NULL )
  /* allocation failed, return NULL to the caller
   */
  goto done;

 /* set pdesc to point to the descriptor for the allocation block
  */
 pdesc = _BACKPTR(pblck);


 if ( (dist = _DISTTOBNDRY(pblck)) < size ) {

  _heap_split_block(pdesc, dist - _HDRSIZE);
  _free_lk(pblck);
  pdesc = pdesc->pnextdesc;
  _SET_INUSE(pdesc);
  pblck += dist;
 }

#ifdef _OLDROVER_

 _heap_split_block(pdesc, size);
 _SET_FREE(pdesc->pnextdesc);
 _heap_advance_rover();

#else /* ndef _OLDROVER_ */

 if ( _BLKSIZE(pdesc) > size ) {
  _heap_split_block(pdesc, size);
  _SET_FREE(pdesc->pnextdesc);
  _heap_desc.proverdesc = pdesc->pnextdesc;
 }

#endif /* _OLDROVER_ */

done:
 return(pblck);
}

void * _CALLTYPE1 _flat_malloc (
 size_t size
 )

#endif /* _CRUISER_ */

{
 _PBLKDESC pdesc;


 size = _ROUND2(size, 4);

#if !defined(_POSIX_) && !defined(MTHREAD)
    for (;;)
    {
#endif /* !_POSIX && !MTHREAD */
 /* try to find a big enough free block
  */
  if ( (pdesc = _heap_search(size)) == NULL )
  if ( _heap_grow(size) != -1 ) {

   if ( (pdesc = _heap_search(size)) == NULL )

    _heap_abort();
  }
#if !defined(_POSIX_) && !defined(MTHREAD)
  else if (!_pnhHeap || (*_pnhHeap)(size) == 0)
   return(NULL);
  else
   continue;
  else
  break; /* success! */
    }
#else /* _POSIX || MTHREAD */
  else
   return(NULL);
#endif /* !_POSIX && !MTHREAD */


 if ( _BLKSIZE(pdesc) != size ) {
  /* split up the block and free the leftover piece back to
   * the heap
   */
  _heap_split_block(pdesc, size);
  _SET_FREE(pdesc->pnextdesc);
 }

 /* mark pdesc inuse
  */
 _SET_INUSE(pdesc);

 /* check proverdesc and reset, if necessary
  */
#ifdef _OLDROVER_

 _heap_advance_rover();

#else /* ndef _OLDROVER_ */

 _heap_desc.proverdesc = pdesc->pnextdesc;

#endif /* _OLDROVER_ */

 return( (void *)((char *)_ADDRESS(pdesc) + _HDRSIZE) );
}


void _CALLTYPE1 _heap_split_block (
 REG1 _PBLKDESC pdesc,
 size_t newsize
 )
{
 REG2 _PBLKDESC pdesc2;

 assert(("_heap_split_block: bad pdesc arg", _CHECK_PDESC(pdesc)));
 assert(("_heap_split_block: bad newsize arg", _ROUND2(newsize,4) == newsize));

 /* carve the block into two pieces (if possible). the first piece
  * is to be exactly newsize bytes.
  */
 if ( _BLKSIZE(pdesc) > newsize ) {
  /* get an empty decriptor
   */
  _GETEMPTY(pdesc2)

  /* set it up to manage the second piece and link it in to
   * the list
   */
  pdesc2->pblock = (void *)((char *)_ADDRESS(pdesc) + newsize +
  _HDRSIZE);
  *(void **)(pdesc2->pblock) = pdesc2;
  pdesc2->pnextdesc = pdesc->pnextdesc;
  pdesc->pnextdesc = pdesc2;
 }
}

#ifdef _OLDROVER_


void _CALLTYPE1 _heap_advance_rover(void)
{
 REG1 _PBLKDESC pdesc;

 /* check proverdesc and advance it, if necessary
  */

#ifdef _CRUISER_ /* CRUISER TARGET */

   if ( !_IS_FREE(_heap_desc.proverdesc) && (_heap_desc.proverdesc !=
   &_heap_desc.sentinel) ) {

#else /* ndef _CRUISER_ */

#ifdef _WIN32_

 if ( _heap_desc.proverdesc != &_heap_desc.sentinel &&
     (!_IS_FREE(_heap_desc.proverdesc) ||
     _BLKSIZE(_heap_desc.proverdesc) <= 8)) {

#else /* ndef _WIN32_ */

#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!

#endif /* _WIN32_ */

#endif /* _CRUISER_ */

  /* set pdesc to point to the descriptor for the next free
   * block, if any, or &sentinel, otherwise.
   */
  for ( pdesc = (_heap_desc.proverdesc)->pnextdesc ;
#ifdef _CRUISER_ /* CRUISER TARGET */
       !(_IS_FREE(pdesc)) && (pdesc != &_heap_desc.sentinel) ;
#else /* ndef _CRUISER_ */
#ifdef _WIN32_
       pdesc != &_heap_desc.sentinel &&
       (!(_IS_FREE(pdesc)) || _BLKSIZE(pdesc) <= 8) ;
#else /* ndef _WIN32_ */

#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!

#endif /* _WIN32_ */

#endif /* _CRUISER_ */
       pdesc = pdesc->pnextdesc )
                        ;

  /* update proverdesc with pdesc
   */
  _heap_desc.proverdesc = pdesc;
 }
}

#endif /* _OLDROVER_ */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值