Skip to content

Commit

Permalink
Merge pull request #61 from nacos-group/develop-atomics-no-asm
Browse files Browse the repository at this point in the history
Develop atomics no asm
  • Loading branch information
TTTTTAAAAAKKKKEEEENNNN authored Mar 19, 2021
2 parents b08f0b9 + 88a2339 commit 5e2b8f0
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 18 deletions.
10 changes: 2 additions & 8 deletions include/thread/AtomicInt.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#ifndef __ATOMIC_INT_H_
#define __ATOMIC_INT_H_

#define __atomic_fool_gcc(x) (*(volatile struct { int a[100]; } *)x)
#define LOCK_PREFIX "lock "

namespace nacos{
class AtomicInt {
private:
Expand All @@ -12,11 +9,8 @@ class AtomicInt {
AtomicInt(int initval = 0) : _intval(initval) {};

int inc(int incval = 1) {
int __i = incval;
asm volatile(LOCK_PREFIX "xaddl %0, %1"
: "+r" (incval), "+m" (_intval)
: : "memory");
return incval + __i;
int oldValue = __sync_fetch_and_add(&_intval, incval);
return incval + oldValue;
};

int dec(int decval = 1) {
Expand Down
3 changes: 3 additions & 0 deletions test/allinone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ bool testDelayedThread2();

bool testNamingServiceAndDeRegisterActively();

bool testThreadPoolConcurrentWithAtomicCounter();

TestData disabledTestList[] =
TEST_ITEM_START
TEST_ITEM_END
Expand Down Expand Up @@ -197,6 +199,7 @@ TEST_ITEM_START
TEST_ITEM("Test delayed task pool", testDelayedThread)
TEST_ITEM("Test delayed task pool - multiple tasks triggered at the same time", testDelayedThread2)
TEST_ITEM("Register a service instance and remove it actively", testNamingServiceAndDeRegisterActively)
TEST_ITEM("thread pool with concurrent add & atomic operation", testThreadPoolConcurrentWithAtomicCounter)
TEST_ITEM_END

int main() {
Expand Down
68 changes: 58 additions & 10 deletions test/testcase/testThreadSmoke.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,13 @@
#include "src/thread/Thread.h"
#include "src/thread/ThreadPool.h"
#include "NacosString.h"
#include "thread/AtomicInt.h"

using namespace std;
using namespace nacos;

class SmokingTestThreadTask : public Task {
public:
SmokingTestThreadTask(const NacosString &taskName) { setTaskName(taskName); };

void run() {
NacosString taskName = getTaskName();
log_info("Hello world from %s\n", taskName.c_str());
};
};

class ThreadPoolLongRunTask : public Task {

public:
ThreadPoolLongRunTask(int taskId) {
NacosString taskName = "ThreadPoolLongRunTask" + NacosStringOps::valueOf(taskId);
Expand Down Expand Up @@ -86,5 +78,61 @@ bool testThreadPoolSmoke() {
}
cout << "If no coredump, should be successful" << endl;
tpStopper.join();

return true;
}

AtomicInt totalFinishedThreads;

class SmokingTestThreadTask : public Task {
private:
AtomicInt &_counter;
public:
SmokingTestThreadTask(const NacosString &taskName, AtomicInt &counter) : _counter(counter) {
setTaskName(taskName);
};

void run() {
NacosString taskName = getTaskName();
int currentTotal = 0;
for (int i = 0; i < 100000; i++) {
currentTotal = _counter.inc();
}
log_info("Hello world from %s, totalCount = %d\n", taskName.c_str(), currentTotal);
totalFinishedThreads.inc();
};
};

bool testThreadPoolConcurrentWithAtomicCounter() {
cout << "Starting testThreadPoolConcurrentWithAtomicCounter..." << endl;
ThreadPool tp(10);
tp.start();
cout << "ok, size = 10" << endl;
AtomicInt totalCounter;

Task *tasks[1000];
for (size_t i = 0; i < 40; i++) {
cout << "Creating task " << i << "..." << endl;
tasks[i] = new SmokingTestThreadTask("Counter-" + NacosStringOps::valueOf(i), totalCounter);
tp.put(tasks[i]);
cout << "ok" << endl;
}


while (totalFinishedThreads.get() != 40) {
sleep(1);
}
tp.stop();
cout << "If no coredump, should be successful" << endl;
cout << "totalCounter.get() = " << totalCounter.get() << endl;

SHOULD_BE_TRUE(totalCounter.get() == 40 * 100000, "40 threads, each thread accumulates totalCounter by 100k, result should be 4000k");

for (size_t i = 0; i < 40; i++) {
cout << "destroying task " << i << "..." << endl;
delete tasks[i];
tasks[i] = NULL;
cout << "ok" << endl;
}
return true;
}

0 comments on commit 5e2b8f0

Please sign in to comment.