Ответ:
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено _гоша 13 августа 2004 г. 11:02
В ответ на: Обясните мне как работает malloc? отправлено lamerok 13 августа 2004 г. 09:34


/*****************************************************************************/
/* */
/* MALLOC - Allocate a packet of a given size, and return pointer to it. */
/* */
/*****************************************************************************/
void *malloc(size_t size)
{
memsz_t allocsize = size;
PACKET *current, *next, *prev;

if (allocsize == 0) return 0;

/*-----------------------------------------------------------------------*/
/* We may need to adjust the size of the allocation request to ensure */
/* that the address of the field "next_free" remains strictly aligned */
/* in all packets on the free list. */
/*-----------------------------------------------------------------------*/
if ((allocsize ^ OVERHEAD) & 1) ++allocsize;

_lock();

if (first_call) minit();

current = sys_free;
prev = 0;

/*-----------------------------------------------------------------------*/
/* Find the first block large enough to hold the requested allocation */
/*-----------------------------------------------------------------------*/
while (current != LIMIT && -current->packet_size < allocsize)
{
prev = current;
current = current->next_free;
}

if (current == LIMIT)
{
/*-------------------------------------------------------------------*/
/* No block large enough was found, so return NULL. */
/*-------------------------------------------------------------------*/
_unlock();
return 0;
}

if (-current->packet_size > (allocsize + OVERHEAD + MINSIZE))
{
/*-------------------------------------------------------------------*/
/* The packet is larger than needed; split the block and mark the */
/* smaller-addressed block as used. The smaller-addressed block */
/* was chosen as a way to ensure that freed blocks get recycled */
/* before allocations are made from the large original free block. */
/* However, this may tend to increase the length of the free list */
/* search for a large enough block. */
/*-------------------------------------------------------------------*/
/* Knuth's algorithm 2.5a instead allocates the larger-addressed */
/* block to the user. This tends to leave the largest free blocks */
/* at the beginning of the free list. Knuth's 2.5a' uses a "rover" */
/* pointer to prevent small free blocks from being concentrated in */
/* any part of the list. */
/*-------------------------------------------------------------------*/
next = (PACKET *)((char *)current + allocsize + OVERHEAD);
next->packet_size=current->packet_size+allocsize+OVERHEAD;/*NEG==FREE*/
#ifdef DEBUG
next->guard = GUARDDWORD;
#endif
current->packet_size = allocsize; /* POSITIVE==IN USE */

if (prev) prev->next_free = next;
else sys_free = next;

next->next_free = current->next_free;
}
else
{
/*-------------------------------------------------------------------*/
/* Allocate the whole block and remove it from the free list. */
/*-------------------------------------------------------------------*/
if (prev) prev->next_free = current->next_free;
else sys_free = current->next_free;

current->packet_size = -current->packet_size; /* POSITIVE==IN USE */
}

_unlock();
return &(current->next_free);
}

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru