无锁栈实现一例 (五)

2014-11-24 02:00:37 · 作者: · 浏览: 7
r(void)
{
HANDLE curth = ::GetCurrentThread();
DWORD_PTR oldmask = ::SetThreadAffinityMask(curth, 0);
::QueryPerformanceCounter(&start_);
::SetThreadAffinityMask(curth, oldmask);
}

double HRTimer::StopTimer(void)
{
HANDLE curth = ::GetCurrentThread();
DWORD_PTR oldmask = ::SetThreadAffinityMask(curth, 0);
::QueryPerformanceCounter(&stop_);
::SetThreadAffinityMask(curth, oldmask);
return ((stop_.QuadPart - start_.QuadPart) / frequency_) * 1000;
}

class AutoHRTimer {
public:
AutoHRTimer(HRTimer& hrt, const char* name);
~AutoHRTimer();

private:
HRTimer& hrt_;
const char* name_;
};

AutoHRTimer::AutoHRTimer(HRTimer& hrt, const char* name)
: hrt_(hrt),
name_(name)
{
hrt_.StartTimer();
}

AutoHRTimer::~AutoHRTimer()
{
double diff = hrt_.StopTimer();
fprintf(stdout, "%s cost time %f ms\n", name_, diff);
}

HRTimer g_hrtimer;

void acs_deque_init(acs_deque_t* deq);
int acs_deque_empty(acs_deque_t* deq);
void acs_deque_push(acs_deque_t* deq, acs_node_t* node);
acs_node_t* acs_deque_pop(acs_deque_t* deq);

void acs_deque_init(acs_deque_t* deq)
{
if (deq) {
deq->tail = &deq->head;
deq->head.next = NULL;
}
}

int acs_deque_empty(acs_deque_t* deq)
{
if (!deq)
return 1;
return deq->head.next == NULL;
}

void acs_deque_push(acs_deque_t* deq, acs_node_t* node)
{
acs_node_t* q = NULL;

do {
q = deq->tail;
} while (InterlockedCompareExchangePointer((PVOID*)&q->next, 0, node) != q->next);

InterlockedCompareExchangePointer((PVOID*)&deq->tail, q, node);
}

acs_node_t* acs_deque_pop(acs_deque_t* deq)
{
acs_node_t* q = NULL;

do {
q = deq->head.next;
if (q == NULL)
return NULL;
} while (InterlockedCompareExchangePointer((PVOID*)&deq->head.next, q, q->next) != deq->head.next);

return q;
}

static DWORD AesThreadFunc(void* arg)
{
acs_deque_t* ad = (acs_deque_t*)arg;

for (int i = 0; i < knMaxNodeCount; ++i) {
acs_node_t* an = new acs_node_t;
an->id = "randid_";
an->id.push_back((i % 10) + '0');
an->index = i;
an->next = NULL;
acs_deque_push(ad, an);
} // for

return 0;
}

static void TestAcsDeque()
{
acs_deque_t ad;
acs_node_t* poped_node = NULL;
HANDLE th[knThreadCount];

{
AutoHRTimer ahr(g_hrtimer, "ACS push 50000");
acs_deque_init(&ad);
for (int i = 0; i < knThreadCount; ++i) {
th[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AesThreadFunc, &ad, 0, NULL);
} // for
::WaitForMultipleObjects(knThreadCount, th, TRUE, INFINITE);
}

{
// Test pop.
AutoHRTimer ahr(g_hrtimer, "ACS pop 5000");
for (int i = 0; i < knPopedCount; ++i) {
poped_node = acs_deque_pop(&ad);
delete poped_node;
}
}

{
AutoHRTimer ahr(g_hrtimer, "ACS free 45000");
acs_node_t* cur = ad.head.next;
while (cur != NULL) {
acs_node_t* tmp = cur;
cur = cur->next;
delete tmp;
}
}
}

static DWORD StdThreadFunc(void* arg)
{
StdDeque* deq_list = (StdDeque*)arg;

for (int i = 0; i < knMaxNodeCount; ++i) {
DequeData* dd = new DequeData;
dd->id = "randid_";
dd->id.push_back((i % 10) + '0');
dd->index = i;
EnterCriticalSection(&g_stdcs);
deq_list->push_back(dd);
LeaveCriticalSection(&g_stdcs);
} // for