; readWord success
  
queue(multithreading) cella 2013 Branchable 0 11836
  

#include
#include

int num_of_threads = 1;
LARGE_INTEGER start, end, freq;

class NODE {
public:
int key;
NODE *next;

NODE() { next = NULL;}

NODE(int key_value) {
next = NULL;
key = key_value;
}

~NODE() {}
};

class QUEUE {
NODE *head, *tail;
CRITICAL_SECTION enq_lock, deq_lock;
public:
QUEUE()
{
head = tail = new NODE(0);
InitializeCriticalSection(&enq_lock);
InitializeCriticalSection(&deq_lock);
}
~QUEUE() {}

void Init()
{
}
void Enq(int key)
{
EnterCriticalSection(&enq_lock);
NODE *e = new NODE(key);
tail->next = e;
tail = e;
LeaveCriticalSection(&enq_lock);
}

int Deq()
{
EnterCriticalSection(&deq_lock);
if (head->next == NULL) {LeaveCriticalSection(&deq_lock); return -999; }
int result = head->next->key;
NODE *temp = head;
head = head->next;
delete temp;
LeaveCriticalSection(&deq_lock);
return result;
}

};

bool CAS (NODE * volatile *Addr, NODE *Old, NODE *New)
{
LONG temp = InterlockedCompareExchange(
reinterpret_cast(Addr),
reinterpret_cast(New),
reinterpret_cast(Old));
return temp == reinterpret_cast(Old);
}

class LFQUEUE {
NODE * volatile head;
NODE * volatile tail;
public:
LFQUEUE()
{
head = tail = new NODE(0);
}
~LFQUEUE() {}

void Init()
{
NODE *ptr;
while(head->next != NULL) {
ptr = head;
head = head->next;
delete ptr;
}
tail = head;
}

void Enq(int x) {
NODE *e = new NODE(x);
while (true) {
NODE *last = tail;
NODE *next = last->next;
if (last != tail) continue;
if (NULL == next) {
if (CAS(&(last->next), NULL, e)) {
CAS(&tail, last, e);
return;
}
} else CAS(&tail, last, next);
} }


int Deq() {
while (true) {
NODE *first = head;
NODE *last = tail;
NODE *next = first->next;
if (first != head) continue;
if (first == last) {
if (next == NULL) {return -999;};
CAS(&tail, last, next);
continue;
}
int value = next->key;
if (false == CAS(&head, first, next)) continue;
delete first;
return value;
}
}
};



LFQUEUE lfqueue;
QUEUE queue;

DWORD WINAPI ThreadFunc(LPVOID lpVoid)
{
for (int i=0;i < 10000000 / num_of_threads;i++) {
if ((rand() % 2) || (i < 1000 / num_of_threads)) {
//queue.Enq(i);
lfqueue.Enq(i);
} else {
//queue.Deq();
lfqueue.Deq();
}
}
return 0;
}


int main()
{
HANDLE threads[64];

QueryPerformanceFrequency(&freq);
for (num_of_threads = 1; num_of_threads <=64 ; num_of_threads *= 2) {
lfqueue.Init();
QueryPerformanceCounter(&start);
for(int i=0;i threads[i] = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
for(int i=0;i WaitForSingleObject(threads[i], INFINITE);
QueryPerformanceCounter(&end);
for(int i=0;i CloseHandle(threads[i]);
int dur = (int)((end.QuadPart - start.QuadPart) / (freq.QuadPart / 1000));
printf("%d threads, %dms\n", num_of_threads, dur);
}
return 0;
}