Skip to content
Snippets Groups Projects
Commit f6fdcbb8 authored by Paul Heinzlreiter's avatar Paul Heinzlreiter
Browse files

* working on pthreads

parent dd89824f
Branches
No related merge requests found
......@@ -6,10 +6,7 @@ namespace nbody {
using namespace std;
BarnesHutTree::BarnesHutTree() {
this->control.maxLeafBodies = 16;
this->control.tree = this;
this->control.processedNodes = 0;
pthread_rwlock_init(&this->control.lock, NULL);
this->maxLeafBodies = 16;
}
BarnesHutTree::~BarnesHutTree() {
......@@ -56,33 +53,41 @@ namespace nbody {
}
}
void BarnesHutTree::split(Node* current) {
vector<Box> subboxes = BarnesHutTree::splitBB(current);
current->leaf = false;
Node* after = current->next;
for (vector<Box>::iterator it = subboxes.begin(); it != subboxes.end(); it++) {
Node* child = new Node(current->tree);
pthread_rwlock_wrlock(&child->lock);
child->parent = current;
child->bb = *it;
child->bodies = it->copyBodies(current->bodies);
child->nextSibling = NULL;
child->prevSibling = NULL;
after->insertBefore(child);
if (it != subboxes.begin()) {
child->prev->nextSibling = child;
child->prevSibling = child->prev;
child->prev->afterSubtree = child;
}
//this->control.toProcess.push(child);
//cout << "storing " << child << endl;
}
after->prev->afterSubtree = current->afterSubtree;
current->bodies.clear();
for (Node* n = current->next; n != NULL; n = n->nextSibling) {
pthread_rwlock_unlock(&n->lock);
}
}
void BarnesHutTree::splitNode(Node* current) {
//this->control.toProcess.push(current);
//this->control.toProcess.pop();
//cout << "storing " << current << endl;
if (current->isSplitable(&this->control)) {
vector<Box> subboxes = this->splitBB(current);
current->leaf = false;
Node* after = current->next;
for (vector<Box>::iterator it = subboxes.begin(); it != subboxes.end(); it++) {
Node* child = new Node(this);
child->parent = current;
child->bb = *it;
child->bodies = it->copyBodies(current->bodies);
child->nextSibling = NULL;
child->prevSibling = NULL;
after->insertBefore(child);
if (it != subboxes.begin()) {
child->prev->nextSibling = child;
child->prevSibling = child->prev;
child->prev->afterSubtree = child;
}
//this->control.toProcess.push(child);
//cout << "storing " << child << endl;
}
after->prev->afterSubtree = current->afterSubtree;
current->bodies.clear();
if (current->isSplitable()) {
split(current);
}
//cout << "removing " << this->control.toProcess.top() << endl;
//this->control.toProcess.pop();
......@@ -105,10 +110,13 @@ namespace nbody {
current->afterSubtree = current->next;
//this->control.toProcess.push(current);
//iterate over existing boxes and split if it contains too much bodies
/*
while (current != this->nodes) {
this->splitNode(current);
current = current->next;
}
*/
BarnesHutTree::splitTree(this->nodes->next);
this->update();
}
......@@ -148,4 +156,49 @@ namespace nbody {
}
this->update();
}
/*
void BarnesHutTree::splitTree(Node* root) {
bool toSplitLeft = false;
Node* current = root;
do {
toSplitLeft = false;
while (current != root->prev) {
if (!pthread_rwlock_tryrdlock(&current->lock)) {
//read lock acquired
if (current->isSplitable()) {
pthread_rwlock_unlock(&current->lock);
if (!pthread_rwlock_trywrlock(&current->lock)) {
//write lock acquired
split(current);
pthread_rwlock_unlock(&current->lock);
}
toSplitLeft = true;
} else {
pthread_rwlock_unlock(&current->lock);
}
} else {
toSplitLeft = true;
}
}
} while (toSplitLeft);
}
*/
void BarnesHutTree::splitTree(Node* root) {
bool toSplitLeft = false;
Node* current = root;
do {
toSplitLeft = false;
while (current != root->prev) {
if (current->isSplitable()) {
split(current);
toSplitLeft = true;
}
current = current->next;
}
} while (toSplitLeft);
}
}
......@@ -11,9 +11,10 @@ namespace nbody {
class BarnesHutTree : public Tree {
protected:
virtual vector<Box> splitBB(Node* node);
static vector<Box> splitBB(Node* node);
virtual void splitNode(Node* current);
virtual void update();
static void split(Node* current);
public:
BarnesHutTree();
virtual ~BarnesHutTree();
......@@ -21,7 +22,7 @@ namespace nbody {
virtual void build(vector<Body> bodies, Box domain);
virtual void mergeLET(vector<Body> bodies);
virtual int numberOfChildren();
static void splitTree(Node* root);
};
}
......
......@@ -21,9 +21,11 @@ namespace nbody {
this->prevSibling = NULL;
this->nextSibling = NULL;
this->parent = NULL;
pthread_rwlock_init(&this->lock, NULL);
}
Node::~Node() {
pthread_rwlock_destroy(&this->lock);
}
Box Node::getBB() {
......@@ -34,10 +36,10 @@ namespace nbody {
this->bb = bb;
}
bool Node::isSplitable(Control* control) {
bool Node::isSplitable() {
bool result = true;
if (this->bodies.size() < control->maxLeafBodies + 1) {
if (this->bodies.size() < this->tree->maxLeafBodies + 1) {
result = false;
}
if (this->bb.volume() <= FLT_EPSILON) {
......
......@@ -26,10 +26,11 @@ namespace nbody {
bool leaf;
Tree* tree;
Body representative;
pthread_rwlock_t lock;
public:
Node(Tree* tree);
virtual ~Node();
virtual bool isSplitable(Control* control);
virtual bool isSplitable();
virtual void extendBBforBodies();
virtual void extendBBtoCube();
virtual Box getBB();
......
......@@ -11,16 +11,12 @@ namespace nbody {
Tree::Tree() {
//insert dummy root node
this->nodes = new Node(this);
this->control.maxLeafBodies = 16;
this->control.tree = this;
this->control.processedNodes = 0;
pthread_rwlock_init(&this->control.lock, NULL);
this->maxLeafBodies = 16;
}
Tree::~Tree() {
this->clean();
delete this->nodes;
pthread_rwlock_destroy(&this->control.lock);
}
void Tree::clean() {
......@@ -44,12 +40,6 @@ namespace nbody {
}
current = current->next;
}
BarnesHutTree* bht = dynamic_cast<BarnesHutTree*>(this);
if (bht != NULL && !(bht->control.processedNodes == 0 && bht->control.toProcess.empty())) {
cout << bht->control.toProcess.size() << endl;
return false;
}
return true;
}
......
......@@ -13,22 +13,13 @@ namespace nbody {
using namespace std;
class Node;
class Tree;
typedef struct _Control {
unsigned int maxLeafBodies;
Tree* tree;
int processedNodes;
stack<Node*> toProcess;
pthread_rwlock_t lock;
} Control;
class Tree {
friend class Node;
protected:
Node* nodes;
Control control;
//Control control;
unsigned int maxLeafBodies;
public:
static vector<Body> dubinskiParse(string filename);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment