メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcMemoryPool.c

説明を見る。
00001 #include "dkcMemoryPool.h"
00002 
00004 static DKC_SAME_OBJECT_POOL_NODE *alloc_sop_node(size_t object_size){
00005     DKC_SAME_OBJECT_POOL_NODE *a;
00006     a = (DKC_SAME_OBJECT_POOL_NODE *)dkcAllocateFast(sizeof(DKC_SAME_OBJECT_POOL_NODE));
00007     if(NULL==a){
00008         return NULL;
00009     }
00010     a->pool = dkcAllocateFast(object_size);
00011     if(NULL==a->pool){
00012         goto Error;
00013     }
00014     a->next = NULL;
00015     return a;
00016 Error:
00017     dkcFree(&a);
00018     return NULL;
00019 }
00020 
00022 static void free_sop_node(DKC_SAME_OBJECT_POOL_NODE *p){
00023     //内部でifチェック済み
00024     dkcFree(&(p->pool));
00025     dkcFree(&p);
00026 }
00027 
00029 static DKC_SAME_OBJECT_POOL *alloc_sameobjectpool(size_t recycle_size){
00030     DKC_SAME_OBJECT_POOL *p = dkcAllocate(sizeof(DKC_SAME_OBJECT_POOL));
00031     if(NULL==p){
00032         return NULL;
00033     }
00034 
00035     p->recycle_pool = (DKC_SAME_OBJECT_POOL_NODE **)
00036         dkcAllocate(sizeof(DKC_SAME_OBJECT_POOL_NODE *) * recycle_size);
00037 
00038     if(NULL==p->recycle_pool){
00039         goto InitError;
00040     }
00041     //dkcmNOT_ASSERT(sizeof(p->flag) != sizeof(BYTE));
00042     p->flag = (BYTE *)dkcAllocateFill(sizeof(BYTE) * recycle_size,FALSE);
00043     if(NULL==p->flag){
00044         goto InitError;
00045     }
00046 
00047     return p;
00048 InitError:
00049     dkcFree((void **)&(p->recycle_pool));
00050     dkcFree(&p);
00051     return NULL;
00052 }
00053 
00055 static int free_sameobjectpool(DKC_SAME_OBJECT_POOL *p){
00056     dkcFree(&(p->flag));
00057     dkcFree((void **)&(p->recycle_pool));
00058     return dkcFree(&p);
00059 }
00060 
00061 DKC_SAME_OBJECT_POOL *WINAPI dkcAllocSameObjectPool(size_t object_size,size_t max_num,
00062                                                                                                         size_t recycle_size)
00063 {
00064     DKC_SAME_OBJECT_POOL *p; 
00065     DKC_SAME_OBJECT_POOL_NODE *t,*a;
00066     size_t i;
00067 
00068     if(0==recycle_size){
00069         recycle_size = max_num / 4;
00070         if(0==recycle_size){
00071             recycle_size = 1;
00072         }
00073     }
00074     p  = alloc_sameobjectpool(recycle_size);
00075 
00076     if(NULL==p){
00077         return NULL;
00078     }
00079 
00080     //set
00081     p->obj_size = object_size;
00082     p->root = NULL;
00083     //p->tail = NULL;
00084     p->max_num = max_num;
00085 
00086     p->recycle_size = recycle_size;
00087 
00088 
00089     t = alloc_sop_node(object_size);
00090     if(NULL==t){
00091         goto Error;
00092     }
00093     //p->root = p->tail = t;
00094     p->root = t;
00095 
00096     a = t;
00097     for(i = 0;i<max_num;i++){
00098         t = alloc_sop_node(object_size);
00099         if(NULL==t){
00100             goto Error;
00101         }
00102         //前確保したNodeの次はt;
00103         a->next = t;
00104         
00105         a = t;
00106     }
00107     //update state
00108     //p->tail = a;
00109     p->now_num = max_num;
00110     return p;
00111 Error:
00112     dkcFreeSameObjectPool(&p);
00113     return NULL;    
00114 
00115 }
00116 
00117 
00118 DKC_SAME_OBJECT_POOL *WINAPI dkcAllocSameObjectPoolDynamic(size_t object_size){
00119     return dkcAllocSameObjectPool(object_size,1024,256);
00120 }
00121 
00122 
00123 
00124 static int free_sop_recycle(DKC_SAME_OBJECT_POOL *p){
00125     DKC_SAME_OBJECT_POOL_NODE **np = p->recycle_pool;
00126     BYTE *flag = p->flag;
00127     size_t i;
00128     for(i = 0;i < p->recycle_size;i++)
00129     {
00130         if(TRUE==flag[i]){
00131             //内部でifチェック
00132             dkcFree(&(np[i]->pool));
00133             dkcFree(&(np[i]));
00134         }
00135     }
00136     return edk_SUCCEEDED;
00137 }
00138 
00139 
00140 int WINAPI dkcFreeSameObjectPool(DKC_SAME_OBJECT_POOL **pp){
00141     DKC_SAME_OBJECT_POOL *p = (*pp);
00142     DKC_SAME_OBJECT_POOL_NODE *n,*t;
00143     if(NULL==pp || NULL==p){
00144         return edk_FAILED;
00145     }
00146     //ノードを開放
00147     n = p->root;
00148 
00149     while(NULL != n){
00150         t = n->next;
00151         free_sop_node(n);
00152         n = t;
00153     }
00154     //最後もお忘れなく・・・
00155     //free_sop_node(    p->tail );
00156 
00157     //リサイクル領域を開放
00158     free_sop_recycle(p);
00159 
00160     //最終領域を開放
00161     return free_sameobjectpool(p);
00162 }
00163 
00165 static BOOL insert_sop_recycle(DKC_SAME_OBJECT_POOL *p,DKC_SAME_OBJECT_POOL_NODE *node){
00166     size_t i,nel = p->recycle_size;
00167     BYTE *flag = p->flag;
00168     for(i= 0;i<nel;i++){
00169         if(FALSE==flag[i]){
00170             p->recycle_pool[i] = node;
00171             flag[i] = TRUE;
00172             return TRUE;
00173         }
00174     }
00175     return FALSE;
00176 }
00177 
00179 static BOOL insert_sop_recycle_memory(DKC_SAME_OBJECT_POOL *p,void *mem){
00180     size_t i,nel = p->recycle_size;
00181     BYTE *flag = p->flag;
00182     for(i= 0;i<nel;i++){
00183         if(TRUE==flag[i]){
00184             if(p->recycle_pool[i]->pool){
00185                 break;
00186             }
00187             p->recycle_pool[i]->pool = mem;
00188             return TRUE;
00189         }
00190     }
00191     return FALSE;
00192 }
00193 
00194 
00195 static BOOL empty_sop_recycle(DKC_SAME_OBJECT_POOL *p){
00196     size_t i,nel = p->recycle_size;
00197     BYTE *flag = p->flag;
00198     for(i= 0;i<nel;i++){
00199         if(TRUE==flag[i])
00200         {//存在していた。
00201             return FALSE;
00202         }
00203     }
00204     //空だった。
00205     return TRUE;
00206 }
00207 
00208 
00209 
00211 void *dkcSameObjectPoolAlloc(DKC_SAME_OBJECT_POOL *p){
00212     DKC_SAME_OBJECT_POOL_NODE *n = p->root;
00213     void *r = n->pool;
00214     //dkcmNOT_ASSERT(0==p->now_num && n == p->tail);
00215     if(0==p->now_num){
00216         if(FALSE==dkcSameObjectPoolReserve(p)){
00217             return NULL;
00218         }
00219         return dkcSameObjectPoolAlloc(p);
00220     }
00221 
00222     //rootの更新
00223     p->root = n->next;
00224 
00225     //使用済みなのでNULL
00226     n->pool = NULL;
00227     n->next = NULL;
00228 
00229     //未使用領域に入れる。
00230     if(FALSE==insert_sop_recycle(p,n)){
00231         //n->pool自体はNULLにしているのでpoolまで開放されない
00232         free_sop_node(n);
00233     }
00234     //マイナス
00235     p->now_num--;
00236 
00237     
00238 #if 0
00239     if(0==p->now_num /*&& p->root == NULL*/)
00240     {
00241         dkcmNOT_ASSERT(p->root != NULL);
00242         p->tail = NULL;
00243 
00244     }
00245 #endif
00246 
00247     return r;
00248 }
00249 
00250 
00251 
00252 DKC_EXTERN void WINAPI dkcSameObjectPoolRecycle(DKC_SAME_OBJECT_POOL *p,void *pv){
00253     if(FALSE==insert_sop_recycle_memory(p,pv))
00254     {//失敗したら廃棄処分
00255         dkcSameObjectPoolFree(pv);
00256     }
00257 }
00258 
00260 static BOOL add_sop_pool(DKC_SAME_OBJECT_POOL *p,DKC_SAME_OBJECT_POOL_NODE *node){
00261 
00262     DKC_SAME_OBJECT_POOL_NODE *t;
00263     dkcmNOT_ASSERT(NULL==node->pool);
00264     
00265     //後ろに繋げる場合は多分これでいいと思うのだが・・・
00266     
00267     /*if(ptr->mNext)
00268     {//次へのポインタがあった場合
00269         t = ptr->mNext;//保存。
00270         ptr->mNext = nextp;//ぶち込む。
00271         nextp->mNext = t;//保存していたのをぶち込む
00272 
00273     }else
00274     {//次へのポインタがなかった場合。
00275         ptr->mNext = nextp;//すぐぶち込む。
00276     }*/
00277     /*if(0==p->now_num){
00278         p->root = node;
00279         p->tail = node;
00280         node->next = NULL;
00281     }else{
00282         t = p->tail;
00283         dkcmNOT_ASSERT(p->tail->next != NULL);
00284         p->tail->next = node;
00285         node->next = NULL;
00286         t = node;
00287     }*/
00288 
00289     //ここらへん状態遷移が激しい。
00290     t = p->root;
00291     p->root = node;
00292     node->next = t;
00293     
00294     
00295 
00296     //数をインクリメント
00297     if(UINT_MAX==p->now_num){
00298         return FALSE;
00299     }
00300     p->now_num++;
00301     return TRUE;
00302 }
00303 
00304 BOOL WINAPI dkcSameObjectPoolReserve(DKC_SAME_OBJECT_POOL *p){
00305     size_t i,nel = p->recycle_size;
00306 
00307     DKC_SAME_OBJECT_POOL_NODE *rp = *(p->recycle_pool);
00308     BYTE *flag = p->flag;
00309     BOOL r = FALSE;
00310 
00311     for(i=0;i<nel;i++){
00312         if(TRUE==flag[i])
00313         {//リサイクル領域にリサイクルすべき領域を発見
00314             if(NULL==rp->pool)
00315             {//リサイクルすべき領域のプールには何も入っていなかった。
00316                 //なので確保。
00317                 rp->pool = dkcAllocateFast(p->obj_size);
00318             }
00319             if(FALSE==add_sop_pool(p,rp))
00320             {//もう入らないらしい。
00321 
00322                 //ここではfreeしなくてOK。
00323                 return FALSE;
00324             }
00325 
00326             //update
00327             r = TRUE;
00328             flag[i] = FALSE;
00329         }
00330     }
00331 
00332     if(p->max_num > p->now_num)
00333     {//足りない・・・
00334         for(;;){
00335             //rpの再利用
00336             rp = alloc_sop_node(p->obj_size);
00337             if(NULL==rp)
00338             {//メモリが確保できない・・・アホPCめ!!!
00339                 return FALSE;
00340             }
00341 
00342             if(FALSE==add_sop_pool(p,rp))
00343             {//もう入らないらしい。(多分無いけど・・・)
00344 
00345                 //ここでこの関数を忘れてはいけない。
00346                 free_sop_node(rp);
00347                 return FALSE;
00348             }
00349             
00350             
00351             if(p->max_num <= p->now_num){
00352                 break;
00353             }
00354         }//end of for
00355         r = TRUE;
00356 
00357     }
00358     return r;
00359 }
00360 
00361 #if 0
00362 
00363 DKC_MEMORY_POOL *WINAPI dkcAllocMemoryPool(size_t poolsize,UINT flag){
00364     DKC_MEMORY_POOL *p = dkcAllocate(sizeof(DKC_MEMORY_POOL));
00365     void *a = NULL;
00366 
00367     if(NULL==p){
00368         return NULL;
00369     }
00370     a = dkcAllocate(size);
00371     if(NULL==a){
00372         goto Error;
00373     }
00374     
00375     p->mpool = a;
00376 
00377 
00378 
00379     p->mAobo = dkcAllocArrayOneByOneDynamic(sizeof(void *),256);
00380     if(NULL==p->mAobo){
00381         goto Error;
00382     }
00383     return p;
00384 
00385 Error:
00386     dkcFree(&a);
00387     dkcFree(&p);
00388 
00389     return NULL;
00390 
00391 }
00392 
00393 int WINAPI dkcFreeMemoryPool(DKC_MEMORY_POOL **p){
00394     if(NULL==p)
00395         return edk_FAILED;
00396 
00397     dkcFreeArrayOneByOne(&((*p)->mAobo));
00398     dkcFree(&((*p)->mpool));
00399     return dkcFree(p);
00400 }
00401 
00402 
00403 void *WINAPI dkcMemoryPoolAlloc(size_t size){
00404     
00405 
00406 
00407 }
00408 
00409 int WINAPI dkcMemoryPoolFree(void *p){
00410 
00411 }
00412 
00413 int WINAPI dkcMemoryPoolSafeFree(void **pp){
00414 
00415 }
00416 
00417 #endif

dkutil_cに対してTue Dec 7 01:09:56 2004に生成されました。 doxygen 1.3.6