From 2706a996d024cd95e76c1da67bf7ae267ba76c19 Mon Sep 17 00:00:00 2001
From: Ansgar Burchardt <Ansgar.Burchardt@tu-dresden.de>
Date: Thu, 26 Apr 2018 18:22:59 +0200
Subject: [PATCH] DDD: xfer: add more state to context object

---
 dune/uggrid/parallel/ddd/dddcontext.hh |  5 ++
 dune/uggrid/parallel/ddd/dddtypes.hh   |  4 ++
 parallel/ddd/include/ddd.h             |  2 +-
 parallel/ddd/xfer/cmds.cc              | 53 +++++++---------
 parallel/ddd/xfer/supp.cc              | 86 ++++++++++++--------------
 parallel/ddd/xfer/xfer.h               | 42 ++++++++-----
 parallel/dddif/handler.cc              |  6 +-
 7 files changed, 103 insertions(+), 95 deletions(-)

diff --git a/dune/uggrid/parallel/ddd/dddcontext.hh b/dune/uggrid/parallel/ddd/dddcontext.hh
index 94efc3012..26e248530 100644
--- a/dune/uggrid/parallel/ddd/dddcontext.hh
+++ b/dune/uggrid/parallel/ddd/dddcontext.hh
@@ -175,6 +175,11 @@ struct XferContext
   /* entry points for global sets */
   XICopyObjSet *setXICopyObj;
   XISetPrioSet *setXISetPrio;
+
+  XICopyObj* theXIAddData;
+
+  AddDataSegm* segmAddData = nullptr;
+  SizesSegm* segmSizes = nullptr;
 };
 
 } /* namespace Xfer */
diff --git a/dune/uggrid/parallel/ddd/dddtypes.hh b/dune/uggrid/parallel/ddd/dddtypes.hh
index 0865fcf02..9fda133eb 100644
--- a/dune/uggrid/parallel/ddd/dddtypes.hh
+++ b/dune/uggrid/parallel/ddd/dddtypes.hh
@@ -121,6 +121,10 @@ namespace Xfer {
 
 enum class XferMode : unsigned char;
 
+struct AddDataSegm;
+struct SizesSegm;
+
+struct XICopyObj;
 struct XICopyObjSet;
 struct XISetPrioSet;
 
diff --git a/parallel/ddd/include/ddd.h b/parallel/ddd/include/ddd.h
index 40f4b071b..65d5db241 100644
--- a/parallel/ddd/include/ddd.h
+++ b/parallel/ddd/include/ddd.h
@@ -365,7 +365,7 @@ void     DDD_IFAExecLocalX(DDD::DDDContext& context, DDD_IF,DDD_ATTR,
 /*
         Transfer Environment Module
  */
-bool     DDD_XferWithAddData();
+bool     DDD_XferWithAddData(const DDD::DDDContext& context);
 void     DDD_XferAddData(DDD::DDDContext& context, int, DDD_TYPE);
 void     DDD_XferAddDataX(DDD::DDDContext& context, int, DDD_TYPE, size_t sizes[]);
 int      DDD_XferIsPrunedDelete(const DDD::DDDContext& context, DDD_HDR);
diff --git a/parallel/ddd/xfer/cmds.cc b/parallel/ddd/xfer/cmds.cc
index 30586e1ee..317082c70 100644
--- a/parallel/ddd/xfer/cmds.cc
+++ b/parallel/ddd/xfer/cmds.cc
@@ -60,20 +60,6 @@ using namespace PPIF;
 /****************************************************************************/
 
 
-
-
-
-
-/****************************************************************************/
-/*                                                                          */
-/* definition of exported global variables                                  */
-/*                                                                          */
-/****************************************************************************/
-
-
-XICopyObj *theXIAddData;
-
-
 /****************************************************************************/
 /*                                                                          */
 /* definition of variables global to this source file only (static!)        */
@@ -291,7 +277,7 @@ static int unify_XIModCpl (const DDD::DDDContext& context, XIModCpl **i1p, XIMod
 
 
 /* TODO remove this */
-void GetSizesXIAddData (int *, int *, size_t *, size_t *);
+void GetSizesXIAddData (const DDD::DDDContext& context, int *, int *, size_t *, size_t *);
 
 
 /*
@@ -304,7 +290,7 @@ static void DisplayMemResources(const DDD::DDDContext& context)
   int nSegms=0, nItems=0, nNodes=0;
   size_t memAllocated=0, memUsed=0;
 
-  GetSizesXIAddData(&nSegms, &nItems, &memAllocated, &memUsed);
+  GetSizesXIAddData(context, &nSegms, &nItems, &memAllocated, &memUsed);
   if (nSegms>0)
     printf("%4d: XferEnd, XIAddData segms=%d items=%d allocated=%ld used=%ld\n",
            me, nSegms, nItems, (long)memAllocated, (long)memUsed);
@@ -779,7 +765,7 @@ exit:
   XICopyObjSet_Reset(reinterpret_cast<XICopyObjSet*>(ctx.setXICopyObj));
 
   if (arrayNewOwners!=NULL) OO_Free (arrayNewOwners /*,0*/);
-  FreeAllXIAddData();
+  FreeAllXIAddData(context);
 
   XISetPrioSet_Reset(reinterpret_cast<XISetPrioSet*>(ctx.setXISetPrio));
 
@@ -933,7 +919,7 @@ static void XferInitCopyInfo (DDD::DDDContext& context,
     /* although XferCopyObj degrades to SetPrio, call XFERCOPY-handler! */
 
     /* reset for eventual AddData-calls during handler execution */
-    theXIAddData = NULL;
+    ctx.theXIAddData = nullptr;
 
     /* call application handler for xfer of dependent objects */
     if (desc->handlerXFERCOPY)
@@ -944,7 +930,7 @@ static void XferInitCopyInfo (DDD::DDDContext& context,
     }
 
     /* theXIAddData might be changed during handler execution */
-    theXIAddData = NULL;
+    ctx.theXIAddData = nullptr;
   }
   else
   {
@@ -977,7 +963,7 @@ static void XferInitCopyInfo (DDD::DDDContext& context,
     xi->addLen = 0;
 
     /* set XferAddInfo for evtl AddData-calls during handler execution */
-    theXIAddData = xi;
+    ctx.theXIAddData = xi;
 
     /* call application handler for xfer of dependent objects */
     if (desc->handlerXFERCOPY)
@@ -988,7 +974,7 @@ static void XferInitCopyInfo (DDD::DDDContext& context,
     }
 
     /* theXIAddData might be changed during handler execution */
-    theXIAddData = xi;
+    ctx.theXIAddData = xi;
   }
 }
 
@@ -1142,15 +1128,17 @@ void DDD_XferCopyObjX (DDD::DDDContext& context, DDD_HDR hdr, DDD_PROC proc, DDD
 
 void DDD_XferAddData (DDD::DDDContext& context, int cnt, DDD_TYPE typ)
 {
+  auto& ctx = context.xferContext();
   XFERADDDATA *xa;
 
 #       if DebugXfer<=2
   Dune::dvverb << "DDD_XferAddData cnt=" << cnt << " typ=" << typ << "\n";
 #       endif
 
-  if (theXIAddData==NULL) return;
+  if (not ctx.theXIAddData)
+    return;
 
-  xa = NewXIAddData();
+  xa = NewXIAddData(context);
   if (xa==NULL)
     throw std::bad_alloc();
 
@@ -1174,7 +1162,7 @@ void DDD_XferAddData (DDD::DDDContext& context, int cnt, DDD_TYPE typ)
     xa->addNPointers = 0;
   }
 
-  theXIAddData->addLen += xa->addLen;
+  ctx.theXIAddData->addLen += xa->addLen;
 }
 
 
@@ -1192,6 +1180,7 @@ void DDD_XferAddData (DDD::DDDContext& context, int cnt, DDD_TYPE typ)
 
 void DDD_XferAddDataX (DDD::DDDContext& context, int cnt, DDD_TYPE typ, size_t *sizes)
 {
+  auto& ctx = context.xferContext();
   XFERADDDATA *xa;
   TYPE_DESC   *descDepTyp;
   int i;
@@ -1200,9 +1189,10 @@ void DDD_XferAddDataX (DDD::DDDContext& context, int cnt, DDD_TYPE typ, size_t *
   Dune::dvverb << "DDD_XferAddData cnt=" << cnt << " typ=" << typ << "\n";
 #       endif
 
-  if (theXIAddData==NULL) return;
+  if (not ctx.theXIAddData)
+    return;
 
-  xa = NewXIAddData();
+  xa = NewXIAddData(context);
   if (xa==NULL)
     HARD_EXIT;
 
@@ -1212,7 +1202,7 @@ void DDD_XferAddDataX (DDD::DDDContext& context, int cnt, DDD_TYPE typ, size_t *
   if (typ<DDD_USER_DATA || typ>DDD_USER_DATA_MAX)
   {
     /* copy sizes array */
-    xa->sizes = AddDataAllocSizes(cnt);
+    xa->sizes = AddDataAllocSizes(context, cnt);
     memcpy(xa->sizes, sizes, sizeof(int)*cnt);
 
     /* normal dependent object */
@@ -1233,7 +1223,7 @@ void DDD_XferAddDataX (DDD::DDDContext& context, int cnt, DDD_TYPE typ, size_t *
     xa->addNPointers = 0;
   }
 
-  theXIAddData->addLen += xa->addLen;
+  ctx.theXIAddData->addLen += xa->addLen;
 }
 
 
@@ -1255,12 +1245,12 @@ void DDD_XferAddDataX (DDD::DDDContext& context, int cnt, DDD_TYPE typ, size_t *
    @return #true# if additional data objects will be gathered, sent
                 and scattered; #false# otherwise.
  */
-bool DDD_XferWithAddData()
+bool DDD_XferWithAddData(const DDD::DDDContext& context)
 {
   /* if theXIAddData==NULL, the XferAddData-functions will
      do nothing -> the Gather/Scatter-handlers will not be
      called. */
-  return theXIAddData != nullptr;
+  return context.xferContext().theXIAddData != nullptr;
 }
 
 
@@ -1324,7 +1314,8 @@ void DDD_XferDeleteObj (DDD::DDDContext& context, DDD_HDR hdr)
 
 void DDD_XferBegin(DDD::DDDContext& context)
 {
-  theXIAddData = NULL;
+  auto& ctx = context.xferContext();
+  ctx.theXIAddData = nullptr;
 
 
   /* step mode and check whether call to XferBegin is valid */
diff --git a/parallel/ddd/xfer/supp.cc b/parallel/ddd/xfer/supp.cc
index e9ebf349a..fda8991f2 100644
--- a/parallel/ddd/xfer/supp.cc
+++ b/parallel/ddd/xfer/supp.cc
@@ -90,10 +90,6 @@ void xfer_FreeSend (void *buffer)
 
 
 
-/* defined in cmds.c */
-extern XICopyObj *theXIAddData;
-
-
 /****************************************************************************/
 /*                                                                          */
 /* definition of constants, macros                                          */
@@ -112,6 +108,10 @@ extern XICopyObj *theXIAddData;
 /*                                                                          */
 /****************************************************************************/
 
+END_UGDIM_NAMESPACE
+namespace DDD {
+namespace Xfer {
+
 /* segment of AddDatas */
 struct AddDataSegm
 {
@@ -131,21 +131,11 @@ struct SizesSegm
   int data[SIZESSEGM_SIZE];
 };
 
+} /* namespace Xfer */
+} /* namespace DDD */
+START_UGDIM_NAMESPACE
 
-
-
-/****************************************************************************/
-/*                                                                          */
-/* definition of static variables                                           */
-/*                                                                          */
-/****************************************************************************/
-
-
-
-
-static AddDataSegm *segmAddData = NULL;
-static SizesSegm   *segmSizes   = NULL;
-
+using namespace DDD::Xfer;
 
 /****************************************************************************/
 /*                                                                          */
@@ -312,25 +302,27 @@ void Method(Print) (ParamThis _PRINTPARAMS)
 /****************************************************************************/
 
 
-static AddDataSegm *NewAddDataSegm (void)
+static AddDataSegm *NewAddDataSegm(DDD::DDDContext& context)
 {
+  auto& ctx = context.xferContext();
   AddDataSegm *segm;
 
   segm = (AddDataSegm *) OO_Allocate(sizeof(AddDataSegm));
   if (segm==NULL)
     throw std::bad_alloc();
 
-  segm->next   = segmAddData;
-  segmAddData  = segm;
-  segm->nItems = 0;
+  segm->next      = ctx.segmAddData;
+  ctx.segmAddData = segm;
+  segm->nItems    = 0;
 
   return(segm);
 }
 
 
-static void FreeAddDataSegms (void)
+static void FreeAddDataSegms(DDD::DDDContext& context)
 {
-  AddDataSegm *segm = segmAddData;
+  auto& ctx = context.xferContext();
+  AddDataSegm *segm = ctx.segmAddData;
   AddDataSegm *next = NULL;
 
   while (segm!=NULL)
@@ -341,32 +333,34 @@ static void FreeAddDataSegms (void)
     segm = next;
   }
 
-  segmAddData = NULL;
+  ctx.segmAddData = nullptr;
 }
 
 
 /****************************************************************************/
 
 
-static SizesSegm *NewSizesSegm (void)
+static SizesSegm *NewSizesSegm(DDD::DDDContext& context)
 {
+  auto& ctx = context.xferContext();
   SizesSegm *segm;
 
   segm = (SizesSegm *) OO_Allocate (sizeof(SizesSegm));
   if (segm==NULL)
     throw std::bad_alloc();
 
-  segm->next    = segmSizes;
-  segmSizes     = segm;
+  segm->next    = ctx.segmSizes;
+  ctx.segmSizes = segm;
   segm->current = 0;
 
   return(segm);
 }
 
 
-static void FreeSizesSegms (void)
+static void FreeSizesSegms(DDD::DDDContext& context)
 {
-  SizesSegm *segm = segmSizes;
+  auto& ctx = context.xferContext();
+  SizesSegm *segm = ctx.segmSizes;
   SizesSegm *next = NULL;
 
   while (segm!=NULL)
@@ -377,49 +371,51 @@ static void FreeSizesSegms (void)
     segm = next;
   }
 
-  segmSizes = NULL;
+  ctx.segmSizes = nullptr;
 }
 
 
 /****************************************************************************/
 
 
-XFERADDDATA *NewXIAddData (void)
+XFERADDDATA *NewXIAddData(DDD::DDDContext& context)
 {
-  AddDataSegm *segm = segmAddData;
+  auto& ctx = context.xferContext();
+  AddDataSegm *segm = ctx.segmAddData;
   XFERADDDATA *xa;
 
   if (segm==NULL || segm->nItems==ADDDATASEGM_SIZE)
   {
-    segm = NewAddDataSegm();
+    segm = NewAddDataSegm(context);
   }
 
   xa = &(segm->item[segm->nItems++]);
-  xa->next = theXIAddData->add;
-  theXIAddData->add = xa;
+  xa->next = ctx.theXIAddData->add;
+  ctx.theXIAddData->add = xa;
 
   return(xa);
 }
 
 
 
-void FreeAllXIAddData (void)
+void FreeAllXIAddData(DDD::DDDContext& context)
 {
-  FreeAddDataSegms();
-  FreeSizesSegms();
+  FreeAddDataSegms(context);
+  FreeSizesSegms(context);
 }
 
 
 /****************************************************************************/
 
-int *AddDataAllocSizes (int cnt)
+int *AddDataAllocSizes (DDD::DDDContext& context, int cnt)
 {
-  SizesSegm *segm = segmSizes;
+  auto& ctx = context.xferContext();
+  SizesSegm *segm = ctx.segmSizes;
   int *pos;
 
   if (segm==NULL || segm->current+cnt>=SIZESSEGM_SIZE)
   {
-    segm = NewSizesSegm();
+    segm = NewSizesSegm(context);
   }
 
   pos = segm->data + segm->current;
@@ -435,14 +431,14 @@ int *AddDataAllocSizes (int cnt)
 /*
         get quantitative resource usage
  */
-void GetSizesXIAddData (int *nSegms, int *nItems, size_t *alloc_mem, size_t *used_mem)
+void GetSizesXIAddData(const DDD::DDDContext& context, int *nSegms, int *nItems, size_t *alloc_mem, size_t *used_mem)
 {
+  const auto& ctx = context.xferContext();
   size_t allocated=0, used=0;
   int ns=0, ni=0;
 
   {
-    AddDataSegm  *segm;
-    for (segm=segmAddData; segm!=NULL; segm=segm->next)
+    for (const AddDataSegm* segm=ctx.segmAddData; segm!=NULL; segm=segm->next)
     {
       /* count number of segments and number of items */
       ns++;
diff --git a/parallel/ddd/xfer/xfer.h b/parallel/ddd/xfer/xfer.h
index 7da4845b8..991393563 100644
--- a/parallel/ddd/xfer/xfer.h
+++ b/parallel/ddd/xfer/xfer.h
@@ -118,6 +118,7 @@ START_UGDIM_NAMESPACE
 
 using DDD::Xfer::XferMode;
 
+END_UGDIM_NAMESPACE
 
 /****************************************************************************/
 
@@ -136,6 +137,8 @@ using DDD::Xfer::XferMode;
 /*                                                                          */
 /****************************************************************************/
 
+namespace DDD {
+namespace Xfer {
 
 /****************************************************************************/
 /* XFERADDDATA: description of additional data on sender side               */
@@ -156,22 +159,31 @@ struct XFERADDDATA {
 /* XICopyObj:                                                               */
 /****************************************************************************/
 
-#define ClassName XICopyObj
-Class_Data_Begin
-DDD_HDR hdr;                    /* local obj for which a copy should be created */
-DDD_GID gid;                    /* gid of local object                          */
-DDD_PROC dest;                  /* proc involved with operation, me -> proc     */
-DDD_PRIO prio;                  /* priority for new object copy                 */
-size_t size;                    /* V1.2: needed for variable-sized objects      */
+struct XICopyObj
+{
+  DDD_HDR hdr;                    /* local obj for which a copy should be created */
+  DDD_GID gid;                    /* gid of local object                          */
+  DDD_PROC dest;                  /* proc involved with operation, me -> proc     */
+  DDD_PRIO prio;                  /* priority for new object copy                 */
+  size_t size;                    /* V1.2: needed for variable-sized objects      */
 
-int addLen;
-XFERADDDATA *add;               /* additional data items                   */
+  int addLen;
+  XFERADDDATA *add;               /* additional data items                   */
 
-int flags;
-Class_Data_End
+  int flags;
+};
+
+} /* namespace Xfer */
+} /* namespace DDD */
+
+START_UGDIM_NAMESPACE
+
+using DDD::Xfer::XFERADDDATA;
+using DDD::Xfer::XICopyObj;
+
+#define ClassName XICopyObj
 void Method(Print)   (DefThis _PRINTPARAMS);
 int  Method(Compare) (ClassPtr, ClassPtr, const DDD::DDDContext* context);
-
 #undef ClassName
 
 
@@ -532,9 +544,9 @@ struct XFER_PER_PROC
 
 
 /* supp.c */
-XFERADDDATA *NewXIAddData (void);
-void FreeAllXIAddData (void);
-int *AddDataAllocSizes(int);
+XFERADDDATA *NewXIAddData(DDD::DDDContext& context);
+void FreeAllXIAddData(DDD::DDDContext& context);
+int *AddDataAllocSizes(DDD::DDDContext& context, int);
 void xfer_SetTmpMem (int);
 void *xfer_AllocTmp (size_t);
 void xfer_FreeTmp (void *);
diff --git a/parallel/dddif/handler.cc b/parallel/dddif/handler.cc
index 4763c1f2f..65f8b84a0 100644
--- a/parallel/dddif/handler.cc
+++ b/parallel/dddif/handler.cc
@@ -257,7 +257,7 @@ static void VectorXferCopy(DDD::DDDContext& context, DDD_OBJ obj, DDD_PROC proc,
 #endif
 
   if (flag) {
-    if (DDD_XferWithAddData()) {
+    if (DDD_XferWithAddData(context)) {
       for(mat=VSTART(pv); mat!=NULL; mat=MNEXT(mat)) {
         ASSERT(nmat<256);
         sizeArray[nmat++] = UG_MSIZE(mat);
@@ -1063,7 +1063,7 @@ static void NodeXferCopy (DDD::DDDContext& context, DDD_OBJ obj, DDD_PROC proc,
   }
         #endif
 
-  if (DDD_XferWithAddData()) {
+  if (DDD_XferWithAddData(context)) {
     /* Extra data for Dune */
     DDD_XferAddData(context, sizeof(theNode->message_buffer_size()) + theNode->message_buffer_size(), DDD_USER_DATA);
   }
@@ -1304,7 +1304,7 @@ static void ElementXferCopy (DDD::DDDContext& context, DDD_OBJ obj, DDD_PROC pro
     BElementXferBndS(context, bnds,nsides,proc,prio);
   }
 
-  if (DDD_XferWithAddData()) {
+  if (DDD_XferWithAddData(context)) {
     DDD_XferAddData(context, sizeof(pe->message_buffer_size()) + pe->message_buffer_size(), DDD_USER_DATA);
 
     /* add edges of element */
-- 
GitLab