| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- /*
- 3APA3A simpliest proxy server
- (c) 2002-2016 by Vladimir Dubrovin <3proxy@3proxy.ru>
- please read License Agreement
- */
- #include "proxy.h"
- #ifndef WITH_STD_MALLOC
- #include "proxy.h"
- #define MEM64K 65536
- #define MEM16K 16384
- #define MEM4K 4096
- #define MEM1K 1024
- #define MEM256 256
- #define DEBUGLEVEL 1
- struct mempage{
- struct mempage *next;
- unsigned usable;
- unsigned char bitmap[32];
- unsigned char data[MEM64K];
- } * pages[] = {NULL, NULL, NULL, NULL, NULL, NULL};
- unsigned memsizes[] = {MEM64K, MEM16K, MEM4K, MEM1K, MEM256, 0};
- enum pagesizes {
- p64k,
- p16k,
- p4k,
- p1k,
- p256,
- nomem,
- };
- pthread_mutex_t mem_mutex;
- int mem_init = 0;
- #ifdef _WIN32
- HANDLE myheap;
- #define malloc(x) HeapAlloc(myheap, 0, x)
- #define free(x) HeapFree(myheap, 0, x)
- #endif
- void init_mem(void) {
- mem_init++;
- pthread_mutex_init(&mem_mutex, NULL);
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Memory initialized\n");
- fflush(stderr);
- #endif
- #ifdef _WIN32
- myheap = HeapCreate(0, MEM64K*16, 0);
- #endif
- }
- void * myalloc64k(){
- struct mempage *newpage;
- if(!mem_init)init_mem();
- if(!(newpage = (struct mempage *)malloc(sizeof(struct mempage)))){
- #if DEBUGLEVEL > 0
- fprintf(stderr, "Failed to allocate p64k\n");
- fflush(stderr);
- #endif
- return NULL;
- }
- memset(newpage->bitmap, 0, 32);
- newpage->usable = 0;
- pthread_mutex_lock(&mem_mutex);
- newpage->next = pages[p64k];
- pages[p64k] = newpage;
- pthread_mutex_unlock(&mem_mutex);
- #if DEBUGLEVEL > 2
- fprintf(stderr, "New p64k created, address %X region: %X\n", newpage, newpage->data);
- fflush(stderr);
- #endif
- #if DEBUGLEVEL == 2
- fprintf(stderr, "myalloc64 %p\n", newpage->data);
- fflush(stderr);
- #endif
- return newpage->data;
- }
- int alloced = 0;
- void * myalloc(size_t size){
- struct mempage *newpage, *page;
- unsigned pagesize;
- unsigned i=0, j, k=0;
- int p;
- alloced++;
- if(!mem_init)init_mem();
- for(p = nomem; ; ) {
- if(!p){
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Page is too large (%u), requesting malloc instead\n", size);
- fflush(stderr);
- #endif
- return malloc(size);
- }
- p--;
- if(size<memsizes[p]){
- break;
- }
- }
- if(p == p64k){
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Page will p64k\n");
- fflush(stderr);
- #endif
- return myalloc64k();
- }
- pagesize = memsizes[p];
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Calculated pagesize: %u\n", pagesize);
- fflush(stderr);
- #endif
- pthread_mutex_lock(&mem_mutex);
- newpage = pages[p];
- if(newpage && newpage->usable){
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Useful page found: %X,", newpage);
- fflush(stderr);
- #endif
- for(j=0; j<32; j++){
- register unsigned c = newpage->bitmap[j];
- if(c){
- for(k=0; ;k++)if(c & (1<<k))break;
- i = (j<<11) + (k<<8);
- #if DEBUGLEVEL > 2
- fprintf(stderr, "region: %X, offset %u, byte %u, %u, %u\n", newpage->data + i, i, j, k, newpage->bitmap[j]);
- fflush(stderr);
- #endif
- break;
- }
- }
- }
- else{
- if(!(newpage = (struct mempage *)malloc(sizeof(struct mempage)))){
- pthread_mutex_unlock(&mem_mutex);
- #if DEBUGLEVEL > 0
- fprintf(stderr, "Failed to allocate p64k\n");
- fflush(stderr);
- #endif
- return NULL;
- }
- #if DEBUGLEVEL > 2
- fprintf(stderr, "New page used: %X,", newpage);
- fflush(stderr);
- #endif
- memset(newpage->bitmap, 0, 32);
- for(i = 0; i<MEM64K; i+=pagesize){
- j = (i >> 11);
- k = ((i & 0x000007FF) >> 8);
- newpage->bitmap[j] |= (1<<k);
- }
- i-=pagesize;
- newpage->next = pages[p];
- newpage->usable = MEM64K;
- pages[p] = newpage;
- }
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Byte was %d/%d/%d\n", j, k, newpage->bitmap[j]);
- fflush(stderr);
- #endif
- newpage->bitmap[j] ^= (1<<k);
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Byte set %d/%d/%d\n", j, k, newpage->bitmap[j]);
- fflush(stderr);
- #endif
- newpage->usable -= pagesize;
- #if DEBUGLEVEL > 2
- fprintf(stderr, "usable amount after allocation: %u\n", newpage->usable);
- fflush(stderr);
- #endif
- if(!newpage->usable){
- #if DEBUGLEVEL > 2
- fprintf(stderr, "No usable amount left\n", newpage->usable);
- fflush(stderr);
- #endif
- if((page = newpage->next) && page->usable){
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Moving to end of list\n", newpage->usable);
- fflush(stderr);
- #endif
- pages[p] = page;
- while(page->next && page->next->usable)page = page->next;
- newpage->next = page->next;
- page->next = newpage;
- }
- }
- pthread_mutex_unlock(&mem_mutex);
- #if DEBUGLEVEL > 2
- fprintf(stderr, "All done, returning: %x\n", newpage->data + i);
- fflush(stderr);
- #endif
- #if DEBUGLEVEL == 2
- fprintf(stderr, "malloc %p\n", (void *)(newpage->data + i));
- fflush(stderr);
- #endif
- return (void *)(newpage->data + i);
- }
- int myfindsize(void * p, struct mempage ***prevpagep, struct mempage **pagep){
- int i;
- struct mempage *prevpage, *page;
- for (i=0; i<nomem; i++){
- for(page = pages[i], prevpage = NULL; page; page=page->next){
- if( p >= (void *)page->data && p < (void *)(page->data + MEM64K))break;
- prevpage = page;
- }
- if(page){
- if(pagep)*pagep = page;
- if(prevpagep)*prevpagep = prevpage?&prevpage->next:&pages[i];
- #if DEBUGLEVEL > 2
- fprintf(stderr, "%x belongs to page: %x with data %x\n", p, page, page->data);
- fflush(stderr);
- #endif
- break;
- }
- }
- return i;
- }
- void myfree(void *p){
- struct mempage **prevpage, *page;
- int i;
- unsigned pagesize;
- unsigned size, j, k;
-
- alloced--;
- #if DEBUGLEVEL == 2
- fprintf(stderr, "free %p\n", p);
- fflush(stderr);
- #endif
- pthread_mutex_lock(&mem_mutex);
- i = myfindsize(p, &prevpage, &page);
- if (i == nomem) {
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Page does not exists, trying free()\n");
- fflush(stderr);
- #endif
- pthread_mutex_unlock(&mem_mutex);
- free(p);
- return;
- }
- pagesize = memsizes[i];
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Calculated pagesize: %u\n", pagesize);
- fflush(stderr);
- #endif
- size = (unsigned)((unsigned char*)p - page->data);
- if(size%pagesize) {
- #if DEBUGLEVEL > 0
- write(2, p, 4);
- fprintf(stderr, "\nGiven address is not block aligned, ignoring\n");
- fflush(stderr);
- #endif
- pthread_mutex_unlock(&mem_mutex);
- return; /* Hmmmmm */
- }
- *prevpage = page->next;
- page->usable += pagesize;
- #if DEBUGLEVEL > 2
- fprintf(stderr, "New usable space: %u\n", page->usable);
- fflush(stderr);
- #endif
- if(page->usable >= MEM64K && ((pagesize == MEM64K) || (pages[i] && pages[i]->usable))) {
- #if DEBUGLEVEL > 2
- fprintf(stderr, "Free this page\n");
- fflush(stderr);
- #endif
- free(page);
- }
- else {
- j = (size>>11);
- k = ((size & 0x000007FF) >> 8);
- k = ('\01'<<k);
- if(page->bitmap[j] & k) {
- #if DEBUGLEVEL > 0
- fprintf(stderr, "Error: double free() %d/%d/%d\n", j, k, page->bitmap[j]);
- fflush(stderr);
- #endif
- page->usable += pagesize;
- }
- page->bitmap[j] |= k;
- page->next = pages[i];
- pages[i] = page;
- #if DEBUGLEVEL > 2
- fprintf(stderr, "This page will be reused next time\n");
- fflush(stderr);
- #endif
- }
- pthread_mutex_unlock(&mem_mutex);
- }
- char * mystrdup(const char *str){
- unsigned l;
- char *p;
- if(!str) return NULL;
- l = ((unsigned)strlen(str))+1;
- p = myalloc(l);
- if(p)memcpy(p, str, l);
- #if DEBUGLEVEL == 2
- fprintf(stderr, "strdup %p\n", p);
- fflush(stderr);
- #endif
- return p;
- }
- void *myrealloc(void *ptr, size_t size){
- unsigned l;
- void * p;
- l = myfindsize(ptr, NULL, NULL);
- if(size <= memsizes[l]) return ptr;
- p = myalloc(size);
- if(p){
- memmove(p,ptr,size);
- myfree(ptr);
- }
- return p;
- }
- #ifdef WITH_MAIN
- int main(){
- void *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10, *p11, *p12, *p13;
- p1 = myalloc(5000);
- p2 = myalloc(5000);
- p3 = myalloc(5000);
- p4 = myalloc(5000);
- p5 = myalloc(5000);
- p6 = myalloc(5000);
- p7 = myalloc(5000);
- p8 = myalloc(5000);
- p9 = myalloc(5000);
- p10 = myalloc(5000);
- myfree(p2);
- myfree(p8);
- p11 = myalloc(5000);
- p12 = myalloc(5000);
- p13 = myalloc(5000);
- p2 = myalloc(5000);
- p8 = myalloc(5000);
- myalloc(5000);
- }
- #endif
- #endif
|