void SimQueueInit(SimQueueStruct *queue, int max_backoff) {
    pointer_t tmp_sp;

    tmp_sp.struct_data.index = LOCAL_POOL_SIZE * N_THREADS;
    tmp_sp.struct_data.seq = 0L;
    queue->enq_sp = tmp_sp;

    tmp_sp.struct_data.index = LOCAL_POOL_SIZE * N_THREADS;
    tmp_sp.struct_data.seq = 0L;
    queue->deq_sp = tmp_sp;

    TVEC_SET_ZERO((ToggleVector *)&queue->enqueuers);
    TVEC_SET_ZERO((ToggleVector *)&queue->dequeuers);

    // Initializing queue's state
    // --------------------------
    TVEC_SET_ZERO((ToggleVector *) &queue->enq_pool[LOCAL_POOL_SIZE * N_THREADS].applied);
    queue->enq_pool[LOCAL_POOL_SIZE * N_THREADS].link_a = &queue->guard;
    queue->enq_pool[LOCAL_POOL_SIZE * N_THREADS].link_b = null;
    queue->enq_pool[LOCAL_POOL_SIZE * N_THREADS].ptr = &queue->guard;
    TVEC_SET_ZERO((ToggleVector *) &queue->deq_pool[LOCAL_POOL_SIZE * N_THREADS].applied);
    queue->deq_pool[LOCAL_POOL_SIZE * N_THREADS].ptr = &queue->guard;
#ifdef DEBUG
    queue->enq_pool[LOCAL_POOL_SIZE * N_THREADS].counter = 0L;
    queue->deq_pool[LOCAL_POOL_SIZE * N_THREADS].counter = 0L;
#endif
    queue->MAX_BACK = max_backoff * 100;
	queue->guard.val = GUARD_VALUE;
	queue->guard.next = null;
    FullFence();
}
inline static void *Execute(void* Arg) {
    long i, rnum, mybank;
    volatile long j;
    long id = (long) Arg;
    volatile ToggleVector lactive_set;
    ToggleVector mystate;

    fastRandomSetSeed(id + 1);
    BarrierWait(&bar);
    if (id == 0)
        d1 = getTimeMillis();
    TVEC_SET_ZERO(&mystate);
    TVEC_SET_BIT(&mystate, id);
    mybank = TVEC_GET_BANK_OF_BIT(id);
    for (i = 0; i < RUNS; i++) {
        mystate = TVEC_NEGATIVE(mystate);
        TVEC_ATOMIC_ADD_BANK(&active_set, &mystate, mybank);
        rnum = fastRandomRange(1, MAX_WORK);
        for (j = 0; j < rnum; j++)
            ;
        lactive_set = active_set;
        rnum = fastRandomRange(1, MAX_WORK);
        for (j = 0; j < rnum; j++)
            ;
    }
    return NULL;
}
void SHARED_OBJECT_INIT(int pid) {
    if (pid == 0) {
        pointer_t tmp_sp;

        tmp_sp.struct_data.index = LOCAL_POOL_SIZE * N_THREADS;
        tmp_sp.struct_data.seq = 0L;
        enq_sp = tmp_sp;

        tmp_sp.struct_data.index = LOCAL_POOL_SIZE * N_THREADS;
        tmp_sp.struct_data.seq = 0L;
        deq_sp = tmp_sp;

        TVEC_SET_ZERO((ToggleVector *)&enqueuers);
        TVEC_SET_ZERO((ToggleVector *)&dequeuers);

        // Initializing queue's state
        // --------------------------
        TVEC_SET_ZERO((ToggleVector *) &enq_pool[LOCAL_POOL_SIZE * N_THREADS].applied);
        enq_pool[LOCAL_POOL_SIZE * N_THREADS].link_a = &guard;
        enq_pool[LOCAL_POOL_SIZE * N_THREADS].link_b = null;
        enq_pool[LOCAL_POOL_SIZE * N_THREADS].ptr = &guard;

        TVEC_SET_ZERO((ToggleVector *) &deq_pool[LOCAL_POOL_SIZE * N_THREADS].applied);
        deq_pool[LOCAL_POOL_SIZE * N_THREADS].ptr = &guard;
#ifdef DEBUG
        enq_pool[LOCAL_POOL_SIZE * N_THREADS].counter = 0L;
        deq_pool[LOCAL_POOL_SIZE * N_THREADS].counter = 0L;
#endif
        MAX_BACK *= 100;
        FullFence();
    }

    TVEC_SET_ZERO(&mask);
    TVEC_SET_ZERO(&my_enq_bit);
    TVEC_SET_ZERO(&enq_toggle);
    TVEC_REVERSE_BIT(&my_enq_bit, pid);
    TVEC_SET_BIT(&mask, pid);
    enq_toggle = TVEC_NEGATIVE(mask);
    init_pool(&pool_node, sizeof(Node));

    TVEC_SET_ZERO(&mask);
    TVEC_SET_ZERO(&my_deq_bit);
    TVEC_SET_ZERO(&deq_toggle);
    TVEC_REVERSE_BIT(&my_deq_bit, pid);
    TVEC_SET_BIT(&mask, pid);
    deq_toggle = TVEC_NEGATIVE(mask);
}
int main(int argc, char *argv[]) {
    TVEC_SET_ZERO((ToggleVector *)&active_set);
    BarrierInit(&bar, N_THREADS);
    StartThreadsN(N_THREADS, Execute, _DONT_USE_UTHREADS_);
    JoinThreadsN(N_THREADS);
    d2 = getTimeMillis();

    printf("time: %d (ms)\tthroughput: %.2f (millions ops/sec)\t", (int) (d2 - d1), 2*RUNS*N_THREADS/(1000.0*(d2 - d1)));
    printStats(N_THREADS);

    return 0;
}
void SimQueueThreadStateInit(SimQueueStruct *queue, SimQueueThreadState *th_state, int pid) {
    TVEC_SET_ZERO(&th_state->mask);
    TVEC_SET_ZERO(&th_state->my_enq_bit);
    TVEC_SET_ZERO(&th_state->enq_toggle);
    TVEC_REVERSE_BIT(&th_state->my_enq_bit, pid);
    TVEC_SET_BIT(&th_state->mask, pid);
    th_state->enq_toggle = TVEC_NEGATIVE(th_state->mask);
    init_pool(&th_state->pool_node, sizeof(Node));

    TVEC_SET_ZERO(&th_state->mask);
    TVEC_SET_ZERO(&th_state->my_deq_bit);
    TVEC_SET_ZERO(&th_state->deq_toggle);
    TVEC_REVERSE_BIT(&th_state->my_deq_bit, pid);
    TVEC_SET_BIT(&th_state->mask, pid);
    th_state->deq_toggle = TVEC_NEGATIVE(th_state->mask);
    th_state->deq_local_index = 0;
    th_state->enq_local_index = 0;
    th_state->backoff = 1;
    th_state->mybank = TVEC_GET_BANK_OF_BIT(pid);
}