1 #include <../../nrnconf.h> 4 #if NRNMPI // to end of file 18 #if defined(HAVE_SSTREAM) // the standard ... 31 #define MessageList MpiMessageList 32 #define WorkItem MpiWorkItem 33 #define WorkList MpiWorkList 34 #define ReadyList MpiReadyList 35 #define ResultList MpiResultList 36 #define PendingList MpiPendingList 37 #define LookingToDoList MpiLookingToDoList 41 WorkItem(
int id, bbsmpibuf*
buf,
int cid);
47 bool todo_less_than(
const WorkItem*)
const;
51 bool operator() (
const char* s1,
const char* s2)
const {
52 return strcmp(s1, s2) < 0;
57 bool operator() (
int i,
int j)
const {
63 bool operator() (
const WorkItem* w1,
const WorkItem* w2)
const {
64 return w1->todo_less_than(w2);
68 static char* newstr(
const char*
s) {
69 char* s1 =
new char[strlen(s) + 1];
74 WorkItem::WorkItem(
int id, bbsmpibuf*
buf,
int cid) {
76 printf(
"WorkItem %d\n",
id);
84 WorkItem::~WorkItem() {
90 bool WorkItem::todo_less_than(
const WorkItem* w)
const {
91 WorkItem* w1 = (WorkItem*)
this;
92 WorkItem* w2 = (WorkItem*)w;
93 while (w1->parent_ != w2->parent_) {
94 if (w1->id_ < w2->id_) {
101 printf(
"todo_less_than %d < %d return %d\n", this->
id_, w->id_, w1->id_ < w2->id_);
103 return w1->id_ < w2->id_;
106 class MessageList :
public std::multimap <const char*, bbsmpibuf*, ltstr>{};
107 class PendingList :
public std::multimap <const char*, const int, ltstr>{};
109 class LookingToDoList :
public std::set <int, ltint>{};
110 class ReadyList :
public std::set<const WorkItem*, ltWorkItem>{};
111 class ResultList:
public std::multimap<int, const WorkItem*, ltint>{};
114 class PendingList {};
116 class LookingToDoList {};
122 #if defined(HAVE_STL) 127 pending_ =
new PendingList();
128 looking_todo_ =
new LookingToDoList();
129 send_context_ =
new LookingToDoList();
132 remaining_context_cnt_ = 0;
137 #if defined(HAVE_STL) 140 delete looking_todo_;
141 printf(
"~BBSLocalServer not deleting everything\n");
146 delete send_context_;
152 printf(
"DirectServer::look_take |%s|\n", key);
155 #if defined(HAVE_STL) 158 MessageList::iterator m = messages_->find(key);
159 if (m != messages_->end()) {
163 char*
s = (
char*)((*m).first);
168 printf(
"DirectServer::look_take |%s| recv=%p return %d\n", key, (*recv), b);
176 printf(
"DirectServer::look |%s|\n", key);
181 #if defined(HAVE_STL) 182 MessageList::iterator m = messages_->find(key);
183 if (m != messages_->end()) {
191 printf(
"DirectServer::look |%s| recv=%p return %d\n", key, (*recv), b);
198 #if defined(HAVE_STL) 200 printf(
"put_pending |%s| %d\n", key, cid);
202 char* s = newstr(key);
203 pending_->insert(std::pair<const char* const, const int>(s, cid));
209 #if defined(HAVE_STL) 210 PendingList::iterator
p = pending_->find(key);
211 if (p != pending_->end()) {
214 printf(
"take_pending |%s| %d\n", key, *cid);
216 char* s = (
char*)((*p).first);
226 #if defined(HAVE_STL) 229 printf(
"DirectServer::post |%s| send=%p\n", key, send);
231 if (take_pending(key, &cid)) {
232 nrnmpi_bbssend(cid,
TAKE, send);
234 MessageList::iterator m = messages_->insert(
235 std::pair<const char* const, bbsmpibuf*>(newstr(key), send)
243 #if defined(HAVE_STL) 244 looking_todo_->insert(cid);
249 #if defined(HAVE_STL) 251 printf(
"BBSDirectServer::post_todo pid=%d cid=%d send=%p\n", pid, cid, send);
253 WorkItem* w =
new WorkItem(next_id_++, send, cid);
255 WorkList::iterator p = work_->find(pid);
256 if (p != work_->end()) {
257 w->parent_ = (WorkItem*)((*p).second);
259 work_->insert(std::pair<const int, const WorkItem*>(w->id_, w));
261 printf(
"work insert %d\n", w->id_);
263 LookingToDoList::iterator
i = looking_todo_->begin();
264 if (i != looking_todo_->end()) {
266 looking_todo_->erase(i);
268 nrnmpi_bbssend(cid, w->id_ + 1, send);
279 #if defined(HAVE_STL) 285 for (j=0; j < 1000; ++
j) {
286 if (remaining_context_cnt_ == 0) {
291 if (remaining_context_cnt_ > 0) {
292 Printf(
"some workers did not receive previous context\n");
293 send_context_->erase(send_context_->begin(), send_context_->end());
294 nrnmpi_unref(context_buf_);
299 send_context_->insert(j);
301 LookingToDoList::iterator i = looking_todo_->begin();
302 while (i != looking_todo_->end()) {
304 looking_todo_->erase(i);
306 printf(
"sending context to already waiting %d\n", cid);
308 nrnmpi_bbssend(cid,
CONTEXT+1, send);
309 i = send_context_->find(cid);
310 send_context_->erase(i);
311 --remaining_context_cnt_;
312 i = looking_todo_->begin();
314 if (remaining_context_cnt_ > 0) {
316 nrnmpi_ref(context_buf_);
330 while (remaining_context_cnt_) {
337 #if defined(HAVE_STL) 338 LookingToDoList::iterator i = send_context_->find(cid);
339 if (i != send_context_->end()) {
340 send_context_->erase(i);
342 printf(
"sending context to %d\n", cid);
344 nrnmpi_bbssend(cid,
CONTEXT+1, context_buf_);
345 if (--remaining_context_cnt_ <= 0) {
346 nrnmpi_unref(context_buf_);
356 #if defined(HAVE_STL) 358 printf(
"DirectServer::post_result id=%d send=%p\n",
id, send);
360 WorkList::iterator i = work_->find(
id);
361 WorkItem* w = (WorkItem*)((*i).second);
363 nrnmpi_unref(w->buf_);
365 results_->insert(std::pair<const int, const WorkItem*>(w->parent_ ? w->parent_->id_ : 0, w));
370 #if defined(HAVE_STL) 372 printf(
"DirectServer::look_take_todo\n");
376 ReadyList::iterator i = todo_->begin();
377 if (i != todo_->end()) {
378 WorkItem* w = (WorkItem*)(*i);
382 printf(
"DirectServer::look_take_todo recv %p with keypos=%d return %d\n", *recv, (*recv)->keypos, w->id_);
396 printf(
"DirectServer::look_take_result pid=%d\n", pid);
398 #if defined(HAVE_STL) 401 ResultList::iterator i = results_->find(pid);
402 if (i != results_->end()) {
403 WorkItem* w = (WorkItem*)((*i).second);
407 WorkList::iterator j = work_->find(
id);
411 printf(
"DirectServer::look_take_result recv=%p return %d\n", *recv,
id);
void post(const char *key)
bool look_take(const char *key)
bool look(const char *key)
bool take_pending(const char *key, int *cid)
static BBSDirectServer * server_
void nrnbbs_context_wait()
void context(int ncid, int *cids)
static double map(void *v)
bool send_context(int cid)
void put_pending(const char *key, int cid)
virtual ~BBSDirectServer()
int look_take_result(int parentid)
void post_todo(int parentid, int cid)
void add_looking_todo(int cid)