#pragma once

#include <pthread.h>

/* You may define additional structures / typedef's in this header file if
 * needed.
 */

typedef int** Matrix;
typedef int* Vector;

typedef struct node_t {
    Matrix left, right, target;
    int num_works;
    struct node_t *next;
} Request;

typedef struct work_t {
    int start, end;
    Matrix left, right, target;
    struct work_t* next;
} Work;

typedef struct tpool {
    int num_threads, n, done, req_sent, req_done;
    pthread_t* backend;
    pthread_t frontend;
    pthread_mutex_t req_lock, work_lock, count_lock;
    pthread_cond_t req_empty, work_empty, sync;
    Request *requests_head, *requests_tail;
    Work* workers_head, *workers_tail;
} Tpool;

struct tpool* tpool_init(int num_threads, int n);
void tpool_request(struct tpool*, Matrix a, Matrix b, Matrix c, int num_works);
void tpool_synchronize(struct tpool*);
void tpool_destroy(struct tpool*);
int calculation(int n, Vector, Vector);  // Already implemented
