static void preview(struct edit *edit) { struct textLine *ln; int len = 0, i; char *buf = malloc(1024 * 16); if (!buf) return; for (i = edit->linecur, ln = edit->curline; i; i--) ln = ln->prev; while (ln && len + ln->len < 1024 * 16 - 1) { memcpy(buf + len, ln->text, ln->len); len += ln->len; if (ln->br) { buf[len] = '\n'; len++; } ln = ln->next; } mem_show(buf, len, 0, t_lines, ""); free(buf); edit->redrawall = 1; move(t_lines - 1, 0); prints ("\033[1;33;44m已显示彩色编辑成果,请按任意键返回编辑画面...\033[0m"); igetkey(); }
/************************************************************************** * main() * **************************************************************************/ int main(int argc, char *argv[]) { int ret=1; BI_CTX *bi_ctx; #ifdef SELF_MALLOC mem_init(8000); #endif mem_show(); ret = RSA_test(); mem_show(); bi_ctx = bi_initialize(); mem_show(); ret = AES_test(bi_ctx); mem_show(); bi_terminate(bi_ctx); mem_show(); return ret; }
void my_mem_show(void (*print)(void *, size_t, int free)) { nb_free = 0; nb_busy = 0; mem_show(print); }
void* mem_alloc(size_t size_alloc) { pthread_mutex_lock(&mutex); if (size_alloc == 0) { printf("opération invalide (size=0)\n"); pthread_mutex_unlock(&mutex); return NULL; } fb* ptr_alloc = ptr_init; //calcul de l'espace mémoire réel à réserver //1) métadonnées size_alloc += METASIZE; //2) alignement size_alloc = align(size_alloc); // //3) zone de débordement // size_alloc += 8; //recherche d'une zone libre selon la stratégie d'allocation choisie ptr_alloc = (*active_fit_fonction)(ptr_alloc, size_alloc); if (ptr_alloc == NULL) { printf("Allocation impossible\n"); pthread_mutex_unlock(&mutex); return NULL; } //3) padding if (size_alloc + align(1) + METASIZE >= ptr_alloc->size) { size_alloc = ptr_alloc->size; } //récupère le pointeur de zone libre précédant la zone libre choisie fb* ptr_prec = ptr_init; if (ptr_prec->next != NULL) { while (ptr_prec->next < ptr_alloc) { ptr_prec = ptr_prec->next; } } //met à jour le chainage des zones libres restantes if (ptr_alloc->size == size_alloc) { //1er cas : la zone libre choisie est totalement remplie if (ptr_alloc == ptr_init) { // la zone allouée est la première du chainage // on remplace le chainage (ptr_alloc---->ptr_alloc.next---->...) par (ptr_alloc.next---->...) ptr_init = ptr_init->next; } else { // on remplace le chainage (ptr_prec---->ptr_alloc---->ptr_alloc.next) par (ptr_prec---->ptr_alloc.next) ptr_prec->next = (fb*) ptr_alloc->next; } } else { //2e cas : la zone libre choisie est partiellement remplie //=> on décale le pointeur de zone libre if ((fb*) ptr_alloc == ptr_init) { //décale les métadonnées de la zone libre : //1) buffer fb* ptr_tmp = ptr_init; //2) décale le pointeur ptr_init = (fb*) ((void*) ptr_init + size_alloc); //3) met à jour la taille ptr_tmp->size = ptr_tmp->size - size_alloc; //4) écrit les métadonnées ptr_init->size = ptr_tmp->size; ptr_init->next = ptr_tmp->next; } else { //décale les métadonnées de la zone libre : //1) buffer fb* ptr_tmp = ptr_prec->next; //2) décale le pointeur ptr_prec->next = (fb*) ((void*) ptr_prec->next + size_alloc); //3) met à jour la taille ptr_tmp->size = ptr_tmp->size - size_alloc; //4) écrit les métadonnées ptr_prec->next->size = ptr_tmp->size; ptr_prec->next->next = ptr_tmp->next; } } //écrit la taille de l'espace mémoire réservé avant celui-ci *((size_t*) ptr_alloc) = size_alloc; // //écrit DEBORDEMENT à la fin de la zone réservée // int* ptr_debordement = (int*) ((void*) ptr_alloc + size_alloc - sizeof(int)); // *ptr_debordement = DEBORDEMENT; //décale ptr_alloc sur la premiere case de l'espace réservé (=valeur de retour) ptr_alloc = (fb*) ((void*) ptr_alloc + METASIZE); accumulation += size_alloc; mem_show(calculation); pthread_mutex_unlock(&mutex); return ptr_alloc; }
void mem_free(void* zone) { pthread_mutex_lock(&mutex); //décale pointeur vers l'arrière pour récupérer les métadonnées fb* ptr_free = (fb*) (zone - METASIZE); ptr_free->size = *((size_t*) ptr_free); // //vérifie si il n'y a pas eu de débordement // int* ptr_debordement = (int*) ((void*) ptr_alloc + ptr_free->size - sizeof(int)); if(ptr_free < ptr_init) { //cas 1 : ptr_free < ptr_init = ptr_free devient le nouveau ptr_init if((fb*) ((void*) ptr_free + ptr_free->size) == ptr_init) { //cas 1.1 : adjacent à la premiere zone libre = fusion (amont) fb* ptr_tmp = ptr_init; ptr_init = (fb*) ((void*) ptr_init - ptr_free->size); ptr_init->size = ptr_free->size + ptr_tmp->size; ptr_init->next = ptr_tmp->next; } else { //cas 1.2 : entouré de zones occupées //on remplace le chainage (ptr_init) par (ptr_free(nouveau init)---->ptr_init(ancien init)) fb* ptr_tmp = ptr_init; ptr_init = ptr_free; ptr_init->next = ptr_tmp; ptr_init->size = ptr_free->size; } } else if (ptr_free > ptr_init) { //cas 2 : ptr_free > ptr_init = mise à jour du chainage à partir de ptr_init if (ptr_init == NULL) { //cas 2.1 : ptr_init == NULL donc la mémoire est pleine : la zone libérée devient le nouveau ptr_init ptr_init = ptr_free; ptr_init->size = ptr_free->size; ptr_init->next = NULL; } else { //cas 2.2 : tous les autres cas //récupére les pointeurs des zones libres "encadrant" la zone à libérer fb* ptr_prec = (fb*) ptr_init; while (ptr_prec->next != NULL && ptr_prec->next < ptr_free) { ptr_prec = ptr_prec->next; } fb* ptr_suivant = ptr_prec->next; if ((fb*) ((void*) ptr_prec + ptr_prec->size) != ptr_free && (fb*) ((void*) ptr_suivant - ptr_free->size) != ptr_free) { //cas 2.2.1 : entouré de zones occupées : on remplace le chainage (ptr_prec---->ptr_suivant) par (ptr_prec---->ptr_free---->ptr_suivant) ptr_prec->next = ptr_free; ptr_free->next = ptr_suivant; } else { if ((fb*) ((void*) ptr_prec + ptr_prec->size) == ptr_free) { //cas 2.2.2 : zone libre juste avant la zone à libérer(fusion aval) fb* ptr_tmp = ptr_free; ptr_free = ptr_prec; ptr_free->size += ptr_tmp->size; } if ((fb*) ((void*) ptr_free + ptr_free->size) == ptr_suivant) { //cas 2.2.3 : zone libre juste après la zone à libérer(fusion amont) fb* ptr_tmp = ptr_suivant; ptr_suivant = (fb*) ((void*) ptr_suivant - ptr_free->size); ptr_suivant->size = ptr_tmp->size + ptr_free->size; ptr_suivant->next = ptr_tmp->next; if (ptr_prec == ptr_suivant) { //cas particulier pour ptr_prec = ptr_init ptr_prec = ptr_suivant; } else { ptr_prec->next = ptr_suivant; } } } } } mem_show(calculation); pthread_mutex_unlock(&mutex); }