Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
2.4 kB
3
Indexable
Never
#include <pthread.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

typedef struct Item {
    _Atomic(struct Item*) next;
    int64_t value;
} item_t;

typedef struct {
    int thread_index;
    int k;
} thread_arg;

_Atomic(item_t*) last;
atomic_int allocs = 0;
atomic_int frees = 0;
atomic_int length = 0;

void build_new_element(int number, int thread_number)
{
    // printf("number: %d, thread: %d\n", number, thread_number);
    item_t* new_elem = malloc(sizeof(item_t));
    ++allocs;
    new_elem->next = NULL;
    new_elem->value = number;
    if (atomic_load(&last->next) != NULL) {
        printf("ooops: %ld\n", last->next->value);
        abort();
    }
    item_t* prev = atomic_load(&last);
    atomic_store(&last, new_elem);
    prev->next = new_elem;
    // atomic_store(&last->next, new_elem);
    //++length;

    // atomic_store(&last, new_elem);
    //sched_yield();
}

void* routine(void* arg)
{
    thread_arg* argument = (thread_arg*)arg;
    int index = argument->thread_index;
    int k = argument->k;
    for (int number = index * k; number < (index + 1) * k; ++number) {
        build_new_element(number, index);
    }
    return arg;
}

void delete_list(_Atomic(item_t*) ptr)
{
    item_t* to_delete = atomic_load(&ptr);
    if (atomic_load(&to_delete->next) == NULL) {
        free(to_delete);
        return;
    }
    delete_list(to_delete->next);
    ++frees;
    free(to_delete);
}

int main(int argc, char* argv[])
{
    int N = atoi(argv[1]);
    int k = atoi(argv[2]);
    if (k == 0)
        return 0;
    item_t* begin = malloc(sizeof(item_t));
    atomic_store(&last, begin);
    pthread_t threads[N];
    for (int i = 0; i < N; ++i) {
        thread_arg* arg = malloc(sizeof(thread_arg));
        arg->k = k;
        arg->thread_index = i;
        if (pthread_create(threads + i, NULL, &routine, arg))
            return 1;
    }
    for (int i = 0; i < N; ++i) {
        void* p;
        if (pthread_join(threads[i], &p))
            return 2;
        free(p);
    }
    item_t* ptr = atomic_load(&begin->next);
    while (ptr != NULL) {
        printf("%ld\n", ptr->value);
        ptr = atomic_load(&ptr->next);
    }
    delete_list(begin->next);
    free(begin);
    ++frees;
    // printf("Total: %d allocs, %d frees\n", allocs, frees);
}