Generated on Fri Oct 19 11:25:13 2018 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 pid;
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     bool unshare(void);
00098     ~GPI(void);
00099   };
00100 
00101 
00102   forceinline void
00103   GPI::Info::init(unsigned int pid0, unsigned int gid0) {
00104     pid=pid0; gid=gid0; afc=1.0;
00105   }
00106 
00107 
00108   forceinline
00109   GPI::Block::Block(void)
00110     : next(NULL), free(n_info) {}
00111 
00112   forceinline void
00113   GPI::Block::rescale(void) {
00114     for (int i=free; i < n_info; i++)
00115       info[i].afc *= Kernel::Config::rescale;
00116   }
00117 
00118 
00119   forceinline
00120   GPI::GPI(void)
00121     : b(&fst), invd(1.0), pid(0U), us(false) {}
00122 
00123   forceinline void
00124   GPI::fail(Info& c) {
00125     m.acquire();
00126     c.afc = invd * (c.afc + 1.0);
00127     if (c.afc > Kernel::Config::rescale_limit)
00128       for (Block* i = b; i != NULL; i = i->next)
00129         i->rescale();
00130     m.release();
00131   }
00132 
00133   forceinline double
00134   GPI::decay(void) const {
00135     double d;
00136     const_cast<GPI&>(*this).m.acquire();
00137     d = 1.0 / invd;
00138     const_cast<GPI&>(*this).m.release();
00139     return d;
00140   }
00141 
00142   forceinline bool
00143   GPI::unshare(void) {
00144     bool u;
00145     m.acquire();
00146     u = us; us = true;
00147     m.release();
00148     return u;
00149   }
00150 
00151   forceinline void
00152   GPI::decay(double d) {
00153     m.acquire();
00154     invd = 1.0 / d;
00155     m.release();
00156   }
00157 
00158   forceinline GPI::Info*
00159   GPI::allocate(unsigned int p, unsigned int gid) {
00160     Info* c;
00161     m.acquire();
00162     if (b->free == 0) {
00163       Block* n = new Block;
00164       n->next = b; b = n;
00165     }
00166     c = &b->info[--b->free];
00167     m.release();
00168     c->init(p,gid);
00169     return c;
00170   }
00171 
00172   forceinline GPI::Info*
00173   GPI::allocate(unsigned int gid) {
00174     Info* c;
00175     m.acquire();
00176     if (b->free == 0) {
00177       Block* n = new Block;
00178       n->next = b; b = n;
00179     }
00180     c = &b->info[--b->free];
00181     c->init(pid++,gid);
00182     m.release();
00183     return c;
00184   }
00185 
00186   forceinline
00187   GPI::~GPI(void) {
00188     Block* n = b;
00189     while (n != &fst) {
00190       Block* d = n;
00191       n = n->next;
00192       delete d;
00193     }
00194   }
00195 
00196 }}
00197 
00198 // STATISTICS: kernel-prop