MFMv2.0.10
Movable Feast Machine Simulator 2.0.10
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tile.h
Go to the documentation of this file.
1 /* -*- mode:C++ -*-
2  Tile.h MFM grid segment
3  Copyright (C) 2014 The Regents of the University of New Mexico. All rights reserved.
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
28 #ifndef TILE_H
29 #define TILE_H
30 
31 #include <pthread.h>
32 #include "Dirs.h"
33 #include "Random.h" /* for Random */
34 #include "Packet.h"
35 #include "Point.h"
36 #include "EventWindow.h"
37 #include "ElementTable.h"
38 #include "Connection.h"
39 #include "ThreadPauser.h"
40 #include "OverflowableCharBufferByteSink.h" /* for OString16 */
41 
42 namespace MFM
43 {
44 #define IS_OWNED_CONNECTION(X) ((X) - Dirs::EAST >= 0 && (X) - Dirs::EAST < 4)
45 
46 #define BACKGROUND_RADIATION_SITE_ODDS 1000
47 #define BACKGROUND_RADIATION_BIT_ODDS 100
48 
53  typedef enum
54  {
55  REGION_CACHE = 0,
56  REGION_SHARED = 1,
57  REGION_VISIBLE = 2,
58  REGION_HIDDEN = 3,
59  REGION_COUNT
60  }TileRegion;
61 
66  typedef enum
67  {
68  LOCKTYPE_NONE = 0,
69  LOCKTYPE_SINGLE = 1,
70  LOCKTYPE_TRIPLE = 2,
71  LOCKTYPE_COUNT
72  }LockType;
73 
78  template <class CC>
79  class Tile
80  {
81  // Extract short names for parameter types
82  typedef typename CC::ATOM_TYPE T;
83  typedef typename CC::PARAM_CONFIG P;
84  enum { R = P::EVENT_WINDOW_RADIUS };
85  enum { W = P::TILE_WIDTH };
86  enum { B = P::ELEMENT_TABLE_BITS };
87 
88  public:
89 
91  static const u32 EVENT_WINDOW_RADIUS = R;
92 
95  static const u32 TILE_WIDTH = W;
96 
100  static const u32 TILE_SIZE = TILE_WIDTH * TILE_WIDTH;
101 
102  static const u32 ELEMENT_TABLE_BITS = B; // Currently hard-coded!
103  static const u32 ELEMENT_TABLE_SIZE = 1u<<ELEMENT_TABLE_BITS;
104 
109  static const u32 OWNED_SIDE = TILE_WIDTH-2*R;
110 
111  private:
115  OString16 m_label;
116 
119  MFMErrorEnvironmentPointer_t m_errorEnvironmentStackTop;
120 
124  bool m_backgroundRadiationEnabled;
125 
131  bool m_ignoreThreadingProblems;
132 
133 #if 0
134 
136  u32 m_writeFailureOdds;
137 #endif
138 
141  ElementTable<CC> elementTable;
142 
144  Random m_random;
145 
148  u64 m_eventsExecuted;
149 
152  u32 m_eventsFailed;
153 
156  u32 m_failuresErased;
157 
164  u64 m_regionEvents[REGION_COUNT];
165 
170  u64 m_lockEvents[LOCKTYPE_COUNT];
171 
172  // Quick hack counts trying to debug vanishing atoms
173  u64 m_lockAttempts;
174  u64 m_lockAttemptsSucceeded;
175 
180  u64 m_siteEvents[OWNED_SIDE][OWNED_SIDE];
181 
186  u64 m_lastChangedEventNumber[OWNED_SIDE][OWNED_SIDE];
187 
188  friend class EventWindow<CC>;
189 
191  T m_atoms[TILE_WIDTH][TILE_WIDTH];
192 
195  s32 m_atomCount[ELEMENT_TABLE_SIZE];
196 
198  bool m_needRecount;
199 
202  s32 m_illegalAtomCount;
203 
206  SPoint m_lastExecutedAtom;
207 
209  EventWindow<CC> m_executingWindow;
210 
213  Connection* m_connections[8];
214 
217  bool m_iLocked[8];
218 
220  bool m_isFnWing;
221  u32 m_curFnWingDirWaitWord;
222  u32 m_origFnWingDirWaitWord;
223 
225  bool m_isA2PRed;
226 
228  bool m_isGSBIsw;
229 
234  Connection m_ownedConnections[4];
235 
241  pthread_t m_thread;
242 
247  bool m_threadInitialized;
248 
253  bool IsPausedOrOwner()
254  {
255  return m_threadPauser.GetStateNonblocking()==THREADSTATE_PAUSED
256  || pthread_equal(pthread_self(), m_thread);
257  }
258 
259 #if 0
260 
267  bool m_threadPaused;
268 #endif
269 
276  bool m_executeOwnEvents;
277 
284  ThreadPauser m_threadPauser;
285 
290  u8 m_generation;
291 
301  bool IsOwnedConnection(Dir dir);
302 
307  void CreateRandomWindow();
308 
315  void CreateWindowAt(const SPoint& pt);
316 
327  u32 SendRelevantAtoms();
328 
340  void SendEndEventPackets(u32 dirWaitWord);
341 
342 
355  static SPoint GetNeighborLoc(Dir neighbor, const SPoint& atomLoc);
356 
369  void SendAtom(Dir neighbor, SPoint& atomLoc);
370 
381  bool TryLock(Dir connectionDir);
382 
396  bool TryLockCorner(Dir cornerDir);
397 
409  bool LockRegion(Dir regionDir);
410 
420  void UnlockCorner(Dir corner);
421 
422  void UnlockDir(Dir dir) ;
423 
434  void UnlockRegion(Dir regionDir);
435 
444  TileRegion RegionFromIndex(const u32 index);
445 
457  TileRegion RegionIn(const SPoint& pt);
458 
467  inline bool IsInHidden(const SPoint& pt);
468 
472  void DoEvent(bool locked, Dir lockRegion);
473 
474  public:
475  void ReportTileStatus(Logger::Level level);
476 
481  const char * GetLabel()
482  {
483  return m_label.GetZString();
484  }
485 
490  {
491  return m_label;
492  }
493 
497  Tile();
498 
511  void SetIgnoreThreadingProblems(bool value);
512 
517  void Reinit();
518 
522  void ClearAtoms();
523 
534  void CheckCacheFromDir(Dir direction, const Tile & otherTile);
535 
539  void SetGeneration(u8 generation)
540  {
541  m_generation = generation;
542  }
543 
547  u8 GetGeneration() const
548  {
549  return m_generation;
550  }
551 
559  void Connect(Tile<CC>& other, Dir toCache);
560 
570  Connection* GetConnection(Dir cache);
571 
575  u32 GetSites() const
576  {
577  return OWNED_SIDE*OWNED_SIDE;
578  }
579 
584  {
585  return TILE_WIDTH;
586  }
587 
592  Random & GetRandom();
593 
600  {
601  return elementTable;
602  }
603 
610  {
611  return elementTable;
612  }
613 
620  const Element<CC> * GetElement(const u32 elementType) const
621  {
622  return elementTable.Lookup(elementType);
623  }
624 
634  inline bool IsConnected(Dir dir) const;
635 
636  bool HasAnyConnections(Dir regionDir) const;
637 
647  static inline bool IsInCache(const SPoint& pt);
648 
658  static inline bool IsOwnedSite(const SPoint & location);
659 
660 
674  static inline bool IsInTile(const SPoint& pt);
675 
693  static inline bool IsInUncachedTile(const SPoint& pt);
694 
708  bool IsLiveSite(const SPoint & location) const;
709 
717  u64 GetEventsExecuted() const
718  {
719  return m_eventsExecuted;
720  }
721 
737  Dir RegionAt(const SPoint& pt, u32 reach) const;
738 
747  Dir CacheAt(const SPoint& pt) const;
748 
759  Dir SharedAt(const SPoint& pt) const;
760 
771  Dir VisibleAt(const SPoint& pt) const;
772 
780  const T* GetAtom(const SPoint& pt) const
781  {
782  return GetAtom(pt.GetX(), pt.GetY());
783  }
784 
799  T* GetWritableAtom(const SPoint& pt)
800  {
801  return GetWritableAtom(pt.GetX(), pt.GetY());
802  }
803 
815  const T* GetAtom(s32 x, s32 y) const
816  {
817  if (((u32) x) >= TILE_WIDTH || ((u32) y) >= TILE_WIDTH)
818  {
819  FAIL(ARRAY_INDEX_OUT_OF_BOUNDS);
820  }
821  return &m_atoms[x][y];
822  }
823 
842  T* GetWritableAtom(s32 x, s32 y)
843  {
844  if (((u32) x) >= TILE_WIDTH || ((u32) y) >= TILE_WIDTH)
845  {
846  FAIL(ARRAY_INDEX_OUT_OF_BOUNDS);
847  }
848  return &m_atoms[x][y];
849  }
850 
860  const T* GetUncachedAtom(const SPoint& pt) const
861  {
862  return GetUncachedAtom(pt.GetX(), pt.GetY());
863  }
864 
878  const T* GetUncachedAtom(s32 x, s32 y) const
879  {
880  return GetAtom(x+R, y+R);
881  }
882 
883 
897  u64 GetUncachedSiteEvents(const SPoint site) const ;
898 
915  u32 GetUncachedWriteAge(const SPoint site) const ;
916 
925  void SendAcknowledgmentPacket(Packet<T>& packet);
926 
933  void ReceivePacket(Packet<T>& packet);
934 
935 #if 0 /* Doesn't exist? */
936 
943  Packet<T>* NextPacket();
944 #endif
945 
953  void FillLastExecutedAtom(SPoint& out);
954 
963  void PlaceAtom(const T& atom, const SPoint& pt);
964 
977  void PlaceInternalAtom(const T& atom, const SPoint& pt)
978  {
979  PlaceAtom(atom,pt+SPoint(R,R));
980  }
981 
992  bool FlushAndWaitOnAllBuffers(u32 dirWaitWord);
993 
998 
1008  void SetExecuteOwnEvents(bool value)
1009  {
1010  m_executeOwnEvents = value;
1011  }
1012 
1021  {
1022  return m_executeOwnEvents;
1023  }
1024 
1028  void Execute();
1029 
1036  static void* ExecuteThreadHelper(void* tilePtr);
1037 
1048  u32 GetAtomCount(ElementType atomType) const;
1049 
1059  void InternalPutAtom(const T & atom, s32 x, s32 y);
1060 
1069  void SetAtomCount(ElementType atomType, s32 count);
1070 
1077  void Start();
1078 
1085  void Pause();
1086 
1095  bool IsRunReady()
1096  {
1097  return m_threadPauser.IsRunReady();
1098  }
1099 
1104  void Run()
1105  {
1106  m_threadPauser.Run();
1107  }
1108 
1118  bool IsPauseReady();
1119 
1120  void RequestPause();
1121 
1131  void IncrAtomCount(ElementType atomType, s32 delta);
1132 
1136  void AssertValidAtomCounts() const;
1137 
1142  void RecountAtomsIfNeeded();
1143 
1148  void RecountAtoms();
1149 
1157  u64 WriteEPSRasterLine(ByteSink & outstrm, u32 lineIdx);
1158 
1164  void RegisterElement(const Element<CC> & anElement)
1165  {
1166  elementTable.RegisterElement(anElement);
1167  }
1168 
1173  void SetBackgroundRadiation(bool value)
1174  {
1175  m_backgroundRadiationEnabled = value;
1176  }
1177 
1182  inline void SingleXRay();
1183 
1192  inline void SingleXRay(u32 x, u32 y);
1193 
1204  void XRay(u32 siteOdds, u32 bitOdds);
1205 
1206  };
1207 } /* namespace MFM */
1208 
1209 #include "Tile.tcc"
1210 
1211 #endif /*TILE_H*/
bool GetExecutingOwnEvents() const
Definition: Tile.h:1020
u32 GetAtomCount(ElementType atomType) const
Definition: Tile.tcc:1095
u32 GetUncachedWriteAge(const SPoint site) const
Definition: Tile.tcc:207
Dir SharedAt(const SPoint &pt) const
Definition: Tile.tcc:353
T * GetWritableAtom(s32 x, s32 y)
Definition: Tile.h:842
static const u32 TILE_SIZE
Definition: Tile.h:100
void SetBackgroundRadiation(bool value)
Definition: Tile.h:1173
u64 GetUncachedSiteEvents(const SPoint site) const
Definition: Tile.tcc:197
bool FlushAndWaitOnAllBuffers(u32 dirWaitWord)
Definition: Tile.tcc:860
bool IsConnected(Dir dir) const
Definition: Tile.tcc:482
void FillLastExecutedAtom(SPoint &out)
Definition: Tile.tcc:281
void SendAcknowledgmentPacket(Packet< T > &packet)
Definition: Tile.tcc:228
u8 GetGeneration() const
Definition: Tile.h:547
Level
Definition: Logger.h:52
Definition: Random.h:45
static bool IsOwnedSite(const SPoint &location)
Definition: Tile.tcc:496
void ReceivePacket(Packet< T > &packet)
Definition: Tile.tcc:241
const ElementTable< CC > & GetElementTable() const
Definition: Tile.h:609
static void * ExecuteThreadHelper(void *tilePtr)
Definition: Tile.tcc:1086
void Start()
Definition: Tile.tcc:1121
static const u32 EVENT_WINDOW_RADIUS
Definition: Tile.h:91
void XRay(u32 siteOdds, u32 bitOdds)
Definition: Tile.tcc:1359
const T * GetUncachedAtom(s32 x, s32 y) const
Definition: Tile.h:878
void AssertValidAtomCounts() const
Definition: Tile.tcc:1272
bool IsLiveSite(const SPoint &location) const
Definition: Tile.tcc:489
Definition: ThreadPauser.h:140
static bool IsInUncachedTile(const SPoint &pt)
Definition: Tile.tcc:516
static const u32 TILE_WIDTH
Definition: Tile.h:95
const char * GetZString()
Definition: OverflowableCharBufferByteSink.h:143
Connection * GetConnection(Dir cache)
Definition: Tile.tcc:185
u32 GetTileWidth()
Definition: Tile.h:583
T GetY() const
Definition: Point.tcc:40
Dir RegionAt(const SPoint &pt, u32 reach) const
Definition: Tile.tcc:305
u32 GetSites() const
Definition: Tile.h:575
void SetIgnoreThreadingProblems(bool value)
Definition: Tile.tcc:22
void Run()
Definition: ThreadPauser.h:301
static bool IsInCache(const SPoint &pt)
Definition: Tile.tcc:502
bool IsRunReady()
Definition: Tile.h:1095
Dir VisibleAt(const SPoint &pt) const
Definition: Tile.tcc:359
void Pause()
Definition: Tile.tcc:1137
Definition: Packet.h:71
Definition: ByteSink.h:47
void InternalPutAtom(const T &atom, s32 x, s32 y)
Definition: Tile.tcc:218
void Run()
Definition: Tile.h:1104
void SetGeneration(u8 generation)
Definition: Tile.h:539
static const u32 OWNED_SIDE
Definition: Tile.h:109
void Connect(Tile< CC > &other, Dir toCache)
Definition: Tile.tcc:170
void RecountAtomsIfNeeded()
Definition: Tile.tcc:1309
Random & GetRandom()
Definition: Tile.tcc:191
void PlaceInternalAtom(const T &atom, const SPoint &pt)
Definition: Tile.h:977
void SetAtomCount(ElementType atomType, s32 count)
Definition: Tile.tcc:1106
Definition: EventWindow.h:41
Definition: ElementTable.h:46
ElementTable< CC > & GetElementTable()
Definition: Tile.h:599
const T * GetAtom(const SPoint &pt) const
Definition: Tile.h:780
void SingleXRay()
Definition: Tile.tcc:1347
const T * GetUncachedAtom(const SPoint &pt) const
Definition: Tile.h:860
Definition: ElementTable.h:43
void ClearAtoms()
Definition: Tile.tcc:102
const T * GetAtom(s32 x, s32 y) const
Definition: Tile.h:815
static bool IsInTile(const SPoint &pt)
Definition: Tile.tcc:510
void Execute()
Definition: Tile.tcc:1003
Dir CacheAt(const SPoint &pt) const
Definition: Tile.tcc:347
void RegisterElement(const Element< CC > &anElement)
Definition: Tile.h:1164
void Reinit()
Definition: Tile.tcc:29
T * GetWritableAtom(const SPoint &pt)
Definition: Tile.h:799
OString16 & GetLabelPrinter()
Definition: Tile.h:489
Tile()
Definition: Tile.tcc:12
void IncrAtomCount(ElementType atomType, s32 delta)
Definition: Tile.tcc:1162
bool IsRunReady()
Definition: ThreadPauser.h:310
Definition: Atom.h:43
u64 GetEventsExecuted() const
Definition: Tile.h:717
void CheckCacheFromDir(Dir direction, const Tile &otherTile)
Definition: Tile.tcc:123
u64 WriteEPSRasterLine(ByteSink &outstrm, u32 lineIdx)
const char * GetLabel()
Definition: Tile.h:481
void ReportIfBuffersAreNonEmpty()
Definition: Tile.tcc:819
const Element< CC > * GetElement(const u32 elementType) const
Definition: Tile.h:620
void RecountAtoms()
Definition: Tile.tcc:1320
Definition: Connection.h:44
bool IsPauseReady()
Definition: Tile.tcc:1150
void PlaceAtom(const T &atom, const SPoint &pt)
Definition: Tile.tcc:365
void SetExecuteOwnEvents(bool value)
Definition: Tile.h:1008
T GetX() const
Definition: Point.tcc:34