// TCALLOC.C - TCtask - Dynamic memory allocation interface // V1.2 TECON Ltd. // This module contains the memory allocation functions that are needed // if TSK_DYNAMIC is defined. #include #include #include #include #include #include "tcconf.h" #include "tsk.h" #include "tclocal.h" #define FREE 1 // POOLSIZE_TCT define dynamic memory allocation pool size. // CAUTION: STACK must exceed POOLSIZE_TCT on 1024 at least. #if (TSK_DYNAMIC) char *st_up(void); #pragma aux st_up = "mov eax, esp "\ value [eax] ; \ dword POOLSIZE_TCT = 0; // будет = stkavail-MAIN_STK_TCT-256 dword MAIN_STK_TCT = 5000; // размер стeка для -MAIN- resource alloc_resource; poolptr pool = NULL; //int stack_size = 120000; /*-------------------------------------------------------------------*/ void tsk_init_pool (int s_size) /* system stack used */ { char *stk_ptr, *ptc; dword i, stkavail; request_resource(&alloc_resource,0L); pool = (poolptr)malloc(s_size); ptc = (char *)pool; for(i=0; i < s_size; i++) ptc[i]='S'; pool->size = s_size | FREE; pool->next = pool->prev = pool; /* stkavail = stackavail() & 0xfffffffe; POOLSIZE_TCT = stkavail-MAIN_STK_TCT-256; // 256 - запас "сверху" stk_ptr=st_up(); pool = (poolptr)(stk_ptr-MAIN_STK_TCT-POOLSIZE_TCT); ptc = (char *)pool; for(i=0; i < POOLSIZE_TCT+MAIN_STK_TCT-64; i++) ptc[i]='S'; pool->size = POOLSIZE_TCT | FREE; pool->next = pool->prev= pool; */ release_resource(&alloc_resource); sleep(5); } /*-------------------------------------------------------------------*/ nearptr talloc (dword size) { poolrec *tmp, *out, *new; size = (size+sizeof(poolrec)+1) & 0xfffffffe; // pool rec are incl. in blk tmp = pool; out = NULL; do // look for smallest suitable free memory block if((tmp->size & FREE) && ((tmp->size == size+1) || (tmp->size > size+sizeof(poolrec)+1))) if((out == NULL) || (tmp->size < out->size)) out = tmp; while((tmp = tmp->next) != pool); if(out == NULL) return (NULL); // not such block if(out->size == size+1) { // block just of size out->size = size; return ((byteptr)out+sizeof(poolrec)); } new = (poolptr)((byteptr)out+size); // blk too large,new blk cut off new->size = out->size - size; new->next = out->next; new->prev = out; (out->next)->prev = new; out->size = size; out->next = new; return ((byteptr)out+sizeof(poolrec)); } /*-------------------------------------------------------------------*/ void tfree (nearptr item) { poolrec *tmp, *p, *n; tmp = pool; do; while((((byteptr)tmp+sizeof(poolrec)) != item) && ((tmp=tmp->next) != pool)); if(((byteptr)tmp+sizeof(poolrec)) != item) return; // item not found tmp->size |= FREE; p = tmp->prev; n = tmp->next; if((p->size & FREE) && (tmp != pool)) // paste to prev. { p->size += (tmp->size & 0xfffffffe); p->next = n; n->prev = p; tmp = p; } if((n->size & FREE) && (n != pool)) // paste next to tmp { tmp->size += (n->size & 0xfffffffe); tmp->next = n->next; (n->next)->prev = tmp; } } /*-------------------------------------------------------------------*/ nearptr tsk_alloc (dword size) { nearptr ptr; request_resource(&alloc_resource,0L); ptr = talloc(size); release_resource(&alloc_resource); return ptr; } /*-------------------------------------------------------------------*/ void tsk_free (nearptr item) { request_resource(&alloc_resource,0L); tfree(item); release_resource(&alloc_resource); } #endif