코딩/Memory

#2 mymemory (GitHub)

주주낙낙 2023. 10. 30. 19:57

Custom Memory Management implementation

https://github.com/miguelperes/custom-malloc/blob/master/README.md

my memory.h

#define SYSTEM_MALLOC 1
#define STRUCT_SIZE 24 
#define MULTIPLIER 10
#define ALIGN_SIZE 8
#define ALIGN(size) (((size) + (ALIGN_SIZE-1)) & ~(ALIGN_SIZE-1))

typedef struct chunkStatus
{
  int size;
  int available;
  struct chunkStatus* next;
  struct chunkStatus* prev;
  char end[1]; 		
} chunkStatus;

chunkStatus* findChunk(chunkStatus *headptr, unsigned int size);

void splitChunk(chunkStatus* ptr, unsigned int size);

chunkStatus* increaseAllocation(chunkStatus *tailptr, unsigned int size);

void mergeChunk(chunkStatus *freed);

void printList(chunkStatus *headptr);

void *mymalloc(unsigned int _size);

unsigned int myfree(void *ptr);

my memory.c

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>
#include <pthread.h>
#include "mymemory.h"

chunkStatus *head = NULL;
chunkStatus *lastVisited = NULL;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void *brkPoint0 = NULL;

chunkStatus* findChunk(chunkStatus *headptr, unsigned int size)
{
  chunkStatus* ptr = headptr;
  
  while(ptr != NULL)
  {
    if(ptr->size >= (size + STRUCT_SIZE) && ptr->available == 1)
    {
      return ptr;
    }
    lastVisited = ptr;
    ptr = ptr->next;
  }  
  return ptr;  
}

void splitChunk(chunkStatus* ptr, unsigned int size)
{
  chunkStatus *newChunk;	
  
  newChunk = ptr->end + size;
  newChunk->size = ptr->size - size - STRUCT_SIZE;
  newChunk->available = 1;
  newChunk->next = ptr->next;
  newChunk->prev = ptr;
  
   if((newChunk->next) != NULL)
   {      
      (newChunk->next)->prev = newChunk;
   }
  
  ptr->size = size;
  ptr->available = 0;
  ptr->next = newChunk;
}

chunkStatus* increaseAllocation(chunkStatus *lastVisitedPtr, unsigned int 
size)
{
  brkPoint0 = sbrk(0);
  chunkStatus* curBreak = brkPoint0;	
  
  if(sbrk(MULTIPLIER * (size + STRUCT_SIZE)) == (void*) -1)
  {
    return NULL;
  }
  
  curBreak->size = (MULTIPLIER * (size + STRUCT_SIZE)) - STRUCT_SIZE;
  curBreak->available = 0;
  curBreak->next = NULL;
  curBreak->prev = lastVisitedPtr;
  lastVisitedPtr->next = curBreak;
  
  if(curBreak->size > size)
    splitChunk(curBreak, size);
  
  return curBreak;  
}

void mergeChunkPrev(chunkStatus *freed)
{ 
  chunkStatus *prev;
  prev = freed->prev;
  
  if(prev != NULL && prev->available == 1)
  {
    prev->size = prev->size + freed->size + STRUCT_SIZE;
    prev->next = freed->next;
    if( (freed->next) != NULL )
      (freed->next)->prev = prev;
  }
}

void mergeChunkNext(chunkStatus *freed)
{  
  chunkStatus *next;
  next = freed->next;
  
  if(next != NULL && next->available == 1)
  {
    freed->size = freed->size + STRUCT_SIZE + next->size;
    freed->next = next->next;
    if( (next->next) != NULL )
      (next->next)->prev = freed;
  }
}

void printList(chunkStatus *headptr)
{
int i = 0;
  chunkStatus *p = headptr;
  
  while(p != NULL)
  {
    printf("[%d] p: %d\\n", i, p);
    printf("[%d] p->size: %d\\n", i, p->size);
    printf("[%d] p->available: %d\\n", i, p->available);
    printf("[%d] p->prev: %d\\n", i, p->prev);
    printf("[%d] p->next: %d\\n", i, p->next);
    printf("__________________________________________________\\n");
    i++;
    p = p->next;
  }
}

void *mymalloc(unsigned int _size) 
{
  //pthread_mutex_lock(&lock);
  
  
  void *brkPoint1;
  unsigned int size = ALIGN(_size);
  int memoryNeed = MULTIPLIER * (size + STRUCT_SIZE);
  chunkStatus *ptr;
  chunkStatus *newChunk;

  pthread_mutex_lock(&lock);
  brkPoint0 = sbrk(0);
  
  
  if(head == NULL)			
  {
    if(sbrk(memoryNeed) == (void*) -1)	
    {
      pthread_mutex_unlock(&lock);
      return NULL;
    }
    
    
    brkPoint1 = sbrk(0);
    head = brkPoint0;
    head->size = memoryNeed - STRUCT_SIZE;
    head->available = 0;
    head->next = NULL;
    head->prev = NULL;
    
    
    ptr = head;
    
    
    if(MULTIPLIER > 1)  
      splitChunk(ptr, size);

    pthread_mutex_unlock(&lock);
    
    return ptr->end;
  }
  
  else							
  {
    chunkStatus *freeChunk = NULL;
    freeChunk = findChunk(head, size);
    
    if(freeChunk == NULL)			
    {
      freeChunk = increaseAllocation(lastVisited, size);
      if(freeChunk == NULL) 				
      {
	pthread_mutex_unlock(&lock);
	return NULL;
      }
      pthread_mutex_unlock(&lock);
      return freeChunk->end;
    }
    
    else				
    {
      if(freeChunk->size > size)		
	splitChunk(freeChunk, size);
    }    
    pthread_mutex_unlock(&lock);    
    return freeChunk->end;
  }  
}

unsigned int myfree(void *ptr) {
	//#if SYSTEM_MALLOC
	pthread_mutex_lock(&lock);
	
	chunkStatus *toFree;
	toFree = ptr - STRUCT_SIZE;
	
	if(toFree >= head && toFree <= brkPoint0)
	{
	  toFree->available = 1;	
	  mergeChunkNext(toFree);
	  mergeChunkPrev(toFree);
	  pthread_mutex_unlock(&lock);
	  return 0;
	  
	}
	else
	{
	  pthread_mutex_unlock(&lock);
	  return 1;
	}
}

main.h

#include "mymemory.h"

int main()
{
    int *a = (int *)mymalloc(sizeof(int));
    printList(a);
    myfree(a);
    return 0;
}

compile

gcc main.h mymemory.h -o main.out

근데.. warning 미친듯이 뜨긴 함

main.c:6:15: warning: incompatible pointer types passing 'int *' to parameter of type 'chunkStatus *' (aka 'struct chunkStatus *') [-Wincompatible-pointer-types]
    printList(a);
              ^
./mymemory.h:27:29: note: passing argument to parameter 'headptr' here
void printList(chunkStatus *headptr);
                            ^
1 warning generated.
mymemory.c:37:12: warning: incompatible pointer types assigning to 'chunkStatus *' (aka 'struct chunkStatus *') from 'char *' [-Wincompatible-pointer-types]
  newChunk = ptr->end + size;
           ^ ~~~~~~~~~~~~~~~
mymemory.c:58:15: warning: 'sbrk' is deprecated [-Wdeprecated-declarations]
  brkPoint0 = sbrk(0);
              ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/unistd.h:582:1: note: 'sbrk' has been explicitly marked deprecated here
__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:211:40: note: expanded from macro '__deprecated'
#define __deprecated    __attribute__((__deprecated__))
                                       ^
mymemory.c:61:6: warning: 'sbrk' is deprecated [-Wdeprecated-declarations]
  if(sbrk(MULTIPLIER * (size + STRUCT_SIZE)) == (void*) -1)
     ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/unistd.h:582:1: note: 'sbrk' has been explicitly marked deprecated here
__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:211:40: note: expanded from macro '__deprecated'
#define __deprecated    __attribute__((__deprecated__))
                                       ^
mymemory.c:117:31: warning: format specifies type 'int' but the argument has type 'chunkStatus *' (aka 'struct chunkStatus *') [-Wformat]
    printf("[%d] p: %d\\n", i, p);
                    ~~        ^
mymemory.c:120:37: warning: format specifies type 'int' but the argument has type 'struct chunkStatus *' [-Wformat]
    printf("[%d] p->prev: %d\\n", i, p->prev);
                          ~~        ^~~~~~~
mymemory.c:121:37: warning: format specifies type 'int' but the argument has type 'struct chunkStatus *' [-Wformat]
    printf("[%d] p->next: %d\\n", i, p->next);
                          ~~        ^~~~~~~
mymemory.c:141:15: warning: 'sbrk' is deprecated [-Wdeprecated-declarations]
  brkPoint0 = sbrk(0);
              ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/unistd.h:582:1: note: 'sbrk' has been explicitly marked deprecated here
__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:211:40: note: expanded from macro '__deprecated'
#define __deprecated    __attribute__((__deprecated__))
                                       ^
mymemory.c:146:8: warning: 'sbrk' is deprecated [-Wdeprecated-declarations]
    if(sbrk(memoryNeed) == (void*) -1)  
       ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/unistd.h:582:1: note: 'sbrk' has been explicitly marked deprecated here
__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:211:40: note: expanded from macro '__deprecated'
#define __deprecated    __attribute__((__deprecated__))
                                       ^
mymemory.c:153:17: warning: 'sbrk' is deprecated [-Wdeprecated-declarations]
    brkPoint1 = sbrk(0);
                ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/unistd.h:582:1: note: 'sbrk' has been explicitly marked deprecated here
__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:211:40: note: expanded from macro '__deprecated'
#define __deprecated    __attribute__((__deprecated__))
                                       ^
mymemory.c:207:30: warning: comparison of distinct pointer types ('chunkStatus *' (aka 'struct chunkStatus *') and 'void *') [-Wcompare-distinct-pointer-types]
        if(toFree >= head && toFree <= brkPoint0)
                             ~~~~~~ ^  ~~~~~~~~~
10 warnings generated.

출력결과

(base) lee@ijunhag-ui-MacBookAir mymemory % ./main3.out
[0] p: 40116248
[0] p->size: 0
[0] p->available: 0
[0] p->prev: 0
[0] p->next: 264
__________________________________________________
[1] p: 264
zsh: segmentation fault  ./main3.out