gpi.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <cmath>
00035
00036 namespace Gecode { namespace Kernel {
00037
00039 class GPI {
00040 public:
00042 class Info {
00043 public:
00045 unsigned int pid;
00047 unsigned int gid;
00049 double afc;
00051 void init(unsigned int pid, unsigned int gid);
00052 };
00053 private:
00055 class Block : public HeapAllocated {
00056 public:
00058 static const int n_info = 8192;
00060 Info info[n_info];
00062 Block* next;
00064 int free;
00066 Block(void);
00068 void rescale(void);
00069 };
00071 Block* b;
00073 double invd;
00075 unsigned int npid;
00077 bool us;
00079 Block fst;
00081 GECODE_KERNEL_EXPORT static Support::Mutex m;
00082 public:
00084 GPI(void);
00086 void decay(double d);
00088 double decay(void) const;
00090 void fail(Info& c);
00092 Info* allocate(unsigned int p, unsigned int gid);
00094 Info* allocate(unsigned int gid);
00096 unsigned int pid(void) const;
00098 bool unshare(void);
00100 ~GPI(void);
00101 };
00102
00103
00104 forceinline void
00105 GPI::Info::init(unsigned int pid0, unsigned int gid0) {
00106 pid=pid0; gid=gid0; afc=1.0;
00107 }
00108
00109
00110 forceinline
00111 GPI::Block::Block(void)
00112 : next(NULL), free(n_info) {}
00113
00114 forceinline void
00115 GPI::Block::rescale(void) {
00116 for (int i=free; i < n_info; i++)
00117 info[i].afc *= Kernel::Config::rescale;
00118 }
00119
00120
00121 forceinline
00122 GPI::GPI(void)
00123 : b(&fst), invd(1.0), npid(0U), us(false) {}
00124
00125 forceinline void
00126 GPI::fail(Info& c) {
00127 m.acquire();
00128 c.afc = invd * (c.afc + 1.0);
00129 if (c.afc > Kernel::Config::rescale_limit)
00130 for (Block* i = b; i != NULL; i = i->next)
00131 i->rescale();
00132 m.release();
00133 }
00134
00135 forceinline double
00136 GPI::decay(void) const {
00137 double d;
00138 const_cast<GPI&>(*this).m.acquire();
00139 d = 1.0 / invd;
00140 const_cast<GPI&>(*this).m.release();
00141 return d;
00142 }
00143
00144 forceinline unsigned int
00145 GPI::pid(void) const {
00146 unsigned int p;
00147 const_cast<GPI&>(*this).m.acquire();
00148 p = npid;
00149 const_cast<GPI&>(*this).m.release();
00150 return p;
00151 }
00152
00153 forceinline bool
00154 GPI::unshare(void) {
00155 bool u;
00156 m.acquire();
00157 u = us; us = true;
00158 m.release();
00159 return u;
00160 }
00161
00162 forceinline void
00163 GPI::decay(double d) {
00164 m.acquire();
00165 invd = 1.0 / d;
00166 m.release();
00167 }
00168
00169 forceinline GPI::Info*
00170 GPI::allocate(unsigned int p, unsigned int gid) {
00171 Info* c;
00172 m.acquire();
00173 if (b->free == 0) {
00174 Block* n = new Block;
00175 n->next = b; b = n;
00176 }
00177 c = &b->info[--b->free];
00178 m.release();
00179 c->init(p,gid);
00180 return c;
00181 }
00182
00183 forceinline GPI::Info*
00184 GPI::allocate(unsigned int gid) {
00185 Info* c;
00186 m.acquire();
00187 if (b->free == 0) {
00188 Block* n = new Block;
00189 n->next = b; b = n;
00190 }
00191 c = &b->info[--b->free];
00192 c->init(npid++,gid);
00193 m.release();
00194 return c;
00195 }
00196
00197 forceinline
00198 GPI::~GPI(void) {
00199 Block* n = b;
00200 while (n != &fst) {
00201 Block* d = n;
00202 n = n->next;
00203 delete d;
00204 }
00205 }
00206
00207 }}
00208
00209