From 982fc062f97aae63b5bb4c638ca12ec608f927b9 Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Fri, 17 Feb 2017 13:19:28 +0100 Subject: [PATCH] fixes bit/byte confusion, also large zones work now --- malloc/includes/malloc.h | 16 ++++-- malloc/libft_malloc_x86_64_Darwin.so | Bin 11536 -> 12004 bytes malloc/main.c | 17 +----- malloc/src/free.c | 19 +++++-- malloc/src/insert_node.c | 12 +++++ malloc/src/malloc.c | 47 +++++++++++------ malloc/src/show_alloc_mem.c | 74 ++++++++++++++++----------- 7 files changed, 117 insertions(+), 68 deletions(-) diff --git a/malloc/includes/malloc.h b/malloc/includes/malloc.h index 71aa48e8..07a3c41f 100644 --- a/malloc/includes/malloc.h +++ b/malloc/includes/malloc.h @@ -1,3 +1,15 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* malloc.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 12:28:05 by jhalford #+# #+# */ +/* Updated: 2017/02/17 13:17:57 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + #ifndef MALLOC_H # define MALLOC_H @@ -6,9 +18,7 @@ # define malloc_N (1 * getpagesize()) # define malloc_M (2 * getpagesize()) # define malloc_magic 1234567 -# define malloc_realign(x) ((((x) + 1) / 8) * 8) -# define malloc_bytes(x) (((x) + 1) / 8) -# define HEADER_SIZE malloc_bytes(sizeof(t_node)) +# define HEADER_SIZE (sizeof(t_node)) # define TINY(x) (x < (malloc_n + 1)) # define SMALL(x) (!TINY(x) && !LARGE(x)) # define LARGE(x) (malloc_m < x) diff --git a/malloc/libft_malloc_x86_64_Darwin.so b/malloc/libft_malloc_x86_64_Darwin.so index 0242ce5390bca4fb078a8b8a0533225f013ad45a..71181154b57db7bcc0d6b6e7a708dba29bc9b548 100755 GIT binary patch literal 12004 zcmeHNeQaCR6~8ZOSo&$xQC2={7}?TQud^G!=`(Z!7 zgjD-y+8@5kd-wj%J?GqW&pG$LoA-R?<9}TI0%KY=W9%|qi*eP~Ft(q$(PHc>T<0{# z3}dTr+g460zX`SyO=9R|P{S|kG>k-OPl8&aIQ5MYGs^3=q9!~~G{t=$8?i&fh$jZS z;zg2E-_9kX>w3vS7}F@0TB(obOhxE3dPCu8D8_O5d`G3eO`MxC!d0@(s~PqM;)z(_ zK#$~c+ILFodq?&wtW=ii2GKAE2X^-j1dYCd?g+=__KmxQq%IW@cIuE_yrQ^{^0>CO zZf&*osCa%(O>w1MQL!hFq#jc6hUJ7?FY)KOZIyei~>8G24KjGl-sO=jqG zOGPqG7-6SAvQZVo2>a)K#zwfU9x=~a)TBohuZOX10FR&^!+?}iG=>hrhfr_$8e>P0 z3=7fTf{V%yc`ZXdh|3-iz_L;cd9vMEt^t9@d1cWL4=#CP&vj>4-|1w^SXK5dJ$=kPDc@9bLNk3+ zx$N}xH19Wku)$YQBPji_$pSsEC)Yvt8>Ed;is|cpmTNz4yNZzV*3u}tsZIJm1)b$6 zxT-ffQHxpRbI)Qx^wSJezE8KGaIF|YlgaV84Pq?X^C1ihDy|yM`Fg4o)lxmMRM-Bb z-*(cq|JHK86pY|P)wQN-3VG5Ygw0L0Iod~+dSP23_b_a0o*z6nQY15Oiq=n$k9NNIBj0;RG}nH59OSOB8Kg#hT8xNX>~3(a*ar@o z9~2K-FJ*I_O~aeeaFm{1W=3D%k#{Azt9cqvxG5Mp+6!sXw7QbC9a!zKCX+<~F63y7 zvo>&yC2}FSl-4JYi;@r%nE76=YhEVi0%+>%%;Q?sI0QJ=Jl}qEi*9uoCg| zS+GFlV<{Uay+|G!o+4<^fBXE*PGk#D*Hjfx3z@o|NHcULkGuIG)mQ4~m3p8Pc>_a| zFS+%V|1{4^NwbQ0Im}X9X4cuy$ZjYiCFtdLbn`OP-|3ns;m6`OWlkbhSAlYjyZ5xd zez0Kr{_INfn5Sz#rP-$!|BWh>HUs#2EloCE^SbCd#j9n{@oLRss*=M6ER#)Q)kwhC zjM%<}-34ou>^6O{8+*~uGb8U$f0R*qw3Noc`Xi@UXTX^IBaaTJa8FtXv2Y-M4)JiV z9=U$RdOwX2H^2Nm-+%b-jEoE10S{oAQ1bC*43(&>hx6?`tA_KM>&{c?%j)JN`PS?> z-)?5wQoi%>*C%*F6_;$cYekzapVKuDV!UINgstYuImX2vFmr5LS+kG*a$Bl{#(ubL zY-fBuP+2esKfr#4>=~wAiJs)i;Sc1Kf~IV}1<&QM{gHq&K>S$E^EFm0Y9hdEiC=hY-@!FeP2{4p{Z{vVT*RT62U~Yq32Q z@DR?zBzhQIvd;55b&H;ITh|LyepAwPSZMkkSHXEc7Ss@6Yi2IPUG~>xNLZ-Zx#>hkC3R zA}sd~{LxECx!iebt)kYe)S`!b?j*H*)OrD}L~IEEZg~})=jU@cx7L0JK)Enn!k?sT+K>5E8oZ!4Y zBLB~LT-Hy^`uDP)khN2;f-4@Vc%b5eiU%qlsCb~_fr|>DjukK;Q!A9 zm*23Q-tVx>y#{>(_Xllk4H2mxBzliQ?IyIN_&%QKCbSM{cdRc#Y_ezuz6&qt zW;XzNV;~X?u|rxQ;tz-70fFP}39WA+9*QMI_p=(__`v?bfnDsF7H2PL;>{1s zYJ4n%y{#qs28Im0sSo>OJt2c#sAAO#gZ)6mJ0tcKv;~E#-)gKXI+(yWeD(_s_i$){ zJ%(RNj4j0Ll(TdjUxeGC#nf7YTh@i!SvPJI_^41F4fjc--q3m@yA3v4MYb61bQPq& zNK#ke3njg(GWtXP?4l+<(Na4}ELVbM>`P$T8yN_(N2^3P`z89u@J39KpQ$4L=Rh03 ziblR#b-XP2*~jRb@F?nAk~$6Q$s+YbN!?eC33#C99Nn^Xv%naXs*C_MD~H#wgp-PxdI>3p|@W-xlnAK4gy_+wFPC zG5%u?{5UY#bK~F3{nJFRQBh8!pX^ciFTk_e6BX=5d+eC}eMsudN_`5Wi~CotKf*L0 zJ0|%i`7uAQ?2%Z>|JpIW9na;DkD$*UpLuv`N&Z;k@JCjT*NlGhhr+i5&*qO^4twl) zE_=2>pWUAOr9IC0Y~i2m82i4oN8ulTjy?8xkbmu%{5v7_9hCYMR{qU8=3~bse~3QE zpd6O+3M+YgJZXG8Ciy1(tb)q8lvh~Ezb(3p`K9nt@Oxw*RVN(yj03;n!0$Tn2M$c* z&lN9iUU|Hh0?(E|9{P%lvI+f^KMLOqyiauTyPB^(KIAVuCV%01z)O$Rr?8SA5#2?9 z*)hqx=?5z)d!)R=O8yY<75gQPZ^tB$rw}hmDX*}Sx5t;{?U>}f^2av^q`bmPekC7`fi-Mg!%$ zxCn2Nn7(Au_$q(tH+_Uve3BBY`2S4t%l+|?#L6Gz5-a~^Bv$cyg)qk7A;*7RVqIcd zC)^)$eZDXIx5@s`B=$;N3tPn>I#8~5;F}$|#euyJtUK_x9GJfD?#8tT*AT9~xW0!A z#rq&`v-NwJQ95tocX4GWGo!nBmNMv+!wmcmO`fQzDbG~+J!9$ohTrPZp^P7Om<0Uz zBY(ig#F0@j@MDuC6pvAc{j_Mr>Eu;9SJ|;p%Nb;oAJ62_aSmih=_qIL!=vQkZNXwc zIrH=HENAJm!>~98s{^n+`p!6LH+I4`@y4CK{&06B7HnL7OQSf?(vR4>6OHj$ppl=U?suZAneO=mc2R|kt{w*smUz&x3DWI76kYdr> Rmu+c@%L$bT^uH06{{Y62a}fXl literal 11536 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 Zw9rxfJ5bn5q-YsYP!XMDQ +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 12:28:03 by jhalford #+# #+# */ +/* Updated: 2017/02/17 13:18:39 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include "malloc.h" int remove_node(t_node **head, t_node *node) @@ -18,7 +30,7 @@ int coalesce_nodes(t_node **head) { while (*head) { - if ((*head)->next == *(void**)head + 8 * (*head)->size) + if ((*head)->next == *(void**)head + (*head)->size) { (*head)->size += (*head)->next->size; (*head)->next = (*head)->next->next; @@ -35,12 +47,9 @@ void free(void *ptr) t_node **alloc_ref; t_node *hptr; - hptr = ptr - 8 * HEADER_SIZE; + hptr = ptr - HEADER_SIZE; zone_ref = TINY(hptr->size) ? &tiny_zone : &small_zone; alloc_ref = TINY(hptr->size) ? &tiny_alloc : &small_alloc; - /* printf("ptr @ [%p]\n", ptr); */ - /* printf("hptr @ [%p]\n", hptr); */ - /* printf("len=[%i]\n", hptr->size); */ if (remove_node(alloc_ref, hptr)) printf("trying to free bad address"); insert_node(zone_ref, hptr); diff --git a/malloc/src/insert_node.c b/malloc/src/insert_node.c index ff9adf4a..7b16e788 100644 --- a/malloc/src/insert_node.c +++ b/malloc/src/insert_node.c @@ -1,3 +1,15 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* insert_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 12:28:15 by jhalford #+# #+# */ +/* Updated: 2017/02/17 12:28:15 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include "malloc.h" void insert_node(t_node **head, t_node *new) diff --git a/malloc/src/malloc.c b/malloc/src/malloc.c index b89c8b73..64baa2bf 100644 --- a/malloc/src/malloc.c +++ b/malloc/src/malloc.c @@ -1,9 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* malloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 12:28:02 by jhalford #+# #+# */ +/* Updated: 2017/02/17 13:18:34 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include "malloc.h" t_node *tiny_zone = NULL; t_node *small_zone = NULL; +t_node *large_zone = NULL; t_node *tiny_alloc = NULL; t_node *small_alloc = NULL; +t_node *large_alloc = NULL; t_node **find_node(t_node **node, size_t size) { @@ -18,9 +32,11 @@ void add_chunk(t_node **node_ref, size_t size) while (*node_ref) node_ref = &(*node_ref)->next; - chunk_size = TINY(size) ? malloc_N : malloc_M; - printf("chunk_size=[%zu]\n", chunk_size); - *node_ref = mmap(NULL, (chunk_size +1) * 8, PROT_READ|PROT_WRITE, + if (LARGE(size)) + chunk_size = size + HEADER_SIZE; + else + chunk_size = TINY(size) ? malloc_N : malloc_M; + *node_ref = mmap(NULL, chunk_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); (*node_ref)->size = chunk_size; (*node_ref)->next = NULL; @@ -32,18 +48,12 @@ void *split_node(t_node **free, t_node **alloc, size_t size) int free_size; free_size = (*free)->size; - /* printf("split now size=[%zu]\n", size); */ - /* printf("free @ [%p], size=[%i]\n", *free, (*free)->size); */ - /* printf("size = [%lu]\n", size + HEADER_SIZE); */ - /* printf("alloc @ [%p]\n", *alloc); */ - /* fflush(stdout); */ new_alloc = *free; - *(void**)free += 8 * (size + HEADER_SIZE); - /* printf("free @ [%p], size=[%i]\n", *free, (*free)->size); */ + *(void**)free += (size + HEADER_SIZE); (*free)->size = free_size - (size + HEADER_SIZE); new_alloc->size = size; insert_node(alloc, new_alloc); - return ((void*)new_alloc + HEADER_SIZE * 8); + return ((void*)new_alloc + HEADER_SIZE); } void *malloc(size_t size) @@ -53,10 +63,17 @@ void *malloc(size_t size) t_node **node_ref; void *ptr; - printf("malloc(%zu) was called. [%lu] bytes\n", size, malloc_bytes(size)); - size = malloc_bytes(size); - zone_ref = TINY(size) ? &tiny_zone : &small_zone; - alloc_ref = TINY(size) ? &tiny_alloc : &small_alloc; + printf("malloc(%zu) was called\n", size); + if (LARGE(size)) + { + zone_ref = &large_zone; + alloc_ref = &large_alloc; + } + else + { + zone_ref = TINY(size) ? &tiny_zone : &small_zone; + alloc_ref = TINY(size) ? &tiny_alloc : &small_alloc; + } while (!*(node_ref = find_node(zone_ref, size))) add_chunk(node_ref, size); ptr = split_node(node_ref, alloc_ref, size); diff --git a/malloc/src/show_alloc_mem.c b/malloc/src/show_alloc_mem.c index d2dc2526..16d1fd06 100644 --- a/malloc/src/show_alloc_mem.c +++ b/malloc/src/show_alloc_mem.c @@ -1,9 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* show_alloc_mem.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 12:28:20 by jhalford #+# #+# */ +/* Updated: 2017/02/17 13:18:10 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include "malloc.h" t_node *tiny_zone; t_node *small_zone; +t_node *large_zone; t_node *tiny_alloc; t_node *small_alloc; +t_node *large_alloc; void print_free_mem(t_node *node) { @@ -13,7 +27,7 @@ void print_free_mem(t_node *node) size = node->size; addr = (void*)node; printf("\t%p - %p : %4zu byte%c\n", - addr, (void*)addr + 8 * size, size, size > 1 ? 's' : 0); + addr, (void*)addr + size, size, size > 1 ? 's' : 0); } void print_alloc_mem(t_node *node) @@ -22,48 +36,48 @@ void print_alloc_mem(t_node *node) void *addr; size = node->size; - addr = (void*)node + 8 * HEADER_SIZE; + addr = (void*)node + HEADER_SIZE; printf("\t%p - %p : %4zu(+%zu) byte%c\n", - addr, (void*)addr + 8 * size, size, HEADER_SIZE, size > 1 ? 's' : 0); + addr, (void*)addr + size, size, HEADER_SIZE, size > 1 ? 's' : 0); } -int show_zone(t_node *node, int is_free) +int show_zone(t_node *node, int is_free, size_t (*total)[3]) { - int total; - - total = 0; while (node) { is_free ? print_free_mem(node) : print_alloc_mem(node); - total += node->size + (is_free ? 0 : HEADER_SIZE); + (*total)[is_free ? 0 : 1] += node->size; + (*total)[2] += is_free ? 0 : HEADER_SIZE; node = node->next; } - return (total); + return (0); +} + +void show_alloc_zone(char *name, t_node *alloc, t_node *zone, size_t (*total)[3]) +{ + if (!alloc && !zone) + return ; + ft_putstr(name); + ft_putstr(FG_RED); + show_zone(alloc, 0, total); + ft_putstr(FG_GREEN); + show_zone(zone, 1, total); + ft_putstr(FG_DEFAULT); } void show_alloc_mem(void) { - size_t free_total; - size_t alloc_total; + size_t total[3]; - free_total = 0; - alloc_total = 0; - if (tiny_alloc || tiny_zone) - ft_putstr("TINY:"); - ft_putstr(FG_RED); - alloc_total += show_zone(tiny_alloc, 0); - ft_putstr(FG_GREEN); - free_total += show_zone(tiny_zone, 1); - ft_putstr(FG_DEFAULT); - if (small_alloc || small_zone) - ft_putstr("SMALL:"); - ft_putstr(FG_RED); - alloc_total += show_zone(small_alloc, 0); - ft_putstr(FG_GREEN); - free_total += show_zone(small_zone, 1); - ft_putstr(FG_DEFAULT); + total[0] = 0; + total[1] = 0; + total[2] = 0; + show_alloc_zone("TINY:", tiny_alloc, tiny_zone, &total); + show_alloc_zone("SMALL:", small_alloc, small_zone, &total); + show_alloc_zone("LARGE:", large_alloc, large_zone, &total); printf("Total:"); - printf("\t%7zu bytes allocated\n", alloc_total); - printf("\t%7zu bytes free\n", free_total); - printf("\t%7zu bytes mapped\n", alloc_total + free_total); + printf("\t%7zu bytes free\n", total[0]); + printf("\t%7zu bytes allocated\n", total[1]); + printf("\t%7zu header bytes\n", total[2]); + printf("\t%7zu bytes mmap'd\n", total[0] + total[1] + total[2]); }