无锁栈实现一例 (二)

2014-11-24 02:00:37 · 作者: · 浏览: 6
f struct acs_deque_t {
struct acs_node_t head;
struct acs_node_t* tail;
} acs_deque_t;

typedef struct DequeData {
std::string id;
int index;
} DequeData;

typedef std::deque StdDeque;

CRITICAL_SECTION g_stdcs;

int g_aes_cost_time = 0;
int g_std_cost_time = 0;

class HRTimer {
public:
HRTimer();
~HRTimer() {}

double GetFrequency(void);
void StartTimer(void);
double StopTimer(void);

private:
LARGE_INTEGER start_;
LARGE_INTEGER stop_;
double frequency_;
};

HRTimer::HRTimer()
: start_(),
stop_(),
frequency_(0.f)
{
frequency_ = this->GetFrequency();
}

double HRTimer::GetFrequency(void)
{
LARGE_INTEGER proc_freq;
if (!::QueryPerformanceFrequency(&proc_freq))
return 0.f;
return proc_freq.QuadPart;
}

void HRTimer::StartTimer(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) {