⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pool.cc

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 CC
字号:
//// pool.cc//// Copyright (C) 1996 Limit Point Systems, Inc.//// Author: Curtis Janssen <cljanss@limitpt.com>// Maintainer: LPS//// This file is part of the SC Toolkit.//// The SC Toolkit is free software; you can redistribute it and/or modify// it under the terms of the GNU Library General Public License as published by// the Free Software Foundation; either version 2, or (at your option)// any later version.//// The SC Toolkit is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Library General Public License for more details.//// You should have received a copy of the GNU Library General Public License// along with the SC Toolkit; see the file COPYING.LIB.  If not, write to// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.//// The U.S. Government is granted a limited license as per AL 91-7.//#ifdef __GNUC__#pragma implementation#endif#include <util/misc/formio.h>#include <util/group/pool.h>using namespace std;using namespace sc;voidPoolData::check(void* lower_bound, void* upper_bound){  if ((void*)this < lower_bound || (void*)this >= upper_bound) {      ExEnv::errn() << scprintf("PoolData::check: this out of bounds\n");      abort();    }  if (next_) {      if ((void*)next_ < lower_bound || (void*)next_ >= upper_bound) {          ExEnv::errn() << scprintf("PoolData::check: next_ out of bounds\n");          abort();        }      if (next_->prev_ != this) {          ExEnv::errn() << scprintf("PoolData::check: next pd doesn't point back\n");          abort();        }      if ((char*)next_ != (char*)this + size_ + PoolData_aligned_size) {          ExEnv::errn() << scprintf("PoolData::check: next_ not consistent with size\n");          abort();        }      if (free_ && next_->free_) {          ExEnv::errn() << scprintf("PoolData::check: free and next is free\n");          abort();        }    }  if (prev_) {      if ((void*)prev_ < lower_bound || (void*)prev_ >= upper_bound) {          ExEnv::errn() << scprintf("PoolData::check: prev_ out of bounds\n");          abort();        }      if (prev_->next_ != this) {          ExEnv::errn() << scprintf("PoolData::check: prev pd doesn't point back\n");          abort();        }      if (free_ && prev_->free_) {          ExEnv::errn() << scprintf("PoolData::check: free and prev is free\n");          abort();        }    }  if (free_) {      PoolData* n = f.next_free_;      PoolData* p = f.prev_free_;      if (n) {          if ((void*)n < lower_bound || (void*)n >= upper_bound) {              ExEnv::errn() << scprintf("PoolData::check: next free out of bounds\n");              abort();            }          if (n->f.prev_free_ != this) {              ExEnv::errn() << scprintf(                      "PoolData::check: next free pd doesn't point back\n");              abort();            }        }      if (p) {          if ((void*)p < lower_bound || (void*)p >= upper_bound) {              ExEnv::errn() << scprintf("PoolData::check: prev free out of bounds\n");              abort();            }          if (p->f.next_free_ != this) {              ExEnv::errn() << scprintf(                      "PoolData::check: prev free pd doesn't point back\n");              abort();            }        }    }}Pool::Pool(size_t size):  size_(size){  // Initialize the first and last members of the data list.  firstdatum_ = (PoolData*)align_pool_data((void*)((char*)this+sizeof(Pool)));  if ((char*)this + size <= (char*) firstdatum_) {      ExEnv::errn() << scprintf("Pool::Pool: not given enough space\n");      abort();    }    size_t firstdatum_size = align_pool_data_downward((size_t)                                                    (((char*)this+size)                                                    - (char*)firstdatum_));  new(firstdatum_) PoolData(firstdatum_size);  firstdatum_->prev_next(0,0);  // Initialize the free lists.  int i;  for (i=0; i<freelist_size; i++) freelist_[i] = 0;  freelist_add(firstdatum_);}voidPool::freelist_add(PoolData*d){  int slot = freelist_find_slot(d->size_);  d->free_ = 1;  PoolData* tmp = freelist_[slot];  d->next_free(tmp);  d->prev_free(0);  freelist_[slot] = d;  if (tmp) tmp->prev_free(d);#ifdef DEBUG_POOL  d->check();  if (d->next()) d->next()->check();  if (d->prev()) d->prev()->check();#endif}voidPool::freelist_del(PoolData*d){  if (d->next_free()) d->next_free()->prev_free(d->prev_free());  if (d->prev_free()) d->prev_free()->next_free(d->next_free());  else {      int slot = freelist_find_slot(d->size_);      freelist_[slot] = d->next_free();    }  d->free_ = 0;#ifdef DEBUG_POOL  d->check();  if (d->next()) d->next()->check();  if (d->prev()) d->prev()->check();#endif}intPool::freelist_find_slot(size_t size){  int slot = 0;  size_t mask = ~ (size_t)0;  while(mask & size) {      slot++;      mask <<= 1;    }  return slot;}void*Pool::allocate(size_t size){  int slot = freelist_find_slot(size);  for (int i=slot; i<freelist_size; i++) {      PoolData* j;      for (j=freelist_[i]; j; j = j->next_free()) {          if (j->size_ >= size) {              freelist_del(j);              // Maybe need to break this chunk into two pieces.              if (j->size_ > size + PoolData_aligned_size) {                  PoolData* freechunk = (PoolData*)((char*)j                                                    + PoolData_aligned_size                                                    + size);                  new(freechunk) PoolData(j->size_ - size);                  freechunk->prev_next(j,j->next());                  if (freechunk->next()) freechunk->next()->prev(freechunk);                  j->size_ = size;                  j->next(freechunk);                  freelist_add(freechunk);                }#ifdef DEBUG_POOL              j->check();              if (j->next()) j->next()->check();              if (j->prev()) j->prev()->check();#endif              return j->data();            }        }    }  return 0;}voidPool::release(void* v){  PoolData *d = voidptr_to_pd(v);  if (d->prev() && d->prev()->free_) {      freelist_del(d->prev());      d->prev()->size_ += d->size_ + PoolData_aligned_size;      d->prev()->next(d->next());      if (d->next()) d->next()->prev(d->prev());      d->set_magic(0);      d = d->prev();    }  if (d->next() && d->next()->free_) {      freelist_del(d->next());      d->next()->set_magic(0);      d->size_ += d->next()->size_ + PoolData_aligned_size;      if (d->next()->next()) d->next()->next()->prev(d);      d->next(d->next()->next());    }  freelist_add(d);}static voidprint_pooldata(ostream&o,PoolData*d,int free){  PoolData *next,*prev;  if (free) {      next = d->next_free();      prev = d->prev_free();    }  else {      next = d->next();      prev = d->prev();    }  o << scprintf("    PoolData: size=%d", d->size_);  if (d->free_) o << scprintf(", free");  else o << scprintf(", allocated");  if (!prev) o << scprintf(", first");  if (!next) o << scprintf(", last");  o << endl;  if (next) print_pooldata(o,next,free);}voidPool::print(ostream&o){  o << scprintf("Memory Pool:\n");  o << scprintf("  data chain:\n");  print_pooldata(o,firstdatum_,0);  for (int i=0; i<freelist_size; i++) {      if (freelist_[i]) {          o << scprintf("  freelist[%d]:\n",i);          print_pooldata(o,freelist_[i],1);        }    }}voidPool::check(){  // The bit lost at the beginning to Pool and alignment.  size_t start = (size_t)                 ((char*)align_pool_data((void*)((char*)this + sizeof(Pool)))                  - (char*)this);  // The bit lost at the end to alignment.  size_t end = (size_t)               ((char*)this + size_                - (char*) align_pool_data_downward((size_t)((void*)this)                                                   +size_));  size_t size = start + end;  PoolData *j;  for (j=firstdatum_; j; j = j->next()) {      j->check(this,(void*)((char*)this+size_));      size += PoolData_aligned_size + j->size_;    }    if (size != size_) {      ExEnv::errn() << scprintf("Pool::check(): inconsistent sizes\n");      ExEnv::errn() << scprintf("  computed: %d\n",size);      ExEnv::errn() << scprintf("  actual:   %d\n",size_);      abort();    }  // make sure that all data is accounted for  for (j=firstdatum_; j; j = j->next()) {      j->flags_ = 1;    }  for (int i=0; i<freelist_size; i++) {      for (j=freelist_[i]; j; j = j->next_free()) {          j->flags_ = 0;        }    }  for (j=firstdatum_; j; j = j->next()) {      if (j->free_ && j->flags_) {          ExEnv::errn() << scprintf("Pool::check: free data not in freelist\n");          abort();        }    }}/////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "CLJ"// End:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -