OSDN Git Service

(none)
[hos/hos-v4a.git] / aplfw / library / container / valmemheap / valmemheap_alloc.c
1 /** 
2  *  Hyper Operating System  Application Framework
3  *
4  * @file  valmemheap_alloc.c
5  * @brief %jp{可変サイズメモリヒープクラス}%en{variable size memory heap class}
6  *
7  * Copyright (C) 2006-2008 by Project HOS
8  * http://sourceforge.jp/projects/hos/
9  */
10
11
12 #include <stdio.h>
13 #include "valmemheap_local.h"
14
15
16
17 /** %jp{メモリの割り当て} */
18 void *ValMemHeap_Alloc(void *pMemHeap, MEMSIZE Size)
19 {
20         C_VALMEMHEAP            *self;
21         T_VALMEMHEAP_MEMBLK     *mblk;
22         T_VALMEMHEAP_MEMBLK     *mblk_next;
23         T_VALMEMHEAP_MEMBLK     *mblk_next2;
24         MEMSIZE                         MemBlockSize;
25         
26         
27         /* upper cast */
28         self = (C_VALMEMHEAP *)pMemHeap;
29         
30         /* %jp{ヒープの存在チェック} */
31         if ( self->pMemBase == NULL )
32         {
33                 return NULL;
34         }
35         
36         /* %jp{サイズのアライメントを調整} */
37         Size = ValMemHeap_AlignSize(self, Size);
38         
39         /* %jp{メモリブロックのサイズを調整} */
40         MemBlockSize = ValMemHeap_GetMemBlockSize(self);
41         
42         /* %jp{空き領域を検索} */
43         mblk = self->pMemBase;
44         while ( mblk->Size != 0 )
45         {
46                 if ( mblk->iFlag == VALMEMHEAP_FREE && mblk->Size >= Size )
47                 {
48                         /* 十分な容量があったら */
49                         if ( mblk->Size - Size > MemBlockSize + (self->AlignMask + 1) )
50                         {
51                                 /* ブロックを分割する */
52                                 mblk_next  = (T_VALMEMHEAP_MEMBLK *)((char *)mblk + MemBlockSize + Size);
53                                 mblk_next2 = (T_VALMEMHEAP_MEMBLK *)((char *)mblk + MemBlockSize + mblk->Size);
54                                 mblk_next->pPrev  = mblk;
55                                 mblk_next->Size   = mblk->Size - Size - MemBlockSize;
56                                 mblk_next->iFlag  = VALMEMHEAP_FREE;
57                                 mblk_next2->pPrev = mblk_next;
58                                 mblk->Size        = Size;
59                         }
60                         mblk->iFlag = VALMEMHEAP_USING;
61                         
62                         return (void *)((char *)mblk + MemBlockSize);
63                 }
64                 
65                 /* 次のブロックへ進む */
66                 mblk = (T_VALMEMHEAP_MEMBLK *)((char *)mblk + mblk->Size + MemBlockSize);
67         }
68
69         return NULL;    /* 空きが無い */
70 }
71
72 /* end of file */