<commit_before>/*
 * Memory pool.
 *
 * author: <NAME> <<EMAIL>>
 */

#include "pool.h"
#include "list.h"

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

#define LINEAR_ALIGN 8
#define LINEAR_ALIGN_BITS 0x7

enum pool_type {
    POOL_LIBC,
    POOL_LINEAR,
};

struct libc_pool_chunk {
    struct libc_pool_chunk *next;
    unsigned char data[1];
};

struct linear_pool_area {
    struct linear_pool_area *prev;
    size_t size, used;
    unsigned char data[1];
};

struct pool {
    struct list_head siblings, children;
    pool_t parent;
    unsigned ref;
    enum pool_type type;
    const char *name;
    union {
        struct libc_pool_chunk *libc;
        struct linear_pool_area *linear;
    } current_area;
};

static struct {
    unsigned num_linear_areas;
    struct linear_pool_area *linear_areas;
} recycler;

static void *
xmalloc(size_t size)
{
    void *p = malloc(size);
    if (p == NULL) {
        fputs("Out of memory\n", stderr);
        abort();
    }
    return p;
}

void
pool_recycler_clear(void)
{
    struct linear_pool_area *linear;

    while (recycler.linear_areas != NULL) {
        linear = recycler.linear_areas;
        recycler.linear_areas = linear->prev;
        free(linear);
    }

    recycler.num_linear_areas = 0;
}

static void
pool_recycler_put_linear(struct linear_pool_area *area)
{
    assert(area != 0);
    assert(area->size > 0);

    if (recycler.num_linear_areas < 32) {
        area->prev = recycler.linear_areas;
        recycler.linear_areas = area;
        ++recycler.num_linear_areas;
    } else {
        free(area);
    }
}

static struct linear_pool_area *
pool_recycler_get_linear(size_t size)
{
    struct linear_pool_area **linear_p, *linear;

    assert(size > 0);

    for (linear_p = &recycler.linear_areas, linear = *linear_p;
         linear != NULL;
         linear_p = &linear->prev, linear = *linear_p) {
        if (linear->size == size) {
            assert(recycler.num_linear_areas > 0);
            --recycler.num_linear_areas;
            *linear_p = linear->prev;
            return linear;
        }
    }

    return NULL;
}

static void
pool_add_child(pool_t pool, pool_t child)
{
    assert(child->parent == NULL);

    child->parent = pool;
    list_add(&child->siblings, &pool->children);
}

static pool_t
pool_new(pool_t parent, const char *name)
{
    pool_t pool;

    pool = xmalloc(sizeof(*pool));
    list_init(&pool->children);
    pool->ref = 1;
    pool->name = name;

    if (parent != NULL)
        pool_add_child(parent, pool);
    else
        pool->parent = NULL;

    return pool;
}

pool_t
pool_new_libc(pool_t parent, const char *name)
{
    pool_t pool = pool_new(parent, name);
    pool->type = POOL_LIBC;
    pool->current_area.libc = NULL;
    return pool;
}

static struct linear_pool_area *
pool_new_linear_area(struct linear_pool_area *prev, size_t size)
{
    struct linear_pool_area *area = xmalloc(sizeof(*area) - sizeof(area->data) + size);
    if (area == NULL)
        abort();
    area->prev = prev;
    area->size = size;
    area->used = 0;
    return area;
}
<commit_msg>fix pool->parent initialization<commit_after>/*
 * Memory pool.
 *
 * author: <NAME> <<EMAIL>>
 */

#include "pool.h"
#include "list.h"

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

#define LINEAR_ALIGN 8
#define LINEAR_ALIGN_BITS 0x7

enum pool_type {
    POOL_LIBC,
    POOL_LINEAR,
};

struct libc_pool_chunk {
    struct libc_pool_chunk *next;
    unsigned char data[1];
};

struct linear_pool_area {
    struct linear_pool_area *prev;
    size_t size, used;
    unsigned char data[1];
};

struct pool {
    struct list_head siblings, children;
    pool_t parent;
    unsigned ref;
    enum pool_type type;
    const char *name;
    union {
        struct libc_pool_chunk *libc;
        struct linear_pool_area *linear;
    } current_area;
};

static struct {
    unsigned num_linear_areas;
    struct linear_pool_area *linear_areas;
} recycler;

static void *
xmalloc(size_t size)
{
    void *p = malloc(size);
    if (p == NULL) {
        fputs("Out of memory\n", stderr);
        abort();
    }
    return p;
}

void
pool_recycler_clear(void)
{
    struct linear_pool_area *linear;

    while (recycler.linear_areas != NULL) {
        linear = recycler.linear_areas;
        recycler.linear_areas = linear->prev;
        free(linear);
    }

    recycler.num_linear_areas = 0;
}

static void
pool_recycler_put_linear(struct linear_pool_area *area)
{
    assert(area != 0);
    assert(area->size > 0);

    if (recycler.num_linear_areas < 32) {
        area->prev = recycler.linear_areas;
        recycler.linear_areas = area;
        ++recycler.num_linear_areas;
    } else {
        free(area);
    }
}

static struct linear_pool_area *
pool_recycler_get_linear(size_t size)
{
    struct linear_pool_area **linear_p, *linear;

    assert(size > 0);

    for (linear_p = &recycler.linear_areas, linear = *linear_p;
         linear != NULL;
         linear_p = &linear->prev, linear = *linear_p) {
        if (linear->size == size) {
            assert(recycler.num_linear_areas > 0);
            --recycler.num_linear_areas;
            *linear_p = linear->prev;
            return linear;
        }
    }

    return NULL;
}

static void
pool_add_child(pool_t pool, pool_t child)
{
    assert(child->parent == NULL);

    child->parent = pool;
    list_add(&child->siblings, &pool->children);
}

static pool_t
pool_new(pool_t parent, const char *name)
{
    pool_t pool;

    pool = xmalloc(sizeof(*pool));
    list_init(&pool->children);
    pool->ref = 1;
    pool->name = name;

    pool->parent = NULL;
    if (parent != NULL)
        pool_add_child(parent, pool);

    return pool;
}

pool_t
pool_new_libc(pool_t parent, const char *name)
{
    pool_t pool = pool_new(parent, name);
    pool->type = POOL_LIBC;
    pool->current_area.libc = NULL;
    return pool;
}

static struct linear_pool_area *
pool_new_linear_area(struct linear_pool_area *prev, size_t size)
{
    struct linear_pool_area *area = xmalloc(sizeof(*area) - sizeof(area->data) + size);
    if (area == NULL)
        abort();
    area->prev = prev;
    area->size = size;
    area->used = 0;
    return area;
}

{'fraction_non_alphanumeric': 0.11905904944791167, 'fraction_numerical': 0.004480716914706353, 'mean_word_length': 2.8367096378146104, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 64, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '42356', 'n_tokens_mistral': 2258, 'n_tokens_neox': 2203, 'n_words': 489}