Пример #1
0
    void HeapManager::printStatus() {

        int free_blocks = 0, used_blocks = 0;
        int free_memory = 0, used_memory = 0;

        unsigned char block_size;
        char type, color;
        bool free;
        int p = 0;
        while(p < HEAP_SIZE - HEAP_HEAD_SIZE) {
            read_block_size(heap+p, block_size);
            read_block_flags(heap+p, type, color, free);

            if (block_size == 0) { // reached free space at the and of the heap
                printf("Free: %.3f kB (%i blocks), used: %.3f kB (%i blocks)\n",
                       free_memory/1024., free_blocks,
                       used_memory/1024., used_blocks);
                double left = (HEAP_SIZE - p)/1024.;
                printf("%.3f kB (%.3f MB) left\n\n", left, left/1024.);
                break;
            }

            if (free) {
                free_blocks++;
                free_memory += block_size;
            } else {
                used_blocks++;
                used_memory += block_size;
            }

            p += HEAP_HEAD_SIZE + block_size;
        }
    }
Пример #2
0
    char* HeapManager::getAddress(unsigned char alloc_size, unsigned char& block_size) {
        char type,color;
        bool free;

        int p = (int)(next_free_block - heap);
        while (p < HEAP_SIZE - HEAP_HEAD_SIZE - alloc_size) {
            read_block_size(heap+p, block_size);
            read_block_flags(heap+p, type, color, free);

            if (free && (block_size == 0 || alloc_size <= block_size)) { return heap+p; }
            p += FULL_BLOCK_SIZE(block_size);
        }
        return NULL;
    }
Пример #3
0
int main(int argc, char *argv[])
{
    int fd_in, fd_out;
    unsigned long n;

    if (argc != 4) {
        fprintf(stderr, "Usage: %s <file input> <file output> <block size>\n",
                argv[0]);
        exit(EXIT_FAILURE);
    }
    open_files(argv[1], argv[2], &fd_in, &fd_out);
    n = read_block_size(argv[3]);
    copy_invert(fd_in, fd_out, n);
    exit(EXIT_SUCCESS);
}
Пример #4
0
    void HeapManager::print() {

        unsigned char block_size;
        char type;
        char color;
        bool free;
        int p = 0;

        printf("Skipping protected\n");
        while(p < HEAP_SIZE - HEAP_HEAD_SIZE) {
            read_block_size(heap+p, block_size);
            read_block_flags(heap+p, type, color, free);

            if (color != GC_PROTECTED) {
                if (block_size == 0) { // reached free space at the and of the heap
                    double left = (HEAP_SIZE - p)/1024.;
                    printf("%.3f kB (%.3f MB) left\n\n", left, left/1024.);
                    break;
                }

                switch(color) {
                    case GC_WHITE: printf("W"); break;
                    case GC_BLACK: printf("B"); break;
                    case GC_GRAY:  printf("G"); break;
                    case GC_PROTECTED:  printf("*"); break;
                    default: break;
                }

                printf(" Block [%i] @%i: %iB", free, p, block_size);
                if (!free) {
                    switch(type) {
                        case GC_TABLE:   printf(", table"); break;
                        case GC_UPVAL:   printf(", upval"); break;
                        case GC_CLOSURE: printf(", closure"); break;
                        case GC_STRING:  printf(", string"); break;
                        case GC_NATIVE:  printf(", native"); break;
                        case GC_FILE:    printf(", file"); break;
                        default: printf("unknown"); break;
                    }
                }
                printf("\n");
            }

            p += HEAP_HEAD_SIZE + block_size;
        }
    }
Пример #5
0
    void HeapManager::purgeHeap(bool force) {

        unsigned char block_size;
        char type, color;
        bool free;

        next_free_block = NULL;
        char* prev_block = NULL;
        unsigned char prev_size = 0;

        int p = 0;
        while (p < HEAP_SIZE - HEAP_HEAD_SIZE - HEAP_MIN_BLOCK_SIZE) {
            char* block = heap+p;

            read_block_size(block, block_size);

            if (block_size == 0) { // reached the end of used space
                if (next_free_block == NULL) { next_free_block = block; }
                if (prev_block != NULL) { write_block_size(prev_block, 0); }
                break;
            }

            read_block_flags(block, type, color, free);

            // free white blocks
            if (!free && (color == GC_WHITE || force)) {

#if DEBUG_HEAP_ALLOC
                printf("DEALLOC %i\n", (int)(block - heap));
#endif

                switch(type) {
                    case GC_TABLE:   ((Table*)       (block + HEAP_HEAD_SIZE))->~Table();        break;
                    case GC_UPVAL:   ((UpvalueRef*)  (block + HEAP_HEAD_SIZE))->~UpvalueRef();   break;
                    case GC_CLOSURE: ((Closure*)     (block + HEAP_HEAD_SIZE))->~Closure();      break;
                    case GC_STRING:  ((StringObject*)(block + HEAP_HEAD_SIZE))->~StringObject(); break;
                    case GC_NATIVE:  ((Native*)      (block + HEAP_HEAD_SIZE))->~Native();       break;
                    case GC_FILE:    ((File*)        (block + HEAP_HEAD_SIZE))->~File();         break;
                    default: break;
                }
                free = true;
            }

            if (!free) {
                write_block_flags(block, type, (char)(color == GC_PROTECTED ? GC_PROTECTED : GC_WHITE), free);
                prev_block = NULL;
            } else {
                if (next_free_block == NULL) { next_free_block = block; }

                // if possible, merge with previous free block
                if (prev_block != NULL && prev_size + block_size + HEAP_HEAD_SIZE <= HEAP_MAX_BLOCK_SIZE) {
                    write_block_size(prev_block, (unsigned char)(prev_size + block_size + HEAP_HEAD_SIZE));
                    prev_size = (unsigned char)(prev_size + block_size + HEAP_HEAD_SIZE);
                // otherwise just mark block as free
                } else {
                    write_block_flags(block, type, GC_WHITE, free);
                    prev_block = block;
                    prev_size = block_size;
                }
            }

            p += FULL_BLOCK_SIZE(block_size);
        }
    }