/* winnie - an experimental window system Copyright (C) 2013 Eleni Maria Stea This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Author: Eleni Maria Stea */ #include #include #include #include #include #include #include #include #include #include #include #include "shalloc.h" #define BLOCK_SIZE 512 #define NUM_BLOCKS (POOL_SIZE / BLOCK_SIZE) #define BITMAP_SIZE (NUM_BLOCKS / 32) static bool is_allocated(int block_number); static int addr_to_block(unsigned char *addr); static unsigned char *block_to_addr(int block_number); static void alloc_blocks(int block_pos, int num_blocks); static void free_blocks(int block_pos, int num_blocks); static void print_stats(); static int fd; static unsigned char *pool; static std::map alloc_sizes; //starting block -> number of blocks // 0 means not allocated 1 means allocated static uint32_t bitmap[BITMAP_SIZE]; struct Statistics { int alloc_num; int free_num; int alloc_memsize; int free_memsize; }; static Statistics stats; bool init_shared_memory() { if(((fd = shm_open(SHMNAME, O_RDWR | O_CREAT, S_IRWXU)) == -1)) { fprintf(stderr, "Failed to open shared memory: %s\n", strerror(errno)); return false; } ftruncate(fd, POOL_SIZE); if((pool = (unsigned char*)mmap(0, POOL_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == (void*)-1) { fprintf(stderr, "Failed to map shared memory: %s\n", strerror(errno)); } for(int i=0; i::iterator it; if((it = alloc_sizes.find(block)) != alloc_sizes.end()) { int num_blocks = it->second; free_blocks(block, num_blocks); alloc_sizes.erase(it); } else { fprintf(stderr, "Attempt to free non-existent blocks from: %d\n", block); } } void *get_pool() { return (void*)pool; } static bool is_allocated(int block_number) { int idx = block_number / 32; int bit_num = block_number % 32; if((bitmap[idx] >> bit_num) & 1) { return true; } return false; } static int addr_to_block(unsigned char *addr) { assert(addr >= pool); assert(addr < pool + POOL_SIZE); return (addr - pool) / BLOCK_SIZE; } static unsigned char *block_to_addr(int block_number) { assert(block_number >= 0); assert(block_number < NUM_BLOCKS); return pool + block_number * BLOCK_SIZE; } static void alloc_blocks(int block_pos, int num_blocks) { for(int i=0; i