X-Git-Url: http://git.mutantstargoat.com?a=blobdiff_plain;f=src%2Fshalloc.cc;h=3f47995dc736dbb25074017e66f2187dfb093b06;hb=e2626c41c841dbbfb64ddf6341b4e23089036299;hp=d8f97dc508bbeb29d77d6441da65d21e838500ae;hpb=12274901ac01898b01b93e15b5b87dec3348afae;p=winnie diff --git a/src/shalloc.cc b/src/shalloc.cc index d8f97dc..3f47995 100644 --- a/src/shalloc.cc +++ b/src/shalloc.cc @@ -1,29 +1,212 @@ -#include +/* +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 SHMNAME "/winnie.shm" + #define POOL_SIZE 16777216 -#define BLOCK_SIZE 1024 +#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; -//address size +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(!(pool = (unsigned char *)malloc(POOL_SIZE))) { + 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)); + } + + shm_unlink(SHMNAME); + + 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); + } +} + +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