#ifndef CBAG_H
#define CBAG_H

#include "def.h"

#define BLOCK_SIZE 16
#define NR_THREADS 16
#define WORD_SIZE 64

// TODO: not at all ready yet!

// multi-node type for this data structure
typedef struct block_t
{
    _Atomic (void) *nodes[BLOCK_SIZE];
    // max 256 threads supported
    _Atomic (uint64_t) notifyAdd[NR_THREADS / WORD_SIZE + 1];
    _Atomic (struct block_t *) next;
} block_t;

block_t *block_get_ref(block_t *block);
bool block_get_mark1(block_t *block);
bool block_get_mark2(block_t *block);
void block_set_mark1(block_t **block, bool mark1);
void block_set_mark2(block_t **block, bool mark2);

void mark_1_block(block_t *block);

block_t *new_block();

void notify_all(block_t *block);
void notify_start(block_t *block, int tid);
bool notify_check(block_t *block, int tid);

void *try_steal_block(int round);
block_t *next_steal_block(block_t *block);

// publicly exposed functions in special namespace
void cbag_init_bag(int thread_count);
void cbag_destroy_bag();
void cbag_init_thread();

void cbag_add(void *item);
void *cbag_try_remove_any();

// TODO: memory management functions, leave unimplemented?
//typedef block_t node_t;
//node_t *new_node(int size);
//void delete_node(node_t *node);
//node_t *de_ref_link(node_t **link);
//void release_ref(node_t *node);
//void re_scan(node_t *node);

#endif