Generated on Thu Apr 11 13:59:15 2019 for Gecode by doxygen 1.6.3

gpi.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2009
00008  *
00009  *  This file is part of Gecode, the generic constraint
00010  *  development environment:
00011  *     http://www.gecode.org
00012  *
00013  *  Permission is hereby granted, free of charge, to any person obtaining
00014  *  a copy of this software and associated documentation files (the
00015  *  "Software"), to deal in the Software without restriction, including
00016  *  without limitation the rights to use, copy, modify, merge, publish,
00017  *  distribute, sublicense, and/or sell copies of the Software, and to
00018  *  permit persons to whom the Software is furnished to do so, subject to
00019  *  the following conditions:
00020  *
00021  *  The above copyright notice and this permission notice shall be
00022  *  included in all copies or substantial portions of the Software.
00023  *
00024  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00028  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00029  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00030  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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 // STATISTICS: kernel-prop