/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* ft_free.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/11/19 15:44:05 by thrieg #+# #+# */ /* Updated: 2025/11/25 16:21:10 by thrieg ### ########.fr */ /* */ /* ************************************************************************** */ #include "../includes/ft_malloc.h" // returns non-0 (1) when the function munmap the zone int defrag_zone(t_zone *zone) { t_header *header = (t_header *)(zone + 1); char *last_adr = ((char *)zone) + zone->size - sizeof(t_header); while ((((char *)header) + header->size) < last_adr) { t_header *next_header = (t_header *)(((char *)header) + sizeof(t_header) + header->size); if (!header->occupied && !next_header->occupied) { header->size = header->size + sizeof(t_header) + next_header->size; } else { header = next_header; } } // if only 1 free header left, mmunmap the zone if (header == (t_header *)(zone + 1) && !header->occupied) { if (zone->type == E_SMALL) { if (g_state.small_zone == zone) { if (zone->next) g_state.small_zone = zone->next; else return (0); // last small zone, don't deallocate to avoid mmap stress } } else if (zone->type == E_TINY) { if (g_state.tiny_zone == zone) { if (zone->next) g_state.tiny_zone = zone->next; else return (0); // last tiny zone, don't deallocate to avoid mmap stress } } if (zone->prev) zone->prev->next = zone->next; if (zone->next) zone->next->prev = zone->prev; munmap(zone, zone->size); return (1); } return (0); } void free(void *ptr) { pthread_mutex_lock(&g_mut); if (!ptr) return ((void)pthread_mutex_unlock(&g_mut)); t_header *header = ((t_header *)ptr) - 1; if (header->zone->type == E_LARGE) { if (header->zone->prev) header->zone->prev->next = header->zone->next; if (header->zone->next) header->zone->next->prev = header->zone->prev; if (header->zone == g_state.large_zone) { if (g_state.large_zone->next) g_state.large_zone = g_state.large_zone->next; else g_state.large_zone = NULL; } void *ptr = header->zone; size_t len = header->zone->size; munmap(ptr, len); } else if (header->zone->type == E_SMALL) { header->occupied = false; defrag_zone(header->zone); } else if (header->zone->type == E_TINY) { header->occupied = false; defrag_zone(header->zone); } pthread_mutex_unlock(&g_mut); }