g+
g+ Communities
Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  Index 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014 
<== Date ==> <== Thread ==>

Subject: dbToRecordTypeH
From: Benjamin Franksen <benjamin.franksen@bessy.de>
To: core-talk@aps.anl.gov
Date: Fri, 19 Feb 2010 14:48:00 +0100
Hi All

I have an application where a number of similar record types get generated. 
This made me aware of how the <recordTypeName>RecordSizeOffset routine that 
gets generated by dbToRecordTypeH wastes a lot of memory. Currently 
dbToRecordTypeH generates code like

static int collect1RecordSizeOffset(dbRecordType *pdbRecordType)
{
    collect1Record *prec = 0;
  pdbRecordType->papFldDes[0]->size=sizeof(prec->name);
  pdbRecordType->papFldDes[0]->offset=(short)((char *)&prec->name - (char 
*)prec);
  pdbRecordType->papFldDes[1]->size=sizeof(prec->desc);
  pdbRecordType->papFldDes[1]->offset=(short)((char *)&prec->desc - (char 
*)prec);
  ...
  pdbRecordType->papFldDes[47]->size=sizeof(prec->i000);
  pdbRecordType->papFldDes[47]->offset=(short)((char *)&prec->i000 - (char 
*)prec);
    pdbRecordType->rec_size = sizeof(*prec);
    return(0);
}

I propose it gets changed to this

static collect1Record *pnullcollect1Record = 0;
static struct { short size; short offset; } collect1RecordSizeOffsets[48] = 
{
  {sizeof(pnullcollect1Record->name), (short)((char *)&pnullcollect1Record-
>name - (char *)pnullcollect1Record)},
  {sizeof(pnullcollect1Record->desc), (short)((char *)&pnullcollect1Record-
>desc - (char *)pnullcollect1Record)},
 ...
  {sizeof(pnullcollect1Record->i000), (short)((char *)&pnullcollect1Record-
>i000 - (char *)pnullcollect1Record)},
};
static int collect1RecordSizeOffset(dbRecordType *pdbRecordType)
{
  int i;
  for (i=0; i<48; i++) {
    pdbRecordType->papFldDes[i]->size = collect1RecordSizeOffsets[i].size;
    pdbRecordType->papFldDes[i]->offset = 
collect1RecordSizeOffsets[i].offset;
  };
  pdbRecordType->rec_size = sizeof(*pnullcollect1Record);
  return(0);
}

This reduces memory consumtion by a fair amount. Before:

> du -h lib            
144K    lib/vxWorks-68040
208K    lib/linux-x86
124K    lib/vxWorks-ppc603
480K    lib

After:

> du -h lib
44K     lib/vxWorks-68040
136K    lib/linux-x86
52K     lib/vxWorks-ppc603
236K    lib

This is for an application that provides 10 record types of various sizes.

I have attached a patch for dbToRecordTypeH.c that implements this change. 
(Apply it to CVS head (revision 1.30) with "patch dbToRecordtypeH.c 
dbToRecordtypeH.patch").

Cheers
Ben

Helmholtz-Zentrum Berlin für Materialien und Energie GmbH   
Hahn-Meitner-Platz 1, 14109 Berlin   
Vorsitzende des Aufsichtsrates: Prof. Dr. Dr. h.c. mult. Joachim Treusch   
Stellvertretende Vorsitzende: Dr. Beatrix Vierkorn-Rudolph Geschäftsführer: Prof. Dr. Anke Rita Kaysser-Pyzalla, Prof. Dr. Dr. h.c. Wolfgang Eberhardt, Dr. Ulrich Breuer   
Sitz der Gesellschaft: Berlin Handelsregister: AG Charlottenburg, 89 HRB 5583   

Disclaimer automatically attached by the E-Mail Security Appliance   
mail0.bessy.de 02/19/10 at Helmholtz-Zentrum Berlin GmbH. 
--- dbToRecordtypeH.1.30.c	2010-02-19 12:39:27.000000000 +0100
+++ dbToRecordtypeH.c		2010-02-19 14:39:42.000000000 +0100
@@ -231,30 +231,47 @@
         fprintf(outFile,"#include <epicsExport.h>\n");
 	pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList);
 	while(pdbRecordType) {
-		fprintf(outFile,"static int %sRecordSizeOffset(dbRecordType *pdbRecordType)\n{\n",
-		pdbRecordType->name);
-	    fprintf(outFile,"    %sRecord *prec = 0;\n",pdbRecordType->name);
-	    for(i=0; i<pdbRecordType->no_fields; i++) {
-		char	name[256];
-		int		j;
+            fprintf(outFile, "static %sRecord *pnull%sRecord = 0;\n",
+                pdbRecordType->name, pdbRecordType->name);
+            fprintf(outFile,
+                "static struct { short size; short offset; } %sRecordSizeOffsets[%d] = {\n",
+                pdbRecordType->name, pdbRecordType->no_fields);
+            for (i = 0; i < pdbRecordType->no_fields; i++) {
+                char fieldName[256];
+                int j;
 
-		pdbFldDes = pdbRecordType->papFldDes[i];
-		for(j=0; j< (int)strlen(pdbFldDes->name); j++)
-		    name[j] = tolower(pdbFldDes->name[j]);
-		name[strlen(pdbFldDes->name)] = 0;
-		fprintf(outFile,
-		"  pdbRecordType->papFldDes[%d]->size=sizeof(prec->%s);\n",
-		    i,name);
-		fprintf(outFile,"  pdbRecordType->papFldDes[%d]->offset=",i);
-		fprintf(outFile,
-		    "(short)((char *)&prec->%s - (char *)prec);\n",name);
-	    }
-	    fprintf(outFile,"    pdbRecordType->rec_size = sizeof(*prec);\n");
-	    fprintf(outFile,"    return(0);\n");
-	    fprintf(outFile,"}\n");
-	    fprintf(outFile,"epicsExportRegistrar(%sRecordSizeOffset);\n",
-		pdbRecordType->name);
-	    pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node);
+                pdbFldDes = pdbRecordType->papFldDes[i];
+                for (j = 0; j < (int)strlen(pdbFldDes->name); j++)
+                    fieldName[j] = tolower(pdbFldDes->name[j]);
+                fieldName[strlen(pdbFldDes->name)] = 0;
+#if 0
+                fprintf(outFile,
+                    "  {sizeof(pnull%sRecord->%s), offsetof(%sRecord, %s)},\n",
+                    pdbRecordType->name, fieldName, pdbRecordType->name, fieldName);
+#endif
+                fprintf(outFile,
+                    "  {sizeof(pnull%sRecord->%s), (short)((char *)&pnull%sRecord->%s - (char *)pnull%sRecord)},\n",
+                    pdbRecordType->name, fieldName, pdbRecordType->name, fieldName, pdbRecordType->name);
+            }
+            fprintf(outFile, "};\n");
+            fprintf(outFile,
+                "static int %sRecordSizeOffset(dbRecordType *pdbRecordType)\n{\n",
+                pdbRecordType->name);
+            fprintf(outFile, "  int i;\n");
+            fprintf(outFile, "  for (i=0; i<%d; i++) {\n", pdbRecordType->no_fields);
+            fprintf(outFile, "    pdbRecordType->papFldDes[i]->size = %sRecordSizeOffsets[i].size;\n",
+                pdbRecordType->name);
+            fprintf(outFile, "    pdbRecordType->papFldDes[i]->offset = %sRecordSizeOffsets[i].offset;\n",
+                pdbRecordType->name);
+            fprintf(outFile, "  };\n");
+
+            fprintf(outFile,
+                "  pdbRecordType->rec_size = sizeof(*pnull%sRecord);\n", pdbRecordType->name);
+            fprintf(outFile, "  return(0);\n");
+            fprintf(outFile, "}\n");
+            fprintf(outFile, "epicsExportRegistrar(%sRecordSizeOffset);\n",
+                pdbRecordType->name);
+            pdbRecordType = (dbRecordType *) ellNext(&pdbRecordType->node);
 	}
 	fprintf(outFile,"#ifdef __cplusplus\n");
 	fprintf(outFile,"}\n");

Navigate by Date:
Prev: Re: FW: StreamDevice bug Andrew Johnson
Next: missing monitors from boRecord Davidsaver, Michael
Index: 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014 
Navigate by Thread:
Prev: Re: FW: StreamDevice bug Andrew Johnson
Next: missing monitors from boRecord Davidsaver, Michael
Index: 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICSv4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·