Exemplo n.º 1
0
/**
 * Allocate memory block
 *
 * Allocates a block of size bytes of memory, returning a pointer to the
 * beginning of the block.  The content of the newly allocated block of
 * memory is not initialized, remaining with indeterminate values.
 *
 * @param size
 *    Size of the memory block, in bytes.
 *
 * @return
 *    On success, a pointer to the memory block allocated by the function.
 *
 *    The type of this pointer is always void*, which can be cast to the
 *    desired type of data pointer in order to be dereferenceable.
 *
 *    If the function failed to allocate the requested block of memory,
 *    a null pointer is returned.
 *
 * @see http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/
 */
void *malloc(size_t size)
{
	if(size<=0) return NULL;

	if(free_list_ptr == NULL)
		free_list_ptr = free_list_init();

	L( actual_size += size);


	size_t size_plus_dic = find_new_alloc_size(size);
	
	void *block_ptr = block_available(size_plus_dic);

	if (block_ptr == NULL)
	{
		/* Allocate new space from sbrk() */
		block_ptr = allocate_new_space(size_plus_dic);
		
		D(printf("malloc(): find new space at loc %zu with length %zu, occupy:%d\n",
				(size_t)(block_ptr - heap_ptr),MDIC(block_ptr)->size,
				MDIC(block_ptr)->occupy ));

		// store the size_plus_dic into the block
		MDIC(block_ptr) -> occupy = true;
		free_list_delete(block_ptr , size2order( MDIC(block_ptr)->size )); // delete from free list.

		L( printf("size actual_size total_size: %zu %zu %zu\n",size,actual_size,total_size) );

		return block_ptr + sizeof(mem_dic);
	}
	else
	{
		if (MDIC(block_ptr)->size > size_plus_dic)
			block_ptr = split_block(block_ptr,size_plus_dic);

		if ( !block_ptr || MDIC(block_ptr)->size != size_plus_dic){
			D( printf("Error in malloc(): size after split cannot match\n") );
			return NULL;
		}
		/* Assign the size to the block, split the block if necessary */
		D( printf("malloc(): find old space at loc %zu with length %zu, occupy:%d\n",
			(size_t)(block_ptr - heap_ptr),MDIC(block_ptr)->size,
			MDIC(block_ptr)->occupy ) );

		MDIC(block_ptr) -> occupy = true;
		free_list_delete(block_ptr,size2order( MDIC(block_ptr)->size ));

		L( printf("size actual_size total_size: %zu %zu %zu\n",size,actual_size,total_size) );

		return block_ptr + sizeof(mem_dic);

	}
	return NULL;
}
Exemplo n.º 2
0
/*
 * bcm_mpm_init() - initialize the whole memory pool system.
 *
 * Parameters:
 *    osh:       INPUT  Operating system handle. Needed for heap memory allocation.
 *    max_pools: INPUT Maximum number of mempools supported.
 *    mgr:       OUTPUT The handle is written with the new pools manager object/handle.
 *
 * Returns:
 *    BCME_OK     Object initialized successfully. May be used.
 *    BCME_NOMEM  Initialization failed due to no memory. Object must not be used.
 */
int BCMATTACHFN(bcm_mpm_init)(osl_t *osh, int max_pools, bcm_mpm_mgr_h *mgrp)
{
	bcm_mpm_mgr_h      mgr = NULL;
	bcm_mp_pool_t      *pool_objs;

	/* Check parameters */
	if ((mgrp == NULL) || (osh == NULL) || (max_pools <= 0)) {
		return (BCME_BADARG);
	}

	/* Allocate memory pool manager object. */
	mgr = (bcm_mpm_mgr_h) MALLOC(osh, (sizeof(*mgr)));
	if (mgr == NULL) {
		return (BCME_NOMEM);
	}

	/* Init memory pool manager object. */
	memset(mgr, 0, sizeof(*mgr));
	mgr->osh = osh;
	mgr->max_pools = (uint16) max_pools;


	/* Pre-allocate pool meta-data (array of bcm_mp_pool structs). */
	pool_objs = (bcm_mp_pool_t *) MALLOC(osh, max_pools * sizeof(bcm_mp_pool_t));
	if (pool_objs == NULL) {
		MFREE(osh, mgr, sizeof(*mgr));
		return (BCME_NOMEM);
	}
	memset(pool_objs, 0, max_pools * sizeof(bcm_mp_pool_t));
	mgr->pool_objs = pool_objs;


	/* Chain all the memory pools onto the manager's free list. */
	STATIC_ASSERT(sizeof(bcm_mp_pool_t) > sizeof(bcm_mp_free_list_t));
	free_list_init(&mgr->free_pools, pool_objs, sizeof(bcm_mp_pool_t), max_pools);

	*mgrp = mgr;
	return (BCME_OK);
}
Exemplo n.º 3
0
/*
 * create_pool() - Create a new pool for fixed size objects. Helper function
 *                         common to all memory pool types.
 *
 * Parameters:
 *    mgr:           INPUT  The handle to the pool manager
 *    obj_sz:        INPUT  Size of objects that will be allocated by the new pool.
 *                          This is the size requested by the user. The actual size
 *                          of the memory object may be padded.
 *                          Must be > 0 for heap pools. Must be >= sizeof(void *) for
 *                          Prealloc pools.
 *    padded_obj_sz: INPUT  Size of objects that will be allocated by the new pool.
 *                          This is the actual size of memory objects. It is 'obj_sz'
 *                          plus optional padding required for alignment.
 *                          Must be > 0 for heap pools. Must be >= sizeof(void *) for
 *                          Prealloc pools.
 *    nobj:          INPUT  Maximum number of concurrently existing objects to support.
 *                          Must be specified for Prealloc pool. Ignored for heap pools.
 *    memstart       INPUT  Pointer to the memory to use, or NULL to malloc().
 *                          Ignored for heap pools.
 *    memsize        INPUT  Number of bytes referenced from memstart (for error checking).
 *                          Must be 0 if 'memstart' is NULL. Ignored for heap pools.
 *    poolname       INPUT  For instrumentation, the name of the pool
 *    type           INPUT  Pool type - BCM_MP_TYPE_xxx.
 *    newp:          OUTPUT The handle for the new pool, if creation is successful
 *
 * Returns:
 *    BCME_OK   Pool created ok.
 *    other     Pool not created due to indicated error. newpoolp set to NULL.
 *
 *
 */
static int BCMATTACHFN(create_pool)(bcm_mpm_mgr_h mgr,
                                    unsigned int obj_sz,
                                    unsigned int padded_obj_sz,
                                    int nobj,
                                    void *memstart,
                                    char poolname[BCM_MP_NAMELEN],
                                    uint16 type,
                                    bcm_mp_pool_h *newp)
{
	bcm_mp_pool_t      *mem_pool = NULL;
	void               *malloc_memstart = NULL;

	/* Check parameters */
	if ((mgr == NULL) ||
	    (newp == NULL) ||
	    (obj_sz == 0) ||
	    (padded_obj_sz == 0) ||
	    (poolname == NULL) ||
	    (poolname[0] == '\0')) {
		return (BCME_BADARG);
	}

	/* Allocate memory object from pool. */
	mem_pool = (bcm_mp_pool_t *) free_list_remove(&mgr->free_pools);
	if (mem_pool == NULL) {
		return (BCME_NOMEM);
	}

	/* For pool manager allocated memory, malloc the contiguous memory
	 * block of objects.
	 */
	if ((type == BCM_MP_TYPE_PREALLOC) && (memstart == NULL)) {
		memstart = MALLOC(mgr->osh, padded_obj_sz * nobj);
		if (memstart == NULL) {
			free_list_add(&mgr->free_pools,
			                     (bcm_mp_free_list_t *) mem_pool);
			return (BCME_NOMEM);
		}
		malloc_memstart = memstart;
	}

	/* Init memory pool object (common). */
	memset(mem_pool, 0, sizeof(*mem_pool));
	mem_pool->objsz = obj_sz;
	BCM_MP_SET_POOL_TYPE(mem_pool, type);
	BCM_MP_SET_IN_USE(mem_pool);
	strncpy(mem_pool->name, poolname, sizeof(mem_pool->name));
	mem_pool->name[sizeof(mem_pool->name)-1] = '\0';


	if (type == BCM_MP_TYPE_PREALLOC) {
		/* Init memory pool object (Prealloc specific). */
		mem_pool->u.p.nobj            = (uint16) nobj;
		mem_pool->u.p.malloc_memstart = malloc_memstart;
		mem_pool->u.p.padded_objsz    = padded_obj_sz;

		/* Chain all the memory objects onto the pool's free list. */
		free_list_init(&mem_pool->u.p.free_objp, memstart, padded_obj_sz, nobj);
	}
	else {
		/* Init memory pool object (Heap specific). */
		mem_pool->u.h.osh = mgr->osh;
	}

	mgr->npools++;
	*newp = mem_pool;
	return (BCME_OK);
}
Exemplo n.º 4
0
int main(int argc, char** argv) {
    if(argc != 2 && argc != 3) {
        c_print_format("Usage: %s FILE [cartridge/folder]\n", argv[0]);
        return 0;
    }
    Arena arena = arena_create(MB(512));

    String cartridge_folder_path_name = (argc > 2)
        ? string_from_c_string(argv[2])
        : L("SuperMarioWorld.sfc");
    Path cartridge_folder_path;
    path_init(&cartridge_folder_path, cartridge_folder_path_name);
    Path manifest_path;
    path_init_from_c(&manifest_path, &cartridge_folder_path, "manifest.bml");
    Buffer manifest_buffer = path_read_file(&manifest_path, &arena);

    Wdc65816MapperBuilder rom_builder = { };
    
    char name[256];
    Buffer name_buffer = buffer(name, 256);
    Buffer rom_buffer;
    for(Wdc65816RomLoader loader = wdc65816_rom_loader_begin(&rom_builder,
                                                             string_from_buffer(manifest_buffer));
        wdc65816_rom_loader_end(&loader);
        wdc65816_rom_loader_next(&loader)) {
        Wdc65816MemoryBufferRequest request = wdc65816_rom_loader_get_buffer_request(&loader,
                                                                                     name_buffer);
        Buffer file_buffer = buffer(arena_alloc_array(&arena, request.size, u8), request.size);
        if(string_equal(request.name, L("program.rom")) &&
           request.type == WDC65816_MEMORY_ROM) {
            rom_buffer = file_buffer;
        }
        wdc65816_rom_loader_set_buffer(&loader, file_buffer);
    }

    uint mapper_buffer_size = wdc65816_mapper_get_buffer_size();
    u8* work_buffer = arena_alloc_array(&arena, mapper_buffer_size, u8);
    Wdc65816Mapper rom;
    wdc65816_mapper_init(&rom, &rom_builder, (u8**)work_buffer);

    nuts_global_init();

    Path working_dir;
    path_init_working_directory(&working_dir);
    FreeList sentinel;
    free_list_init(&sentinel);
    ErrorList error_list;
    error_list_init(&error_list, arena_subarena(&arena, MB(10)));


    AST ast;
    ast_init(&ast, &arena);
    String file_name = string_from_c_string(argv[1]); 
    /* struct timespec lex_start,      lex_end,      lex_time = { 0 }; */
    /* struct timespec parse_start,    parse_end,    parse_time = { 0 }; */
    /* struct timespec assemble_start, assemble_end, assemble_time = { 0 }; */
    /* struct timespec all_start,      all_end,      all_time; */
    

    /* clock_gettime(CLOCK_REALTIME, &all_start); */
    Parser parser;
    parser_init(&parser, &arena, &sentinel, &error_list, &ast);
    int error_num = 0;
    while(1) {
        Path file;
        path_init(&file, file_name);
        Buffer file_buffer = path_read_file(&file, &arena);
        TokenList token_list;
        //c_print_format("read %.*s\n", file_name.length, file_name.data);
        Text file_text = {
            .buffer = file_buffer,
            .name   = file_name
        };
        /* clock_gettime(CLOCK_REALTIME, &lex_start); */
        Result result = lex(file_text, &token_list, &arena, &error_list, &ast.identifier_map);
        if(result == RESULT_ERROR) {
            for(;error_num < error_list.length; error_num++) {
                describe_error(error_list.errors[error_num]);
            }
        }
        /* clock_gettime(CLOCK_REALTIME, &lex_end); */
        /* lex_time = timespec_add(lex_time, timespec_sub(lex_start, lex_end)); */
        /* clock_gettime(CLOCK_REALTIME, &parse_start); */
        /* result = parse(&parser, token_list); */
        /* clock_gettime(CLOCK_REALTIME, &parse_end); */
        /* parse_time = timespec_add(parse_time, timespec_sub(parse_start, parse_end)); */

        if(result == RESULT_NEED_TOKEN_STREAM) {
            file_name = parser.needed_token_stream_file_name;
            continue;
        } else if(result == RESULT_OK) {
            break;
        } else if(result == RESULT_ERROR) {
            for(;error_num < error_list.length; error_num++) {
                describe_error(error_list.errors[error_num]);
            }
            return 1;
        } else {
            invalid_code_path;
        }
    }

    /* clock_gettime(CLOCK_REALTIME, &assemble_start); */
    Assembler assembler;
    assembler_init(&assembler, &error_list, &ast, &rom);
    Result result = RESULT_ERROR;
    while(result != RESULT_OK) {
        result = assemble(&assembler);
        if(result == RESULT_NEED_FILE) {
            String file_name = assembler_get_file_name(&assembler);
            Path file;
            path_init(&file, file_name);
            Buffer file_buffer = path_read_file(&file, &arena);
            assembler_give_buffer(&assembler, file_buffer);
        } else if(result == RESULT_ERROR) {
            break;
        }
    }
    /* clock_gettime(CLOCK_REALTIME, &assemble_end); */
    /* assemble_time = timespec_add(assemble_time, timespec_sub(assemble_start, assemble_end)); */

    for(int i = 0; i < error_list.length; i++) {
        describe_error(error_list.errors[i]);
    }

    /* parser_deinit(&parser); */
    /* clock_gettime(CLOCK_REALTIME, &all_end); */
    /* all_time = timespec_sub(all_start, all_end); */
    /* c_print_format("Lex:      %li.%06lims\n",      lex_time.tv_sec * 1000 +      lex_time.tv_nsec / 1000000,      lex_time.tv_nsec % 1000000); */
    /* c_print_format("Parse:    %li.%06lims\n",    parse_time.tv_sec * 1000 +    parse_time.tv_nsec / 1000000,    parse_time.tv_nsec % 1000000); */
    /* c_print_format("Assemble: %li.%06lims\n", assemble_time.tv_sec * 1000 + assemble_time.tv_nsec / 1000000, assemble_time.tv_nsec % 1000000); */
    /* c_print_format("All:      %li.%06lims\n",      all_time.tv_sec * 1000 +      all_time.tv_nsec / 1000000,      all_time.tv_nsec % 1000000); */

    Path rom_path;
    path_create_from(&rom_path, &cartridge_folder_path, L("program.rom"));
    path_write_file(&rom_path, rom_buffer);
    
    return 0;
}