Skip to content
Snippets Groups Projects
Select Git revision
  • fd8b6bcf5572b342b1e61f4f3737a2a650659166
  • main default protected
  • phhw
  • captouch-threshold
  • t
  • dos
  • test2
  • test
  • slewtest
  • simtest
  • view-think
  • vm-pending
  • media-buf
  • scope
  • passthrough
  • wave
  • vsync
  • dos-main-patch-50543
  • json-error
  • rahix/big-flow3r
  • pippin/media_framework
  • v1.3.0
  • v1.2.0
  • v1.2.0+rc1
  • v1.1.1
  • v1.1.0
  • v1.1.0+rc1
  • v1.0.0
  • v1.0.0+rc6
  • v1.0.0+rc5
  • v1.0.0+rc4
  • v1.0.0+rc3
  • v1.0.0+rc2
  • v1.0.0+rc1
34 results

gc.c

Blame
  • Forked from flow3r / flow3r firmware
    Source project has a limited visibility.
    gc.c 11.89 KiB
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    
    #include "mpyconfig.h"
    #include "gc.h"
    
    // a machine word is big enough to hold a pointer
    /*
    #define BYTES_PER_WORD (8)
    typedef unsigned long machine_uint_t;
    */
    typedef unsigned char byte;
    
    #define BITS_PER_BYTE (8)
    #define BITS_PER_WORD (BITS_PER_BYTE * BYTES_PER_WORD)
    #define WORDS_PER_BLOCK (4)
    #define BYTES_PER_BLOCK (WORDS_PER_BLOCK * BYTES_PER_WORD)
    #define STACK_SIZE (64) // tunable; minimum is 1
    
    static byte *gc_alloc_table_start;
    static byte *gc_alloc_table_end;
    static machine_uint_t gc_alloc_table_byte_len;
    static machine_uint_t *gc_pool_start;
    static machine_uint_t *gc_pool_end;
    
    static int gc_stack_overflow;
    static machine_uint_t gc_stack[STACK_SIZE];
    static machine_uint_t *gc_sp;
    
    // TODO waste less memory; currently requires that all entries in alloc_table have a corresponding block in pool
    void gc_init(void *start, void *end) {
        // align end pointer on block boundary
        end = (void*)((machine_uint_t)end & (~(BYTES_PER_BLOCK - 1)));
    
        // calculate parameters for GC
        machine_uint_t total_word_len = (machine_uint_t*)end - (machine_uint_t*)start;
        gc_alloc_table_byte_len = total_word_len * BYTES_PER_WORD / (1 + BITS_PER_BYTE / 2 * BYTES_PER_BLOCK);
        gc_alloc_table_start = (byte*)start;
        gc_alloc_table_end = gc_alloc_table_start + gc_alloc_table_byte_len;
        machine_uint_t gc_pool_block_len = gc_alloc_table_byte_len * BITS_PER_BYTE / 2;
        machine_uint_t gc_pool_word_len = gc_pool_block_len * WORDS_PER_BLOCK;
        gc_pool_start = (machine_uint_t*)end - gc_pool_word_len;
        gc_pool_end = end;
    
        // clear ATBs
        memset(gc_alloc_table_start, 0, gc_alloc_table_byte_len);
    
        /*
        printf("GC layout:\n");
        printf("  alloc table at %p, length %u bytes\n", gc_alloc_table_start, gc_alloc_table_byte_len);
        printf("  pool at %p, length %u blocks = %u words = %u bytes\n", gc_pool_start, gc_pool_block_len, gc_pool_word_len, gc_pool_word_len * BYTES_PER_WORD);
        */
    }
    
    // ATB = allocation table byte
    // 0b00 = FREE -- free block
    // 0b01 = HEAD -- head of a chain of blocks
    // 0b10 = TAIL -- in the tail of a chain of blocks
    // 0b11 = MARK -- marked head block
    
    #define AT_FREE (0)
    #define AT_HEAD (1)
    #define AT_TAIL (2)
    #define AT_MARK (3)
    
    #define BLOCKS_PER_ATB (4)
    #define ATB_MASK_0 (0x03)
    #define ATB_MASK_1 (0x0c)