this repo has no description
at develop 209 lines 5.2 kB view raw
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * 6 * Copyright: 7 * Christian Schulte, 2009 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34#include <cmath> 35 36namespace Gecode { namespace Kernel { 37 38 /// Global propagator information 39 class GPI { 40 public: 41 /// Class for storing propagator information 42 class Info { 43 public: 44 /// Propagator identifier 45 unsigned int pid; 46 /// Group identifier 47 unsigned int gid; 48 /// The afc value 49 double afc; 50 /// Initialize 51 void init(unsigned int pid, unsigned int gid); 52 }; 53 private: 54 /// Block of propagator information 55 class Block : public HeapAllocated { 56 public: 57 /// Number of propagator information entries in a block 58 static const int n_info = 8192; 59 /// Info entries 60 Info info[n_info]; 61 /// Next block 62 Block* next; 63 /// Number of free blocks 64 int free; 65 /// Initialize 66 Block(void); 67 /// Rescale used afc values in entries 68 void rescale(void); 69 }; 70 /// The current block 71 Block* b; 72 /// The inverse decay factor 73 double invd; 74 /// Next free propagator id 75 unsigned int npid; 76 /// Whether to unshare 77 bool us; 78 /// The first block 79 Block fst; 80 /// Mutex to synchronize globally shared access 81 GECODE_KERNEL_EXPORT static Support::Mutex m; 82 public: 83 /// Initialize 84 GPI(void); 85 /// Set decay factor to \a d 86 void decay(double d); 87 /// Return decay factor 88 double decay(void) const; 89 /// Increment failure count 90 void fail(Info& c); 91 /// Allocate info for existing propagator with pid \a p 92 Info* allocate(unsigned int p, unsigned int gid); 93 /// Allocate new actor info 94 Info* allocate(unsigned int gid); 95 /// Return next free propagator id 96 unsigned int pid(void) const; 97 /// Provide access to unshare info and set to true 98 bool unshare(void); 99 /// Delete 100 ~GPI(void); 101 }; 102 103 104 forceinline void 105 GPI::Info::init(unsigned int pid0, unsigned int gid0) { 106 pid=pid0; gid=gid0; afc=1.0; 107 } 108 109 110 forceinline 111 GPI::Block::Block(void) 112 : next(nullptr), free(n_info) {} 113 114 forceinline void 115 GPI::Block::rescale(void) { 116 for (int i=free; i < n_info; i++) 117 info[i].afc *= Kernel::Config::rescale; 118 } 119 120 121 forceinline 122 GPI::GPI(void) 123 : b(&fst), invd(1.0), npid(0U), us(false) {} 124 125 forceinline void 126 GPI::fail(Info& c) { 127 m.acquire(); 128 c.afc = invd * (c.afc + 1.0); 129 if (c.afc > Kernel::Config::rescale_limit) 130 for (Block* i = b; i != nullptr; i = i->next) 131 i->rescale(); 132 m.release(); 133 } 134 135 forceinline double 136 GPI::decay(void) const { 137 double d; 138 const_cast<GPI&>(*this).m.acquire(); 139 d = 1.0 / invd; 140 const_cast<GPI&>(*this).m.release(); 141 return d; 142 } 143 144 forceinline unsigned int 145 GPI::pid(void) const { 146 unsigned int p; 147 const_cast<GPI&>(*this).m.acquire(); 148 p = npid; 149 const_cast<GPI&>(*this).m.release(); 150 return p; 151 } 152 153 forceinline bool 154 GPI::unshare(void) { 155 bool u; 156 m.acquire(); 157 u = us; us = true; 158 m.release(); 159 return u; 160 } 161 162 forceinline void 163 GPI::decay(double d) { 164 m.acquire(); 165 invd = 1.0 / d; 166 m.release(); 167 } 168 169 forceinline GPI::Info* 170 GPI::allocate(unsigned int p, unsigned int gid) { 171 Info* c; 172 m.acquire(); 173 if (b->free == 0) { 174 Block* n = new Block; 175 n->next = b; b = n; 176 } 177 c = &b->info[--b->free]; 178 m.release(); 179 c->init(p,gid); 180 return c; 181 } 182 183 forceinline GPI::Info* 184 GPI::allocate(unsigned int gid) { 185 Info* c; 186 m.acquire(); 187 if (b->free == 0) { 188 Block* n = new Block; 189 n->next = b; b = n; 190 } 191 c = &b->info[--b->free]; 192 c->init(npid++,gid); 193 m.release(); 194 return c; 195 } 196 197 forceinline 198 GPI::~GPI(void) { 199 Block* n = b; 200 while (n != &fst) { 201 Block* d = n; 202 n = n->next; 203 delete d; 204 } 205 } 206 207}} 208 209// STATISTICS: kernel-prop