대문 / 공개프로젝트 / mzalloca

mzalloca

  • 개발자
    조재혁 (Mminzkn@minzkn.com)

  • 기록사항
    2007년 11월 23일 : 첫 버젼 공개 (v1.0.0 build 0)

개요

gnuc 에서의 alloca 함수는 builtin macro 에 기반한 치환으로 구현됩니다. 이것은 함수내에서 할당한것은 함수를 벗어나면 자동으로 해제되는 garbage collection 메커니즘에 기반합니다. 개념적으로 이러한 메커니즘을 별도의 함수로 구현하여 라이브러리화 해보았습니다.

저작권

GPL

개발계획

Thread 환경에서는 garbage collection 이 제대로 이루어지지 않을수 있는데 이 부분의 개선이 필요합니다. 즉, 아직까지는 개념적 접근으로만 구현되어 있을뿐이며 실전에 사용가능하도록 하려면 추가적으로 살을 덧붙이는것이 필요합니다.

알려진 문제점 및 검증요소

현재 Thread unsafe 이기 때문에 thread 환경에서의 사용은 적합하지 않습니다.

다운로드

최근 소스 받기 : svn://svn.hwport.com/opensource/mzalloca/trunk ([http]http://source.hwport.com/viewvc/opensource/mzalloca/[])

참고자료 및 사이트 링크

오래전에 어디선가 개념적 접근법에 대한 글을 본적이 있는데 링크가 기억나지 않네요.

사용방법

  • mzalloca 함수 : alloca 와 비슷하지만 실제 할당을 stack 이 아닌 malloc 으로 할당하여 반환해주며 free 할수 없고 함수를 벗어나면 자동으로 해제됨.
  • mzalloca_count : 디버깅을 위해서 할당노드수를 반환해줌.

소스

/* 
 Copyright (C) Information Equipment co.,LTD. 
 All rights reserved. 
 Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> 
*/ 

#if !defined(__def_mzapi_source_mzalloca_c__) 
#define __def_mzapi_source_mzalloca_c__ "mzalloca.c" 

#include "mzalloca.h" 

#if defined(__cplusplus) 
# define def_mzalloca_export extern "C" 
#else 
# define def_mzalloca_export 
#endif 

struct mzalloca_node_ts { struct mzalloca_node_ts *next, **entry; }; 

static int __mzalloca_detect_stack_direction(void); 

def_mzalloca_export size_t mzalloca_count(void); 
def_mzalloca_export void *mzalloca(size_t s_size); 

static volatile size_t __g_mzalloca_count = (size_t)0; 

static int __mzalloca_detect_stack_direction(void) 
{ 
    static unsigned char *sg_address = (unsigned char *)0; 
    auto unsigned char s_stack_byte; 
    
    if(sg_address == ((unsigned char *)0)) { 
        sg_address = (unsigned char *)(&s_stack_byte); 
        return(__mzalloca_detect_stack_direction()); /* recursive call */ 
    } 
    
    return((sg_address < ((unsigned char *)(&s_stack_byte))) ? 1 : (-1)); 
} 

size_t mzalloca_count(void) 
{ 
    return(__g_mzalloca_count); 
} 

void *mzalloca(size_t s_size) 
{ 
    static struct mzalloca_node_ts *sg_node = (struct mzalloca_node_ts *)0; /* linked list node */ 
    static int sg_type = 0; /* stack direction type */ 

    auto struct mzalloca_node_ts *s_temp; 

    if(sg_type == 0) { sg_type = __mzalloca_detect_stack_direction(); } 

    while(sg_node != ((struct mzalloca_node_ts *)0)) { 
        if(((sg_type < 0) && (sg_node->entry < ((struct mzalloca_node_ts **)(&s_temp)))) || 
           ((sg_type > 0) && (sg_node->entry > ((struct mzalloca_node_ts **)(&s_temp))))) { 
            s_temp = sg_node->next; 
            free((void *)sg_node); 
            sg_node = s_temp; 

            __g_mzalloca_count--; 
        } 
        else break; 
    } 

    if(s_size == ((size_t)0)) { 
        /* DESCRIPTION: force garbage collection */ 
        return((void *)0); 
    } 

    do { 
        size_t s_allocate_size; 
        s_allocate_size = ((size_t)sizeof(struct mzalloca_node_ts)) + s_size; 
        if(s_allocate_size < s_size) { 
            /* ASSERT: overflow allocate size */ 
            return((void *)0); 
        } 
        s_temp = (struct mzalloca_node_ts *)malloc(s_allocate_size); 
        if(s_temp == ((struct mzalloca_node_ts *)0)) { 
            /* ASSERT: can not allocate memory */ 
            return((void *)0); 
        } 
    }while(0); 
    
    s_temp->entry = (struct mzalloca_node_ts **)(&s_temp); 
    
    s_temp->next = sg_node; 
    sg_node = s_temp; 

    __g_mzalloca_count++; 
  
    return((void *)(&s_temp[1])); 
} 

#endif 

/* vim: set expandtab: */ 
/* End of source */ 

/*
End of page
(RemoteIP=38.107.179.244:59096)
Copyright © HWPORT.COM
All Rights Reserved.
*/