SWjungle/#malloc

[Malloc] Implicit Free List๋ฐฉ์‹-๊ตฌํ˜„

์žฅ์˜ 2023. 9. 11. 14:01

Malloc - lab


๐Ÿ“Œheap

  • ๋™์  ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ธฐ๋Š” ํž™์ด๋ผ๋Š” ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.
  • ์ด๋Ÿฌํ•œ ํž™ ์˜์—ญ์—๋Š” ํ• ๋‹น๋œ ๋ธ”๋ก๊ณผ ๊ฐ€์šฉ๋ธ”๋ก์ด ์žˆ๋‹ค.
  • ํ• ๋‹น๊ธฐ์˜ ์ข…๋ฅ˜
    1. ๋ช…์‹œ์  ํ• ๋‹น๊ธฐ(explicit allocator) : ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ณผ ํ•ด์ œ๋ฅผ ์ง์ ‘์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์กฐ์ž‘ํ•˜๋Š” ํ• ๋‹น๊ธฐ
      • ๋‹จ์  : ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ , ๋ฌดํšจ ํ‘œ์ธํ„ฐ(์ด์ „์— ์ฐธ์กฐํ•˜๋˜ ๋ฉ”๋ชจ๋ฆฌ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค์ง€๋งŒ ์ด์ œ๋Š” ๋ฌดํšจํ™”๋œ ํฌ์ธํ„ฐ๋ฅผ ๋‚˜ํƒ€๋ƒ„)
    2. ์•”์‹œ์  ํ• ๋‹น๊ธฐ(implicit allocator) : ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ๋˜๋Š” ๋Ÿฐํƒ€์ž„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋‚ด์žฅ๋˜์–ด ์žˆ์–ด์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๋ฐ ํ•ด์ œ๋ฅผ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๋ฐฉ์‹
      • ๋‹จ์  : ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ ๋ฌธ์ œ, ์„ฑ๋Šฅ ๋ฌธ์ œ

 

Malloc pacakge


๐Ÿ“Œmalloc

void *malloc(size_t size)
  • ํ• ๋‹น ์„ฑ๊ณต์‹œ, 8byte๋กœ ์ •๋ ฌ๋œ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฅดํ‚ค๋Š” ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์‹คํŒจ์‹œ null(0) ๋ฐ˜ํ™˜.

 

๐Ÿ“Œfree

void free(void *p)
  • ํ• ๋‹น๋˜์ง€ ์•Š๋Š” ๋ธ”๋ก์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • p๋Š” ๋จผ์ € malloc์ด๋‚˜ calloc์— ์˜ํ•ด ํ• ๋‹น ๋˜์–ด์•ผ ํ•จ.
    • calloc : ๋ธ”๋ก์„ 0์œผ๋กœ ์ดˆ๊ธฐํ™”
    • realloc : ์ด๋ฏธ ํ• ๋‹น๋œ ๋ธ”๋ก ์‚ฌ์ด์ฆˆ๋ฅผ ์ค„์ด๊ฑฐ๋‚˜ ๋Š˜๋ฆผ
    • sbrak : ํž™ ์‚ฌ์ด์ฆˆ๋ฅผ ์ค„์ด๊ฑฐ๋‚˜ ๋Š˜๋ฆผ

 

โœ๏ธmalloc ์‚ฌ์šฉ์˜ˆ์‹œ

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr;
    int n = 5; // ์ •์ˆ˜ ๋ฐฐ์—ด์˜ ํฌ๊ธฐ

    // malloc์„ ์‚ฌ์šฉํ•˜์—ฌ n๊ฐœ์˜ int ํฌ๊ธฐ๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น
    arr = (int *)malloc(n * sizeof(int));

    if (arr == NULL) {
        fprintf(stderr, "๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์˜ค๋ฅ˜\n");
        return 1;
    }

    // ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์ถœ๋ ฅ
    for (int i = 0; i < n; i++) {
        arr[i] = i * 10;
        printf("arr[%d] = %d\n", i, arr[i]);
    }

    // ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œ
    free(arr);
    return 0;
}

 

allocator


 

๐Ÿ“Œํ• ๋‹น๊ธฐ ๊ตฌํ˜„ ์ œ์•ฝ

  • ์ด๋ฏธ ํ• ๋‹น๋œ ๋ธ”๋ก์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค.
  • malloc ์š”์ฒญ์— ๋ฐ”๋กœ ์‘๋‹ตํ•œ๋‹ค. ์ง€์—ฐ์‹œํ‚ค๊ฑฐ๋‚˜ ์žฌ์ •๋ ฌ์ด ๋ถˆ๊ฐ€๋Šฅ
    • -> ์š”์ฒญ ์ž์ฒด๋ฅผ ์ •๋ ฌ ํ•˜๊ฑฐ๋‚˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ํšจ์œจ์ ์ด๋‹ค. ํ•˜์ง€๋งŒ malloc ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์ง€์—ฐ์ด ์•„๋‹ˆ๋ผ ๊ณง๋ฐ”๋กœ ํž™์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•œ ํ›„ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•œ๋‹ค.
  • free์ธ ๋ธ”๋ก์—๋งŒ ํ• ๋‹น์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ํ• ๋‹น๋œ ๋ธ”๋ก์€ ์˜ฎ๊ธธ ์ˆ˜ ์—†๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ ์ •๋ ฌ์ด ํ•„์š”ํ•˜๋‹ค.
    • -> 32๋น„ํŠธ๋ผ๋ฉด 4๋ฐ”์ดํŠธ์”ฉ, 64๋น„ํŠธ๋ผ๋ฉด 8๋ฐ”์ดํŠธ์”ฉ
  • free ๋ธ”๋ก๋งŒ ์กฐ์ž‘ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ“Œํ• ๋‹น๊ธฐ ๊ตฌํ˜„ ์ด์Šˆ

  • ์–ด๋–ป๊ฒŒ ๊ฐ€์šฉ(free)๋ธ”๋ก์„ ์ง€์ˆ™์ ์œผ๋กœ ์ถ”์ ํ• ๊ฒƒ์ธ๊ฐ€?
  • ์–ด๋Š์ •๋„์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ free์‹œ์ผœ์•ผํ• ์ง€ , ํ•˜๋‚˜์˜ ํฌ์ธํ„ฐ๋กœ ์•Œ ์ˆ˜ ์žˆ๋Š”๊ฐ€?
  • ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹นํ›„ ๋‚˜๋จธ์ง€ ๊ฐ€์šฉ ๋ธ”๋ก๋“ค์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ธ๊ฐ€?
    • -> ๊ทธ๋Œ€๋กœ ๋†”๋‘๋ฉด ๋‚ด๋ถ€ ๋‹จํŽธํ™”๊ฐ€ ์ผ์–ด๋‚ ๊ฒƒ์ด๋‹ค. ์ž‘์€ ๋ธ”๋ก์œผ๋กœ ๋‹ค์‹œ ๋‚˜๋ˆ ์„œ free๋ธ”๋ก์œผ๋กœ ์“ธ ์ˆ˜๋„ ์žˆ์„๊ฒƒ์ด๋‹ค.
  • ํ• ๋‹น๋œ free ๋ธ”๋ก๋“ค์„ ์–ด๋–ป๊ฒŒ ๊ณ ๋ฅผ ๊ฒƒ์ธ๊ฐ€?
  • free๋œ ๋ธ”๋ก๋“ค์„ ์–ด๋–ป๊ฒŒ ํ•  ๊ฒƒ์ธ๊ฐ€? ์žฌ์—ฐ๊ฒฐ ํ• ๊ฒƒ์ธ๊ฐ€?

 

๐Ÿ“Œheader

  • header์—๋Š” ํ•ด๋‹น ๋ธ”๋ก์˜ ์‚ฌ์ด์ฆˆ
  • ํ• ๋‹น์—ฌ๋ถ€, free์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ด๊ฒจ์ ธ์žˆ์Œ

 

๐Ÿ“Œfree๋œ ๋ธ”๋ก๋“ค์„ ์ถ”์ ํ•˜๋Š” ๋ฒ•

 

๐Ÿ’ก1. implicit list (๋ฌต์‹œ์  ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ)

  • ๋ชจ๋“  ๋ธ”๋ก๋“ค์˜ ํ—ค๋”๋“ค์„ ๋ฐฉ๋ฌธํ•˜์—ฌ, ํ•ด๋‹น ๋ธ”๋ก์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ์ €์žฅํ•œ๋‹ค.

 

๐Ÿ’ก2. explicit list(๋ช…์‹œ์  ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ)

  • free๋œ ๋ธ”๋ก ๋‚ด์— ๋‹ค์Œ free ๋ธ”๋ก์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๊ฐ€ ์žˆ์–ด, ํ•œ free ๋ธ”๋ก์—์„œ ๋‹ค์Œ free ๋ธ”๋ก์˜ ์œ„์น˜๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ’ก3. segregated free list(๋ถ„๋ฆฌ ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ) 

  • ํ• ๋‹น์ด ํ•ด์ œ๋˜์–ด ์žˆ๋Š” ๋ธ”๋ก๋“ค์„ ์‚ฌ์ด์ฆˆ ๋ณ„๋กœ ๊ฐ๊ฐ์˜ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋กœ ๋งŒ๋“ค์–ด ๊ด€๋ฆฌํ•œ๋‹ค.

 

๐Ÿ’ก4. blocks sorted by size(ํฌ๊ธฐ๋ณ„๋กœ ์ •๋ ฌ๋œ ๋ธ”๋ก)

  • ๊ท ํ˜•ํŠธ๋ฆฌ๋ฅผ ์ด์šฉํ•ด ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ๋“ค์„ ํฌ๊ธฐ ์ˆœ์„œ๋Œ€๋กœ ์ •๋ ฌํ•œ๋‹ค.

 

implicit list (๋ฌต์‹œ์  ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ)


๐Ÿ“Œimplicit list

  • ๋ธ”๋ก์ด ํ• ๋‹น ๋˜์–ด ์žˆ์œผ๋ฉด a๋Š” 1์ด๊ณ , ํ• ๋‹น๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด 0์ด๋‹ค. 
  • a๋Š” ํ•ญ์ƒ 0์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์ด์ฆˆ๊ฐ€ 4๋ฐ”์ดํŠธ๋ฉด 100, 2๋ฐ”์ดํŠธ๋ฉด 10, ์—ฌ๊ธฐ๋ฅผ allocated/ free flag๋กœ ์‚ฌ์šฉ

๐Ÿ“ŒImplicit Free List ์˜ˆ์‹œ

  • ๋งจ ์ฒ˜์Œ์€ unused word
    • -> ๋งจ ์ฒ˜์Œ์— ํ—ค๋”๊ฐ€ ํ•„์š”ํ•˜๊ณ , 32bit๋กœ 8๋ฐ”์ดํŠธ(word 2๊ฐœ)๋กœ ์ •๋ ฌ๋˜์–ด ์žˆ๋‹ค๋Š” ์ „์ œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

 

๐Ÿ“Œํ• ๋‹นํ•  ๋ธ”๋ก ๋ฐฐ์น˜ ๋ฐฉ๋ฒ•

  • ๊ฐ„๋‹จํ•˜๊ฒŒ ์˜ˆ๋ฅผ ๋“ค์–ด ์„ค๋ช… ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌ๋˜๊ธฐ์ „ "๋‚˜์˜ ์šฉ๋Ÿ‰์€ 99M์ž…๋‹ˆ๋‹ค. ์ œ๊ฐ€ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์„๋งŒํผ์˜ ์šฉ๋Ÿ‰์„ ์ €์—๊ฒŒ ์ฃผ์„ธ์š”^^;๋ผ๊ณ  ๋งํ•  ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ํ”„๋กœ์„ธ์Šค๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฐ€์šฉ ๋ธ”๋ก์ค‘ ํ•˜๋‚˜๋ฅผ ์ค„๊ฒƒ์ด๋‹ค. ์–ด๋–ป๊ฒŒ, ์–ด๋– ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๋‹น ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ํ• ๋‹นํ•ด ์ค„๊ฒƒ์ธ๊ฐ€? ๋ฐ”๋กœ , first -fit , next-fit , best-fit ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด ์ค„๊ฒƒ์ด๋‹ค.
  • ์œ„์˜ ๊ทธ๋ฆผ์œผ๋กœ ์„ค๋ช…ํ•˜์ž๋ฉด 16M์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌ๋˜๋ ค๊ณ ํ•œ๋‹ค.
  • first-fit(์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ํƒ์ƒ‰ํ•˜์—ฌ ์š”์ฒญ๋œ ํฌ๊ธฐ์™€ ๊ฐ€์žฅ ๊ทผ์ ‘ํ•œ, ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ค„๊ฒƒ์ด๋‹ค)
    • ->๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ ์ฒซ ๋ถ€๋ถ„์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž, ๊ทธ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์—ด์„ ํƒ์ƒ‰ํ•˜๋“ฏ์ด ํƒ์ƒ‰ํ•  ๊ฒƒ์ด๋‹ค. ์ฒซ ๊ฐ€์šฉ ๋ธ”๋ก์€ 8M์œผ๋กœ ๋‹ค์Œ์„ ํƒ์ƒ‰ํ•˜๊ณ , ๊ทธ๋‹ค์Œ์€ 12M , ๋˜ ๋‹ค์Œ์„ ํƒ์ƒ‰ํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ 22M์€ ์ถฉ๋ถ„ํžˆ 16M์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ 22M์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ํ• ๋‹นํ•ด์ค„๊ฒƒ์ด๋‹ค.
  • next - fit(๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ๋“ค์–ด๊ฐ„ ๊ณต๊ฐ„์œผ๋กœ๋ถ€ํ„ฐ ๊ฐ€์žฅ ์ ํ•ฉํ•œ๊ณณ์„ ์ค„๊ฒƒ์ด๋‹ค.)
    • ->์Šคํƒ์ฒ˜๋Ÿผ, ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ๋“ค์–ด๊ฐ„ ๊ณต๊ฐ„์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ๊ทธ ์˜์—ญ๋ถ€ํ„ฐ ํƒ์ƒ‰์„ ์‹œ์ž‘ํ•˜์—ฌ ๊ณต๊ฐ„์„ ์ฐพ๋Š”๊ฒƒ์ด๋‹ค. ํฌ์ธํ„ฐ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋ฉด์„œ ๊ฒฐ๊ตญ ์ฐพ์€ ๊ณณ์€ 36M์ด๋‹ค.
  • best-fit(์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ํƒ์ƒ‰ํ•˜์—ฌ ์š”์ฒญ๋œ ํฌ๊ธฐ์™€ ๊ฐ€์žฅ ๊ทผ์ ‘ํ•œ, ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ค„๊ฒƒ์ด๋‹ค.)
    • -> ์™ผ์ชฝ์—์„œ ๋ณด๋ฉด ํ˜„์žฌ 18M์ด ๊ฐ€์žฅ 16M๊ณผ ๊ฐ€๊น๊ณ  ๊ทผ์ ‘ํ•˜๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ 18M์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์ค„๊ฒƒ์ด๋‹ค.

๐Ÿ’ก1. Fist fit

  • first fit : ์ฒ˜์Œ๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•˜๊ณ  ํฌ๊ธฐ๊ฐ€ ๋งž๋Š” ์ฒซ ๊ฐ€์šฉ ๋ธ”๋ก์„ ์„ ํƒ
  • ์žฅ์  : ๋งค์šฐ ๋น ๋ฅธ ํƒ์ƒ‰ ์†๋„ , ์ฒ˜์Œ ์œผ๋กœ ์ถฉ๋ถ„ํ•œ ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์„ ์ฐพ์•„ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ• ๋‹นํ•˜๋ฏ€๋กœ ๊ฒ€์ƒ‰ ์‹œ๊ฐ„์ด ๋งค์šฐ ์งง๋‹ค.
  • ๋‹จ์  : ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ํ• ๋‹น๋ฐ›์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ
    • ์˜ˆ์‹œ)
Input : blockSize[]   = {100, 500, 200, 300, 600};
        processSize[] = {212, 417, 112, 426};
Output:
Process No.    Process Size    Block no.
   1               212            2
   2               417            5
   3               112            2
   4               426        Not Allocated
  • ๋งˆ์ง€๋ง‰์œผ๋กœ ํ”„๋กœ์„ธ์Šค 4๋ฅผ ํ• ๋‹นํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ, ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก์ค‘์—๋Š” 300 ํฌ๊ธฐ์˜ ๋ธ”๋ก์ด ๊ฐ€์žฅ ํฐ๊ฒƒ์ด๊ณ , ์ด๋Š” 426์˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ˆ˜์šฉํ•  ์ˆ˜์—†์–ด ํ• ๋‹น๋˜์ง€ ์•Š๋Š”๋‹ค.

 

๐Ÿ’ก๊ตฌํ˜„ ๋‹จ๊ณ„

  1. ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก ํฌ๊ธฐ์™€ ํ”„๋กœ์„ธ์Šค ํฌ๊ธฐ๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.
    • ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก ํฌ๊ธฐ: ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์˜ ํฌ๊ธฐ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฌผ๋ฆฌ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ์˜ ํฌ๊ธฐ ๋˜๋Š” ํŒŒํ‹ฐ์…˜ ํฌ๊ธฐ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ํ”„๋กœ์„ธ์Šค ํฌ๊ธฐ: ํ• ๋‹นํ•˜๋ ค๋Š” ํ”„๋กœ์„ธ์Šค์˜ ํฌ๊ธฐ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  2. ๋ชจ๋“  ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์„ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ ๋นˆ ์ƒํƒœ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๋‹จ๊ณ„์—์„œ๋Š” ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ , ์ด ๋ธ”๋ก๋“ค์€ ์ดˆ๊ธฐ ์ƒํƒœ์—์„œ๋Š” ์•„๋ฌด๋Ÿฐ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ• ๋‹น๋˜์ง€ ์•Š์€ ์ƒํƒœ(๋นˆ ์ƒํƒœ)๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
  3. ๊ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์„ ํƒํ•˜๊ณ  ํ˜„์žฌ ๋ธ”๋ก์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๋‹จ๊ณ„์—์„œ๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ํ•˜๋‚˜์”ฉ ์„ ํƒํ•˜๊ณ , ํ˜„์žฌ ๊ฒ€์‚ฌ ์ค‘์ธ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  4. ๋งŒ์•ฝ ํ”„๋กœ์„ธ์Šค ํฌ๊ธฐ๊ฐ€ ํ˜„์žฌ ๋ธ”๋ก ํฌ๊ธฐ๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์œผ๋ฉด ํ•ด๋‹น ๋ธ”๋ก์— ํ• ๋‹นํ•˜๊ณ  ๋‹ค์Œ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ™•์ธ
    • ํ˜„์žฌ ๊ฒ€์‚ฌ์ค‘์ธ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์˜ ํฌ๊ธฐ๊ฐ€ ์„ ํƒํ•œ ํ”„๋กœ์„ธ์Šค์˜ ํฌ๊ธฐ์™€ ๊ฐ™๊ฑฐ๋‚˜ ํฌ๋ฉด, ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค๋ฅผ ํ˜„์žฌ ๋ธ”๋ก์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋‹ค์Œ ๋‹ค์Œ ๋‹ค์Œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์„ ํƒํ•˜์—ฌ ํ• ๋‹น ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก์„ ์ฐพ์•„๊ฐ‘๋‹ˆ๋‹ค.
  5. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‹ค์Œ ๋ธ”๋ก์„ ํ™•์ธํ•˜๊ณ , ์ด ๊ณผ์ •์„ ๋ฐ˜๋ณต
    • ํ˜„์žฌ ๋ธ”๋ก์˜ ํฌ๊ธฐ๊ฐ€ ์„ ํƒํ•œ ํ”„๋กœ์„ธ์Šค์˜ ํฌ๊ธฐ๋ณด๋‹ค ์ž‘์œผ๋ฉด ๋‹ค์Œ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์œผ๋กœ ์ด๋™ํ•˜์—ฌ ํ• ๋‹น ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก์„ ์ฐพ๋Š”๋‹ค. ์ด๋Ÿฌํ•œ ๊ณผ์ •์„ ๋ชจ๋“  ๋ธ”๋ก์— ๋Œ€ํ•ด ๋ฐ˜๋ณต

๐Ÿ’กfirst-fit

#include<stdio.h>

// First-Fit ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋”ฐ๋ผ ๋ธ”๋ก์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๋Š” ํ•จ์ˆ˜
void firstFit(int blockSize[], int m, int processSize[], int n)
{
	int i, j;
	// ๊ฐ ํ”„๋กœ์„ธ์Šค์— ํ• ๋‹น๋œ ๋ธ”๋ก ID๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฐ์—ด
	int allocation[n];

	// ์ดˆ๊ธฐ์—๋Š” ์–ด๋–ค ๋ธ”๋ก๋„ ์–ด๋–ค ํ”„๋กœ์„ธ์Šค์— ํ• ๋‹น๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
	for(i = 0; i < n; i++)
	{
		allocation[i] = -1;
	}

	// ๊ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์„ ํƒํ•˜๊ณ  ์ ์ ˆํ•œ ๋ธ”๋ก์„ ์ฐพ์•„ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค
	for (i = 0; i < n; i++)	 // ์—ฌ๊ธฐ์„œ n์€ ํ”„๋กœ์„ธ์Šค์˜ ์ˆ˜์ž…๋‹ˆ๋‹ค
	{
		for (j = 0; j < m; j++)	 // ์—ฌ๊ธฐ์„œ m์€ ๋ธ”๋ก์˜ ์ˆ˜์ž…๋‹ˆ๋‹ค
		{
			if (blockSize[j] >= processSize[i])
			{
				// ๋ธ”๋ก j๋ฅผ i๋ฒˆ์งธ ํ”„๋กœ์„ธ์Šค์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค
				allocation[i] = j;

				// ์ด ๋ธ”๋ก์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ์†Œ์‹œํ‚ต๋‹ˆ๋‹ค.
				blockSize[j] -= processSize[i];

				break; // ๋‹ค์Œ ํ”„๋กœ์„ธ์Šค๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
			}
		}
	}

	printf("\nํ”„๋กœ์„ธ์Šค ๋ฒˆํ˜ธ\tํ”„๋กœ์„ธ์Šค ํฌ๊ธฐ\t๋ธ”๋ก ๋ฒˆํ˜ธ\n");
	for (int i = 0; i < n; i++)
	{
		printf(" %i\t\t\t", i+1); // ํ”„๋กœ์„ธ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
		printf("%i\t\t\t\t", processSize[i]); // ํ”„๋กœ์„ธ์Šค ํฌ๊ธฐ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
		if (allocation[i] != -1)
			printf("%i", allocation[i] + 1); // ํ• ๋‹น๋œ ๋ธ”๋ก ๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
		else
			printf("ํ• ๋‹น๋˜์ง€ ์•Š์Œ"); // ํ• ๋‹น๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
		printf("\n");
	}
}

// ๋ฉ”์ธ ํ•จ์ˆ˜
int main()
{
	int m; // ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์˜ ์ˆ˜
	int n; // ์ž…๋ ฅ ํ์— ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค์˜ ์ˆ˜
	int blockSize[] = {100, 500, 200, 300, 600}; // ๊ฐ ๋ธ”๋ก์˜ ํฌ๊ธฐ
	int processSize[] = {212, 417, 112, 426}; // ๊ฐ ํ”„๋กœ์„ธ์Šค์˜ ํฌ๊ธฐ
	m = sizeof(blockSize) / sizeof(blockSize[0]); // ๋ธ”๋ก ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
	n = sizeof(processSize) / sizeof(processSize[0]); // ํ”„๋กœ์„ธ์Šค ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

	firstFit(blockSize, m, processSize, n); // First-Fit ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

	return 0;
}
  • ๊ฒฐ๊ณผ


 

๐Ÿ“Œfree ๋ธ”๋ก ์ฐพ๋Š” ๋ฐฉ๋ฒ• ( fisrt fit)

p = start;

while ((p < end) && ((*p & 1) || (*p <= len))) {
    p = p + (*p & -2);
}
  • p์˜ ์ฃผ์†Œ ๊ฐ’์ด, heap์˜ ๋งจ ๋ ์ฃผ์†Œ ๋ณด๋‹ค ์ž‘์„ ๋•Œ๋งŒ ๋ฐ˜๋ณตํ•ด์„œ ์ฐพ๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  p๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ’์˜ ๋งจ ๋์˜ ๋น„ํŠธ๊ฐ€ 1์ด๋ฉด ํ• ๋‹น๋˜์–ด ์žˆ๋‹ค๋Š” ๋œป์ด๋‹ˆ ๋„˜์–ด๊ฐ„๋‹ค. ๋˜ํ•œ ์šฐ๋ฆฌ๊ฐ€ ํ• ๋‹นํ•˜๋ ค๋Š” ์‚ฌ์ด์ฆˆ ๋ณด๋‹ค, p๊ฐ€ ๊ฐ€๋ฅดํ‚ค๋Š” ๋ธ”๋ก์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ ์ž‘์œผ๋ฉด ํ• ๋‹นํ•  ์ˆ˜ ์—†์œผ๋‹ˆ ์ด ๋˜ํ•œ ๋„˜์–ด๊ฐ„๋‹ค.
p = p + (*p & -2);
  • 2๋Š” 11111110์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ &๋ผ๋Š” ๋น„ํŠธ ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด p์˜ ์‚ฌ์ด์ฆˆ๋งŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๋งจ ๋งˆ์ง€๋ง‰์€ allocated, free๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” flag์ด๋ฏ€๋กœ ์ด์™€ ์ƒ๊ด€์—†์ด ์‚ฌ์ด์ฆˆ๋งŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
  • next fit : ์ด์ „ ํƒ์ƒ‰์ด ๋๋‚œ ์ง€์ ์œผ๋กœ๋ถ€ํ„ฐ free ๋ฆฌ์ŠคํŠธ๋ฅผ ํƒ์ƒ‰ํ•œ๋‹ค.
  • best fit : ์ฒ˜์Œ๋ถ€ํ„ฐ ์ „๋ถ€ ๊ฒ€์ƒ‰ํ•˜์—ฌ ํฌ๊ธฐ๊ฐ€ ๋”ฑ ๋งž๋Š” ๋ธ”๋ก์„ ์ถ”๋ ค๋‚ธ๋‹ค. first fit๋ณด๋‹ค ๋Š๋ฆด ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ“Œfree ๋ธ”๋ก์— ํ• ๋‹นํ•˜๊ธฐ

  • ์šฐ๋ฆฌ๊ฐ€ ํ• ๋‹นํ•˜๊ณ ์ž ํ•˜๋Š” ๋ธ”๋ก์˜ ํฌ๊ธฐ๊ฐ€ free ๋ธ”๋ก์˜ ํฌ๊ธฐ๋ณด๋‹ค ์ž‘์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿด ๋•Œ๋Š” ๋‚ด๋ถ€ ๋‹จํŽธํ™”๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ๋‚จ์€ ๋ธ”๋ก์„ splitํ•˜๋Š”๊ฒŒ ํšจ์œจ์ ์ด๋‹ค.

void addblock (ptr p, int len) {
    int newsize = ((len + 1) >> 1) << 1;
    int oldsize = *p & -2;
    *p = newsize | 1;
    if (newsize < oldsize) {
        *(p + newsize) = oldsize - newsize;
    }
}
  • ํ• ๋‹น๋˜๋Š” ํฌ๊ธฐ์ธ newsize๋Š” ์ง์ˆ˜๊ฐ€ ๋˜๊ฒŒํ•œ๋‹ค. ํ™€์ˆ˜๊ฐ€ ๋“ค์–ด์˜ค๋ฉด +1์„ ํ•œ ํ›„ ์˜ค๋ฅธ์ชฝ์œผ๋กœ shiftํ•˜๊ณ  ๋‹ค์‹œ ์™ผ์ชฝ์œผ๋กœ shiftํ•˜๋ฉด ๋งจ ๋์ด 0์ด๋ฉด์„œ ํฌ๊ธฐ๋Š” ์ง์ˆ˜๊ฐ€ ๋œ๋‹ค. ์›๋ž˜ ์‚ฌ์ด์ฆˆ๋ฅผ oldsize๋กœ ์ฝ์–ด์ฃผ๊ณ  p๊ฐ€ ๊ฐ€๋ฅดํ‚ค๋Š” ๊ณณ์—๋Š” newsize๋ฅผ ๋„ฃ์Œ๊ณผ ๋™์‹œ์— 1์„ ๋”ํ•˜์—ฌ allocated์ž„์„ ํ‘œ์‹œํ•œ๋‹ค. ์ด ๋–„ ๋งŒ์•ฝ ์›๋ž˜ ๋ธ”๋ก์˜ ํฌ๊ธฐ๊ฐ€ ๋” ์ปธ๋‹ค๋ฉด, p์— newsize๋งŒํผ ๋”ํ•œ ๊ณณ์˜ ํ—ค๋”์—๋Š” ํ• ๋‹นํ•˜๊ณ  ๋‚จ์€ ๋ธ”๋ก์˜ ํฌ๊ธฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ฒŒ ํ•œ๋‹ค. ์ด๋•Œ newsisze์™€ oldsize ๋ชจ๋‘ ๋งจ ๋๋น„ํŠธ๋Š” 0์ด๋ฏ€๋กœ ๋‘˜์ด ๋นผ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค.

 

๐Ÿ“Œํ• ๋‹น๋œ ๋ธ”๋ก free์‹œํ‚ค๊ธฐ

void free_block(ptr p) {
	*p = *p & - 2;
}
  • free์‹œํ‚ค๋Š” ๊ฒƒ์€, ๋‹จ์ˆœํžˆ ๋งจ ๋ flag ๋น„ํŠธ๋ฅผ 0์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๋ฉด ๋œ๋‹ค. ๋ธ”๋ก์— ํ• ๋‹น๋œ ๋ฐ์ดํ„ฐ๋Š” ์ง€์›Œ์ง€๋Š” ๋ฐฉ์‹์ด ์•„๋‹ˆ๋ผ ๋ฎ์–ด์”Œ์›Œ ์ง€๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ๋งŒ ํ•ด์ฃผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด 5๋ฅผ ํ• ๋‹นํ•  ๋•Œ ์™ธ๋ถ€ ๋‹จํŽธํ™”๋กœ ์ธํ•ด ํ• ๋‹นํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ free๋ผ๋ฆฌ ์ด์–ด์ ธ ์žˆ๋‹ค๋ฉด ์—ฐ๊ฒฐ ์‹œ์ผœ์ค˜์•ผ ํ•œ๋‹ค.

 

๐Ÿ“Œ์—ฐ๊ฒฐ

void free_block(ptr p) {
    *p = *p & -2;               // ๊ธฐ์กด ๋ธ”๋ก์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. *p = 0000 0101(allocated) -> 0000 0100(free), p = 0000 1000์ด๋ผ๊ณ  ๊ฐ€์ •ํ•œ๋‹ค๋ฉด,
    next = p + *p;              // ๋‹ค์Œ ๋ธ”๋ก์€ ๊ธฐ์กด ๋ธ”๋ก์— ๊ทธ ํฌ๊ธฐ๋ฅผ ๋”ํ•œ ๊ฐ’์ด ๋œ๋‹ค. next = 0000 1100
    if ((*next & 1) == 0) {     // ๋งŒ์•ฝ ๋‹ค์Œ ๋ธ”๋ก์ด free ๋ธ”๋ก์ด๋ผ๋ฉด, ex. *next = 0000 0010
        *p = *p + *next;        // ๋ธ”๋ก์˜ ํฌ๊ธฐ๋ฅผ ๋Š˜๋ฆฐ๋‹ค. ์ด ๋•Œ *p, ์ฆ‰ ํฌ์ธํ„ฐ๊ฐ€ ๊ฐ€๋ฅดํ‚ค๋Š” ๊ฐ’์€ ํ—ค๋”์ด๋‹ค.
    }                           // *p๋Š” 0000 0110์œผ๋กœ ํฌ๊ธฐ๊ฐ€ 4์—์„œ 6์œผ๋กœ ๋œ๋‹ค.
}
  • ๋‹จ์ˆœํžˆ free๋งŒ ์‹œํ‚ค๋Š” ์ฝ”๋“œ์—์„œ ์—ฐ๊ฒฐ๊นŒ์ง€ ํ•ด์ฃผ๋Š” ๊ฒƒ
  • flag๋ฅผ 0 ์œผ๋กœ ๋งŒ๋“ค์–ด์ค€ ํ›„, next๋Š” ํ˜„์žฌ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ์— ์‚ฌ์ด์ฆˆ๋ฅผ ๋”ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. ์ด ๋–„ ์ด next์˜ flag๊ฐ€ 0์ด๋ผ๋ฉด free ๋ธ”๋ก์ž„์„ ๋‚˜ํƒ€๋‚ด๋ฏ€๋กœ ํฌ์ธํ„ฐ๊ฐ€ ๊ฐ€๋ฅดํ‚ค๋Š” header์— ํ˜„์žฌ ๋ธ”๋ก ์‚ฌ์ด์ฆˆ์™€ next ๋ธ”๋ก์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ๋”ํ•ด์ค€๋‹ค. ์ด ๋•Œ ๋‘˜๋‹ค flag๋Š” 0์ด๋ฏ€๋กœ ๊ทธ์ € ๋”ํ•ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด๋œ๋‹ค.
  • ์œ„๋Š” ๋‹ค์Œ ๋ธ”๋ก์ด free์ผ ๋•Œ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ด์ „ ๋ธ”๋ก์ด free๋ผ๋ฉด ์–ด๋–ป๊ฒŒ ์—ฐ๊ฒฐํ• ๊นŒ?

 

๐Ÿ“Œ๊ฒฝ๊ณ„ํƒœ๊ทธ๋กœ ์—ฐ๊ฒฐํ•˜๊ธฐ

  • ํ—ค๋”๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ, ๋ธ”๋ก์˜ ๋์— ์œ„์น˜์‹œํ‚ค๋„๋กํ•œ๋‹ค. ์ด๋ฅผ footer ํ˜น์€ ๊ฒฝ๊ณ„ ํƒœ๊ทธ๋ผ๊ณ  ์นญํ•œ๋‹ค. ์ด๋Š” free ๋ฆฌ์ŠคํŠธ๋ฅผ ํƒ์ƒ‰ํ•  ๋•Œ ๋’ค๋กœ ๊ฐ€๋Š” ๊ฒƒ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์•ž์œผ๋กœ๋„ ๊ฐˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์ง€๋งŒ, ๊ณต๊ฐ„์„ ์ถ”๊ฐ€์ ์œผ๋กœ ์š”๊ตฌํ•œ๋‹ค.

  • ํ—ค๋”์—์„œ ํ•œ ์นธ๋งŒ ์•ž์œผ๋กœ ๊ฐ€๋ฉด ์ด์ „ ๋ธ”๋ก์ด ํ• ๋‹น ์ƒํƒœ์ธ์ง€, free์ƒํƒœ์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒ์ˆ˜์‹œ๊ฐ„, constant time์œผ๋กœ ์—ฐ๊ฒฐ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.  ๋”ฐ๋ผ์„œ free ๋ธ”๋ก์„ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐ์— ๋ฐœ์ƒ ํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(1)์ด ๋œ๋‹ค.

 

๐Ÿ“Œ๊ฒฝ๊ณ„ํƒœ๊ทธ์—ฐ๊ฒฐ์ด 4๊ฐ€์ง€์ธ ๊ฒฝ์šฐ

 

 

๐Ÿ“Œ๊ฒฝ๊ณ„ํƒœ๊ทธ๋‹จ์ ๊ณผ ๊ฐœ์„  ๋ฐฉ์•ˆ

  • ๋‹จ์  : ๊ฒฐ๊ตญ header์™€ footer๋ผ๋Š” ๊ฐœ๋…์„ ์‚ฌ์šฉํ•˜๋ฉด ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ๊ณ„์† ํ•„์š”๋กœ ํ•˜๋Š” ์…ˆ์ด๋‹ˆ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
    * ์˜ค๋ฒ„ํ—ค๋“œ : ์–ด๋–ค ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ฐ„์ ‘์ ์ธ ์‹œ๊ฐ„ or ๋ฉ”๋ชจ๋ฆฌ๋กœ, header์™€ footer๋ผ๋Š” ๊ฐœ๋…์„ ๋„์ž…ํ•˜๋ฉด์„œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๊ฒŒ ๋˜๋‹ˆ ์ „์ฒด์ ์œผ๋กœ ํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์ด ๋” ๋Š˜์–ด๋‚˜๊ฒŒ ๋œ๋‹ค.
  • ๊ฐœ์„  ๋ฐฉ์•ˆ : ์ด์ „ ํ˜น์€ ์ดํ›„ ๋ธ”๋ก์ด ํ• ๋‹น๋œ๋‹ค๋ฉด, ์ฆ‰ ํ• ๋‹น๋œ ๋ธ”๋ก์ด ๋˜๋ฒ„๋ฆฐ๋‹ค๋ฉด footer๋ฅผ ์—†์• ๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. case๋“ค์„ ์‚ดํŽด๋ณด๋ฉด ํ• ๋‹น๋œ ๋ธ”๋ก๋“ค์˜ footer๋“ค์€, ์—ฐ๊ฒฐ๋œ ๋ธ”๋ก์˜ header์™€ footer์— ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์„ ๋ผ์น˜๊ณ  ์žˆ์ง€ ์•Š๋‹ค. ๋”ฐ๋ผ์„œ ํ• ๋‹น๋œ ๋ธ”๋ก์—์„œ๋Š” footer๊ฐ€ ํ•„์š”์น˜ ์•Š๋‹ค.
  • ๊ทธ๋ ‡๋‹ค๋ฉด, ํ•ด๋‹น ๋ธ”๋ก์€ ์–ด๋–ป๊ฒŒ ์ด์ „์˜ ๋ธ”๋ก์ด ํ• ๋‹น๋˜์—ˆ๋Š”์ง€ ํ˜น์€ free์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ? ํ•ด๋‹น ๋ธ”๋ก์—์„œ ํ—ค๋”์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋น„ํŠธ์ธ 3๊ฐœ์˜ ๋น„ํŠธ ์ค‘ 1๊ฐœ์— ์ด์ „์˜ ๋ธ”๋ก ํ• ๋‹น ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋ฉด ๋œ๋‹ค. ์ด๋Ÿฌ๋ฉด ์•ž์˜ ๋ธ”๋ก์ด ํ• ๋‹น๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ, ํ˜„์žฌ ํ•ด๋‹น ๋ธ”๋ก์˜ 3๊ฐœ ๋น„ํŠธ ์ค‘ 1๊ฐœ์˜ ๋น„ํŠธ๋Š” ์ด์ „ ๋ธ”๋ก์ด ํ• ๋‹น๋˜์—ˆ๋‹ค๊ณ  ์•Œ๋ ค์ฃผ๋ฏ€๋กœ ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

๐Ÿ“Œfirst-fit

/*
 * mm-naive.c - The fastest, least memory-efficient malloc package.
 * 
 * In this naive approach, a block is allocated by simply incrementing
 * the brk pointer.  A block is pure payload. There are no headers or
 * footers.  Blocks are never coalesced or reused. Realloc is
 * implemented directly using mm_malloc and mm_free.
 *
 * NOTE TO STUDENTS: Replace this header comment with your own header
 * comment that gives a high level description of your solution.
 */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>

#include "mm.h"
#include "memlib.h"

/*********************************************************
 * NOTE TO STUDENTS: Before you do anything else, please
 * provide your team information in the following struct.
 ********************************************************/
team_t team = {
    /* Team name */
    "week5",
    /* First member's full name */
    "janghotoung",
    /* First member's email address */
    "ghdud4653@gmail.com",
    /* Second member's full name (leave blank if none) */
    "",
    /* Second member's email address (leave blank if none) */
    ""
};

/* ๋ฉ”ํฌ๋กœ */
#define WSIZE 4
#define DSIZE 8
#define CHUNKSIZE (1<<12)

#define MAX(x, y) ((x) > (y)? (x) : (y))

/* ํฌ๊ธฐ์™€ ํ• ๋‹น ๋น„ํŠธ๋ฅผ ํ†ตํ•ฉํ•ด์„œ ํ—ค๋”์™€ ํ’‹ํ„ฐ์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ return */
#define PACK(size, alloc) ((size) | (alloc))

/* ์ธ์ž p๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์›Œ๋“œ ์ฝ์–ด์„œ return */
/* ์ธ์ž p๋Š” ๋Œ€๊ฐœ (void*) ํฌ์ธํ„ฐ. ์ง์ ‘์ ์œผ๋กœ ์—ญ์ฐธ์กฐ ๋ถˆ๊ฐ€ */ 
#define GET(p) (*(unsigned int *)(p))
/* ์ธ์ž p๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์›Œ๋“œ์— val ์ €์žฅ */
#define PUT(p, val) (*(unsigned int *)(p) = (val))

/* ๊ฐ๊ฐ ์ฃผ์†Œ p์— ์žˆ๋Š” ํ—ค๋”, ํ’‹ํ„ฐ์˜ size์™€ ํ• ๋‹น ๋น„ํŠธ๋ฅผ return */
#define GET_SIZE(p) (GET(p) & ~0x7)
#define GET_ALLOC(p) (GET(p) & 0x1)

/* ๋ธ”๋ก ํฌ์ธํ„ฐ bp๊ฐ€ ์ฃผ์–ด์ง€๋ฉด, ๊ฐ๊ฐ ๋ธ”๋ก ํ—ค๋”์™€ ํ’‹ํ„ฐ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ return */
#define HDRP(bp) ((char *)(bp) - WSIZE)
#define FTRP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE)

/* ๋ธ”๋ก ํฌ์ธํ„ฐ bp๊ฐ€ ์ฃผ์–ด์ง€๋ฉด, ๊ฐ๊ฐ ๋‹ค์Œ๊ณผ ์ด์ „ ๋ธ”๋ก์˜ ๋ธ”๋ก ํฌ์ธํ„ฐ๋ฅผ return */
#define NEXT_BLKP(bp) ((char *)(bp) + GET_SIZE(((char *)(bp) - WSIZE)))
#define PREV_BLKP(bp) ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE)))

/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (DSIZE-1)) & ~0x7)

#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))

/* ํ•จ์ˆ˜ ์„ ์–ธ */
static void *extend_heap(size_t);
static void *coalesce(void *);

/* ์ „์—ญ ๋ณ€์ˆ˜ */
static char *heap_listp;

/* 
 * mm_init - ํ• ๋‹น๊ธฐ ์ดˆ๊ธฐํ™” 
 */
int mm_init(void)
{   
    /* ๋ฉ”๋ชจ๋ฆฌ ์‹œ์Šคํ…œ์—์„œ 4์›Œ๋“œ ๊ฐ€์ ธ์™€ ๋นˆ ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ์ดˆ๊ธฐํ™” */
    if ((heap_listp = mem_sbrk(4*WSIZE)) == (void *)-1)
    return -1;
    PUT(heap_listp, 0);                          /* Alignment padding */
    PUT(heap_listp + (1*WSIZE), PACK(DSIZE, 1)); /* Prologue header */
    PUT(heap_listp + (2*WSIZE), PACK(DSIZE, 1)); /* Prologue footer */
    PUT(heap_listp + (3*WSIZE), PACK(0, 1));     /* Epilogue header */
    heap_listp += (2*WSIZE);

    /* heap์„ CHUNKSIZE ๋ฐ”์ดํŠธ๋กœ ํ™•์žฅ ํ›„ ์ดˆ๊ธฐ ๊ฐ€์šฉ ๋ธ”๋ก ์ƒ์„ฑ */
    if (extend_heap(CHUNKSIZE/WSIZE) == NULL) 
        return -1;
    return 0;
}

/*
 * coalesc - ๊ฐ€์šฉ ๋ธ”๋Ÿญ ์ƒ์„ฑ์‹œ ํ†ตํ•ฉ 
 */
static void *coalesce(void *bp)
{
    size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
    size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
    size_t size = GET_SIZE(HDRP(bp));

    if (prev_alloc && next_alloc){        /* Case 1 */
        return bp;
    }

    else if (prev_alloc && !next_alloc){   /* Case 2 */
        size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
        PUT(HDRP(bp), PACK(size, 0));
        PUT(FTRP(bp), PACK(size, 0));
    }
    else if (!prev_alloc && next_alloc){   /* Case 3 */
        size += GET_SIZE(HDRP(PREV_BLKP(bp)));
        PUT(FTRP(bp), PACK(size, 0));
        PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
        bp = PREV_BLKP(bp);
    }
    else{                                   /* Case 4 */
        size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp)));
        PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
        PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
        bp = PREV_BLKP(bp);
    }
    return bp;
}

/* 
 * expend_heap - malloc package ์ดˆ๊ธฐํ™”
 *               1. ํž™ ์ดˆ๊ธฐํ™”์‹œ
 *               2. mm_malloc์ด ์ ๋‹นํ•œ fit์„ ๋ชป์ฐพ์•˜์„ ๋•Œ, ์ •๋ ฌ ์œ ์ง€ ์œ„ํ•ด ํ˜ธ์ถœ
 */
static void *extend_heap(size_t words)
{
    char *bp;
    size_t size;

    /* ์ •๋ ฌ ์œ ์ง€ ์œ„ํ•ด ์ง์ˆ˜ word ํ• ๋‹น */
    size = (words % 2) ? (words+1) * WSIZE : words * WSIZE;
    if ((long)(bp = mem_sbrk(size)) == -1)
    return NULL;

    /* ๊ฐ€์šฉ ๋ธ”๋Ÿญ์˜ ํ—ค๋”, ํ‘ธํ„ฐ ์™€ epilogue ํ—ค๋” ์ดˆ๊ธฐํ™” */
    PUT(HDRP(bp), PACK(size, 0));         /* Free block ํ—ค๋” */
    PUT(FTRP(bp), PACK(size, 0));         /* Free block ํ‘ธํ„ฐ */
    PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue ํ—ค๋” */

    /* ์ด์ „ ๋ธ”๋ก์ด ๊ฐ€์šฉ๋ฌ์„ ๋•Œ ํ†ตํ•ฉ */
    return coalesce(bp);
}

/* first-fit ๊ฒ€์ƒ‰ */
static void *find_fit(size_t asize)
{
    void *bp;

    for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp))
    {
        if (!GET_ALLOC(HDRP(bp)) && (asize <= GET_SIZE(HDRP(bp)))){
            return bp;
        }
    }
    /* No fit */
    return NULL;    
}

/* 
 * place - ๋งž๋Š” ๋ธ”๋ก ์ฐพ์œผ๋ฉด ํ• ๋‹น๊ธฐ๋Š” ์š”์ฒญํ•œ ๋ธ”๋ก์„ ๋ฐฐ์น˜, ์˜ต์…˜์œผ๋กœ ์ถ”๊ฐ€ ๋ถ€๋ถ„ ๋ถ„ํ• 
 */
static void place(void *bp, size_t asize)
{
    size_t csize = GET_SIZE(HDRP(bp));

    if ((csize - asize) >= (2 * DSIZE))
    {
        PUT(HDRP(bp), PACK(asize, 1));
        PUT(FTRP(bp), PACK(asize, 1));
        bp = NEXT_BLKP(bp);
        PUT(HDRP(bp), PACK(csize - asize, 0));
        PUT(FTRP(bp), PACK(csize - asize, 0));
    }
    else
    {
        PUT(HDRP(bp), PACK(csize, 1));
        PUT(FTRP(bp), PACK(csize, 1));
    }
}

/* 
 * mm_malloc - size ๋ฐ”์ดํŠธ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก ์š”์ฒญ
 *             brk pointer๋ฅผ ์ฆ๊ฐ€์‹œ์ผœ ๋ธ”๋ก ํ• ๋‹น        
 */
void *mm_malloc(size_t size)
{
    size_t asize;        /* ์กฐ์ •๋œ ๋ธ”๋ก ํฌ๊ธฐ */
    size_t extendsize;   /* ์ ํ•ฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ํž™์„ ํ™•์žฅํ•  ํฌ๊ธฐ */
    char *bp;

    /* ๊ฑฐ์ง“ ์š”์ฒญ์‹œ */
    if (size == 0)
        return NULL;

    /* ํ—ค๋”์™€ ํ’‹ํ„ฐ ์œ„ํ•œ ๊ณต๊ฐ„ ํ™•๋ณด ๋ฐ ๋”๋ธ” ์›Œ๋“œ ์š”๊ฑด ๋งŒ์กฑ์‹œํ‚ด */
    if (size <= DSIZE)
        asize = 2*DSIZE;
    else /* 8๋ฐ”์ดํŠธ ๋„˜๋Š” ์š”์ฒญ์— ๋Œ€ํ•ด ์˜ค๋ฒ„ํ—ค๋“œ ๋ฐ”์ดํŠธ ์ถ”๊ฐ€, ์ธ์ ‘ 8์˜ ๋ฐฐ์ˆ˜๋กœ ๋ฐ˜์˜ฌ๋ฆผ */
        asize = DSIZE * ((size + (DSIZE) + (DSIZE-1)) / DSIZE);
    
    /* ์ ์ ˆํ•œ ๊ฐ€์šฉ ๋ธ”๋ก์„ ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ์—์„œ ๊ฒ€์ƒ‰ */
    if ((bp = find_fit(asize)) != NULL){
        /* ๋งž๋Š” ๋ธ”๋ก ์ฐพ์œผ๋ฉด ํ• ๋‹น๊ธฐ๋Š” ์š”์ฒญํ•œ ๋ธ”๋ก์„ ๋ฐฐ์น˜, ์˜ต์…˜์œผ๋กœ ์ถ”๊ฐ€ ๋ถ€๋ถ„ ๋ถ„ํ•  */
        place(bp, asize);
        /* ์ƒˆ๋กœ ํ• ๋‹นํ•œ ๋ธ”๋ก์˜ ํฌ์ธํ„ฐ return */
        return bp;
    }

    /* ์ ์ ˆํ•œ ๊ฐ€์šฉ ๋ธ”๋ก์„ ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ์—์„œ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด, ํž™์„ ์ƒˆ๋กœ์šด ๊ฐ€์šฉ ๋ธ”๋ก์œผ๋กœ ํ™•์žฅ */
    extendsize = MAX(asize, CHUNKSIZE);
    if ((bp = extend_heap(extendsize/WSIZE)) == NULL)
        return NULL;
    /* ์š”์ฒญํ•œ ๋ธ”๋ก์„ ์ƒˆ ๊ฐ€์šฉ ๋ธ”๋ก์— ๋ฐฐ์น˜, ํ•„์š”์‹œ ๋ธ”๋ก์„ ๋ถ„ํ•  */
    place(bp, asize);
    /* ์ƒˆ๋กœ ํ• ๋‹นํ•œ ๋ธ”๋ก์˜ ํฌ์ธํ„ฐ return */
    return bp;
}

/*
 * mm_free - ์š”์ฒญํ•œ ๋ธ”๋ก ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฒฝ๊ณ„ ํƒœ๊ทธ ์—ฐ๊ฒฐ ์‚ฌ์šฉํ•ด ์ƒ์ˆ˜ ์‹œ๊ฐ„์— ์ธ์ ‘ ๊ฐ€์šฉ ๋ธ”๋ก๋“ค๊ณผ ํ†ตํ•ฉ
 */
void mm_free(void *bp)
{
    size_t size = GET_SIZE(HDRP(bp));

    PUT(HDRP(bp), PACK(size, 0));
    PUT(FTRP(bp), PACK(size, 0));
    /* ์ธ์ ‘ ๊ฐ€์šฉ ๋ธ”๋ก๋“ค ํ†ตํ•ฉ */
    coalesce(bp);
}


/*
 * mm_realloc - ๋™์  ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ ๋‚ด์šฉ ์œ ์ง€ํ•˜๋ฉฐ ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ ๋ณ€๊ฒฝ
 */
void *mm_realloc(void *bp, size_t size)
{

    if ((int)size == 0)
    {
        // mm_free(bp);
        return NULL;
    }
    else 
    if (size > 0)
    {
        size_t oldsize = GET_SIZE(HDRP(bp));
        size_t newsize = size + (2 * WSIZE); /* ํ—ค๋”์™€ ํ‘ธํ„ฐ ์œ„ํ•œ 2 words ์ถ”๊ฐ€ */ 
        /* newsize๊ฐ€ oldsize๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์œผ๋ฉด return bp */
        if (newsize <= oldsize)
        {
            return bp;
        }
        /* oldsize ๋ณด๋‹ค new size๊ฐ€ ํฌ๋ฉด ๋ฐ”๊ฟˆ */
        else
        {
            /* ๋‹ค์Œ ๋ธ”๋ก์˜ ํ• ๋‹น ์—ฌ๋ถ€ ๋น„ํŠธ */
            size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
            size_t csize;
            /* next block์ด ๊ฐ€์šฉ ์ƒํƒœ์ด๊ณ , old์™€ next block์˜ ์‚ฌ์ด์ฆˆ ํ•ฉ์ด new size๋ณด๋‹ค ํฌ๋ฉด ํ•ฉ์ณ์„œ ์‚ฌ์šฉ  */
            if (!next_alloc && ((csize = oldsize + GET_SIZE(HDRP(NEXT_BLKP(bp))))) >= newsize)
            {
                // remove_from_free_list(NEXT_BLK(bp));
                PUT(HDRP(bp), PACK(csize, 1));
                PUT(FTRP(bp), PACK(csize, 1));
                return bp;
            }
            /* next block์ด ํ• ๋‹น๋œ ์ƒํƒœ์ด๊ฑฐ๋‚˜, old์™€ next block์˜ ์‚ฌ์ด์ฆˆ ํ•ฉ์ด new size๋ณด๋‹ค ์ž‘์„ ๋•Œ ์ƒˆ block ์ƒ์„ฑ */
            else
            {
                void *new_ptr = mm_malloc(newsize);
                // place(new_ptr, newsize);
                memcpy(new_ptr, bp, newsize);
                mm_free(bp);
                return new_ptr;
            }
        }
    }
    else
        return NULL;
}

 

 

 

 

 

๐Ÿ“Œnext-fit

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>

#include "mm.h"
#include "memlib.h"

/*********************************************************
 * NOTE TO STUDENTS: Before you do anything else, please
 * provide your team information in the following struct.
 ********************************************************/
team_t team = {
    /* Team name */
    "week5",
    /* First member's full name */
    "janghoyoung",
    /* First member's email address */
    "ghdud4653@gmail.com",
    /* Second member's full name (leave blank if none) */
    "",
    /* Second member's email address (leave blank if none) */
    ""
};

/* ๋ฉ”ํฌ๋กœ */
#define WSIZE 4
#define DSIZE 8
#define CHUNKSIZE (1<<12)

#define MAX(x, y) ((x) > (y)? (x) : (y))

/* ํฌ๊ธฐ์™€ ํ• ๋‹น ๋น„ํŠธ๋ฅผ ํ†ตํ•ฉํ•ด์„œ ํ—ค๋”์™€ ํ’‹ํ„ฐ์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ return */
#define PACK(size, alloc) ((size) | (alloc))

/* ์ธ์ž p๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์›Œ๋“œ ์ฝ์–ด์„œ return */
/* ์ธ์ž p๋Š” ๋Œ€๊ฐœ (void*) ํฌ์ธํ„ฐ. ์ง์ ‘์ ์œผ๋กœ ์—ญ์ฐธ์กฐ ๋ถˆ๊ฐ€ */ 
#define GET(p) (*(unsigned int *)(p))
/* ์ธ์ž p๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์›Œ๋“œ์— val ์ €์žฅ */
#define PUT(p, val) (*(unsigned int *)(p) = (val))

/* ๊ฐ๊ฐ ์ฃผ์†Œ p์— ์žˆ๋Š” ํ—ค๋”, ํ’‹ํ„ฐ์˜ size์™€ ํ• ๋‹น ๋น„ํŠธ๋ฅผ return */
#define GET_SIZE(p) (GET(p) & ~0x7)
#define GET_ALLOC(p) (GET(p) & 0x1)

/* ๋ธ”๋ก ํฌ์ธํ„ฐ bp๊ฐ€ ์ฃผ์–ด์ง€๋ฉด, ๊ฐ๊ฐ ๋ธ”๋ก ํ—ค๋”์™€ ํ’‹ํ„ฐ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ return */
#define HDRP(bp) ((char *)(bp) - WSIZE)
#define FTRP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE)

/* ๋ธ”๋ก ํฌ์ธํ„ฐ bp๊ฐ€ ์ฃผ์–ด์ง€๋ฉด, ๊ฐ๊ฐ ๋‹ค์Œ๊ณผ ์ด์ „ ๋ธ”๋ก์˜ ๋ธ”๋ก ํฌ์ธํ„ฐ๋ฅผ return */
#define NEXT_BLKP(bp) ((char *)(bp) + GET_SIZE(((char *)(bp) - WSIZE)))
#define PREV_BLKP(bp) ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE)))

/* ์ •๋ ฌ ์œ ์ง€ ์œ„ํ•ด ๊ฐ€๊นŒ์šด ๋ฐฐ์ˆ˜๋กœ ๋ฐ˜์˜ฌ๋ฆผ */
#define ALIGN(size) (((size) + (DSIZE-1)) & ~0x7)

#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))

/* ํ•จ์ˆ˜ ์„ ์–ธ */
static void *extend_heap(size_t);
static void *coalesce(void *);
static void *find_fit(size_t);
static void place(void *, size_t);

/* ์ „์—ญ ๋ณ€์ˆ˜ */
static char *heap_listp;
static char *last_bp ; 

/* 
 * mm_init - ํ• ๋‹น๊ธฐ ์ดˆ๊ธฐํ™” 
 */
int mm_init(void)
{   
    /* ๋ฉ”๋ชจ๋ฆฌ ์‹œ์Šคํ…œ์—์„œ 4์›Œ๋“œ ๊ฐ€์ ธ์™€ ๋นˆ ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ์ดˆ๊ธฐํ™” */
    if ((heap_listp = mem_sbrk(4*WSIZE)) == (void *)-1)
    return -1;
    PUT(heap_listp, 0);                          /* Alignment padding */
    PUT(heap_listp + (1*WSIZE), PACK(DSIZE, 1)); /* Prologue header */
    PUT(heap_listp + (2*WSIZE), PACK(DSIZE, 1)); /* Prologue footer */
    PUT(heap_listp + (3*WSIZE), PACK(0, 1));     /* Epilogue footer */
    heap_listp += (2*WSIZE);

    /* heap์„ CHUNKSIZE ๋ฐ”์ดํŠธ๋กœ ํ™•์žฅ ํ›„ ์ดˆ๊ธฐ ๊ฐ€์šฉ ๋ธ”๋ก ์ƒ์„ฑ */
    if (extend_heap(CHUNKSIZE/WSIZE) == NULL) 
        return -1;
    last_bp = heap_listp; 
    return 0;
}

/*
 * coalesc - ๊ฐ€์šฉ ๋ธ”๋Ÿญ ์ƒ์„ฑ์‹œ ํ†ตํ•ฉ 
 */
static void *coalesce(void *bp)
{
    size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
    size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
    size_t size = GET_SIZE(HDRP(bp));

    if (prev_alloc && next_alloc){        /* Case 1 */
        last_bp = bp; 
        return bp;
    }

    else if (prev_alloc && !next_alloc){   /* Case 2 */
        size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
        PUT(HDRP(bp), PACK(size, 0));
        PUT(FTRP(bp), PACK(size, 0));
    }
    else if (!prev_alloc && next_alloc){   /* Case 3 */
        size += GET_SIZE(HDRP(PREV_BLKP(bp)));
        PUT(FTRP(bp), PACK(size, 0));
        PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
        bp = PREV_BLKP(bp);
    }
    else{                                   /* Case 4 */
        size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp)));
        PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
        PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
        bp = PREV_BLKP(bp);
    }
    last_bp = bp; 
    return bp;
}

/* 
 * expend_heap - malloc package ์ดˆ๊ธฐํ™”
 *               1. ํž™ ์ดˆ๊ธฐํ™”์‹œ
 *               2. mm_malloc์ด ์ ๋‹นํ•œ fit์„ ๋ชป์ฐพ์•˜์„ ๋•Œ, ์ •๋ ฌ ์œ ์ง€ ์œ„ํ•ด ํ˜ธ์ถœ
 */
static void *extend_heap(size_t words)
{
    char *bp;
    size_t size;

    /* ์ •๋ ฌ ์œ ์ง€ ์œ„ํ•ด ์ง์ˆ˜ word ํ• ๋‹น */
    size = (words % 2) ? (words+1) * WSIZE : words * WSIZE;
    if ((long)(bp = mem_sbrk(size)) == -1)
    return NULL;

    /* ๊ฐ€์šฉ ๋ธ”๋Ÿญ์˜ ํ—ค๋”, ํ‘ธํ„ฐ ์™€ epilogue ํ—ค๋” ์ดˆ๊ธฐํ™” */
    PUT(HDRP(bp), PACK(size, 0));         /* Free block ํ—ค๋” */
    PUT(FTRP(bp), PACK(size, 0));         /* Free block ํ‘ธํ„ฐ */
    PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue ํ—ค๋” */

    /* ์ด์ „ ๋ธ”๋ก์ด ๊ฐ€์šฉ๋ฌ์„ ๋•Œ ํ†ตํ•ฉ */
    return coalesce(bp);
}

/* next-fit ๊ฒ€์ƒ‰ */
static void *find_fit(size_t asize)
{
    char *bp = last_bp;

    /* ํ˜„์žฌ ์œ„์น˜์—์„œ ๋‹ค์Œ ๋ธ”๋ก์˜ ๋ธ”๋ก ํฌ๊ธฐ๊ฐ€ 0์ด ์•„๋‹ ๋•Œ, ๊ทธ ๋‹ค์Œ ๋ธ”๋ก ๊ฒ€์ƒ‰ */
    for (bp = NEXT_BLKP(bp); GET_SIZE(HDRP(bp))!=0; bp = NEXT_BLKP(bp))
    {
        /* ๊ฐ€์šฉ ๋ธ”๋ก์ด๊ณ , ํฌ๊ธฐ๊ฐ€ ์‚ฌ์ด์ฆˆ๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์„ ๋•Œ */
        if (GET_ALLOC(HDRP(bp)) == 0 && GET_SIZE(HDRP(bp)) >= asize)
        {
            last_bp = bp;
            return bp;
        }        
    }

    /* ๊ฐ€์šฉ ๋ธ”๋ก ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋‚˜์˜ฌ ๋•Œ๊นŒ์ง€ */
    bp = heap_listp;
    while (bp < last_bp)
    {
        bp = NEXT_BLKP(bp);
        if (GET_ALLOC(HDRP(bp)) == 0 && GET_SIZE(HDRP(bp)) >= asize)
        {
            last_bp = bp;
            return bp;
        }
    }
    return NULL ;  
}

/* 
 * place - ๋งž๋Š” ๋ธ”๋ก ์ฐพ์œผ๋ฉด ํ• ๋‹น๊ธฐ๋Š” ์š”์ฒญํ•œ ๋ธ”๋ก์„ ๋ฐฐ์น˜, ์˜ต์…˜์œผ๋กœ ์ถ”๊ฐ€ ๋ถ€๋ถ„ ๋ถ„ํ• 
 */
static void place(void *bp, size_t asize)
{
    size_t csize = GET_SIZE(HDRP(bp));

    if ((csize - asize) >= (2 * DSIZE))
    {
        PUT(HDRP(bp), PACK(asize, 1));
        PUT(FTRP(bp), PACK(asize, 1));
        bp = NEXT_BLKP(bp);
        PUT(HDRP(bp), PACK(csize - asize, 0));
        PUT(FTRP(bp), PACK(csize - asize, 0));
    }
    else
    {
        PUT(HDRP(bp), PACK(csize, 1));
        PUT(FTRP(bp), PACK(csize, 1));
    }
}

/* 
 * mm_malloc - size ๋ฐ”์ดํŠธ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก ์š”์ฒญ
 *             brk pointer๋ฅผ ์ฆ๊ฐ€์‹œ์ผœ ๋ธ”๋ก ํ• ๋‹น        
 */
void *mm_malloc(size_t size)
{
    size_t asize;        /* ์กฐ์ •๋œ ๋ธ”๋ก ํฌ๊ธฐ */
    size_t extendsize;   /* ์ ํ•ฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ํž™์„ ํ™•์žฅํ•  ํฌ๊ธฐ */
    char *bp;

    /* ๊ฑฐ์ง“ ์š”์ฒญ์‹œ */
    if (size == 0)
        return NULL;

    /* ํ—ค๋”์™€ ํ’‹ํ„ฐ ์œ„ํ•œ ๊ณต๊ฐ„ ํ™•๋ณด ๋ฐ ๋”๋ธ” ์›Œ๋“œ ์š”๊ฑด ๋งŒ์กฑ์‹œํ‚ด */
    if (size <= DSIZE)
        asize = 2*DSIZE;
    else /* 8๋ฐ”์ดํŠธ ๋„˜๋Š” ์š”์ฒญ์— ๋Œ€ํ•ด ์˜ค๋ฒ„ํ—ค๋“œ ๋ฐ”์ดํŠธ ์ถ”๊ฐ€, ์ธ์ ‘ 8์˜ ๋ฐฐ์ˆ˜๋กœ ๋ฐ˜์˜ฌ๋ฆผ */
        asize = DSIZE * ((size + (DSIZE) + (DSIZE-1)) / DSIZE);
    
    /* ์ ์ ˆํ•œ ๊ฐ€์šฉ ๋ธ”๋ก์„ ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ์—์„œ ๊ฒ€์ƒ‰ */
    if ((bp = find_fit(asize)) != NULL){
        /* ๋งž๋Š” ๋ธ”๋ก ์ฐพ์œผ๋ฉด ํ• ๋‹น๊ธฐ๋Š” ์š”์ฒญํ•œ ๋ธ”๋ก์„ ๋ฐฐ์น˜, ์˜ต์…˜์œผ๋กœ ์ถ”๊ฐ€ ๋ถ€๋ถ„ ๋ถ„ํ•  */
        place(bp, asize);
        last_bp = bp;
        /* ์ƒˆ๋กœ ํ• ๋‹นํ•œ ๋ธ”๋ก์˜ ํฌ์ธํ„ฐ return */
        return bp;
    }

    /* ์ ์ ˆํ•œ ๊ฐ€์šฉ ๋ธ”๋ก์„ ๊ฐ€์šฉ ๋ฆฌ์ŠคํŠธ์—์„œ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด, ํž™์„ ์ƒˆ๋กœ์šด ๊ฐ€์šฉ ๋ธ”๋ก์œผ๋กœ ํ™•์žฅ */
    extendsize = MAX(asize, CHUNKSIZE);
    if ((bp = extend_heap(extendsize/WSIZE)) == NULL)
        return NULL;
    /* ์š”์ฒญํ•œ ๋ธ”๋ก์„ ์ƒˆ ๊ฐ€์šฉ ๋ธ”๋ก์— ๋ฐฐ์น˜, ํ•„์š”์‹œ ๋ธ”๋ก์„ ๋ถ„ํ•  */
    place(bp, asize);
    last_bp = bp;
    /* ์ƒˆ๋กœ ํ• ๋‹นํ•œ ๋ธ”๋ก์˜ ํฌ์ธํ„ฐ return */
    return bp;
}

/*
 * mm_free - ์š”์ฒญํ•œ ๋ธ”๋ก ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฒฝ๊ณ„ ํƒœ๊ทธ ์—ฐ๊ฒฐ ์‚ฌ์šฉํ•ด ์ƒ์ˆ˜ ์‹œ๊ฐ„์— ์ธ์ ‘ ๊ฐ€์šฉ ๋ธ”๋ก๋“ค๊ณผ ํ†ตํ•ฉ
 */
void mm_free(void *bp)
{
    size_t size = GET_SIZE(HDRP(bp));
    PUT(HDRP(bp), PACK(size, 0));
    PUT(FTRP(bp), PACK(size, 0));
    /* ์ธ์ ‘ ๊ฐ€์šฉ ๋ธ”๋ก๋“ค ํ†ตํ•ฉ */
    coalesce(bp);
}


/*
 * mm_realloc - ๋™์  ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ ๋‚ด์šฉ ์œ ์ง€ํ•˜๋ฉฐ ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ ๋ณ€๊ฒฝ
 */
void *mm_realloc(void *bp, size_t size)
{
    if ((int)size < 0)
        return NULL;
    else if ((int)size == 0)
    {
        mm_free(bp);
        return NULL;
    }
    else if (size > 0)
    {
        size_t oldsize = GET_SIZE(HDRP(bp));
        size_t newsize = size + (2 * WSIZE); /* ํ—ค๋”์™€ ํ‘ธํ„ฐ ์œ„ํ•œ 2 words ์ถ”๊ฐ€ */ 
        /* newsize๊ฐ€ oldsize๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์œผ๋ฉด return bp */
        if (newsize <= oldsize)
        {
            return bp;
        }
        /* oldsize ๋ณด๋‹ค new size๊ฐ€ ํฌ๋ฉด ๋ฐ”๊ฟˆ */
        else
        {
            /* ๋‹ค์Œ ๋ธ”๋ก์˜ ํ• ๋‹น ์—ฌ๋ถ€ ๋น„ํŠธ */
            size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
            size_t csize;
            /* next block์ด ๊ฐ€์šฉ ์ƒํƒœ์ด๊ณ , old์™€ next block์˜ ์‚ฌ์ด์ฆˆ ํ•ฉ์ด new size๋ณด๋‹ค ํฌ๋ฉด ํ•ฉ์ณ์„œ ์‚ฌ์šฉ  */
            if (!next_alloc && ((csize = oldsize + GET_SIZE(HDRP(NEXT_BLKP(bp))))) >= newsize)
            {
                // remove_from_free_list(NEXT_BLK(bp));
                PUT(HDRP(bp), PACK(csize, 1));
                PUT(FTRP(bp), PACK(csize, 1));
                return bp;
            }
            /* next block์ด ํ• ๋‹น๋œ ์ƒํƒœ์ด๊ฑฐ๋‚˜, old์™€ next block์˜ ์‚ฌ์ด์ฆˆ ํ•ฉ์ด new size๋ณด๋‹ค ์ž‘์„ ๋•Œ ์ƒˆ block ์ƒ์„ฑ */
            else
            {
                void *new_ptr = mm_malloc(newsize);
                place(new_ptr, newsize);
                memcpy(new_ptr, bp, newsize);
                mm_free(bp);
                return new_ptr;
            }
        }
    }
    else
        return NULL;
}