add reserve, tsc and alignment atomicity with cmpxchg
[lttv.git] / genevent / genevent.c
index 739eee2b6ea2ba6024c1bebd28ee4017efec81d3..5930489f755bc1f7f9ce7140f31313509a337c85 100644 (file)
@@ -268,7 +268,8 @@ void generateEnumEvent(FILE *fp, char *facName, int * nbEvent, unsigned long che
 
 static void
 printStruct(FILE * fp, int len, void ** array, char * name, char * facName,
-       int * whichTypeFirst, int * hasStrSeq, int * structCount)
+       int * whichTypeFirst, int * hasStrSeq, int * structCount,
+       type_descriptor *type)
 {
   int flag = 0;
   int pos;
@@ -313,7 +314,16 @@ printStruct(FILE * fp, int len, void ** array, char * name, char * facName,
   }
 
   if(flag) {
-    fprintf(fp,"} __attribute__ ((packed));\n\n");
+    if(type->alignment == 0)
+      fprintf(fp,"} __attribute__ ((packed));\n\n");
+    else {
+      if(type->alignment != 1 && type->alignment != 2
+          && type->alignment != 4 && type->alignment != 8) {
+        printf("Wrong alignment %i, using packed.\n", type->alignment);
+        fprintf(fp,"} __attribute__ ((packed));\n\n");
+      } else
+        fprintf(fp,"} __attribute__ ((aligned(%i)));\n\n", type->alignment);
+    }
   }
 }
 
@@ -334,6 +344,7 @@ generateTypeDefs(FILE * fp, char *facName)
   fprintf(fp,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n", facName);
   fprintf(fp,"#include <linux/ltt-core.h>\n");
 
+#if 0 //broken
   fprintf(fp, "/****  Basic Type Definitions  ****/\n\n");
 
   for (pos = 0; pos < fac->named_types.values.position; pos++) {
@@ -344,6 +355,7 @@ generateTypeDefs(FILE * fp, char *facName)
     fprintf(fp, "typedef struct _%s %s;\n\n",
             type->type_name, type->type_name);
   }
+#endif //0
 }
 
 
@@ -417,7 +429,8 @@ void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
     //structure for kernel
     if(ev->type != 0)
       printStruct(fp, ev->type->fields.position, ev->type->fields.array,
-        ev->name, facName, &whichTypeFirst, &hasStrSeq, &structCount);
+        ev->name, facName, &whichTypeFirst, &hasStrSeq, &structCount,
+        ev->type);
 
 
     //trace function : function name and parameters : stub function.
@@ -471,36 +484,6 @@ void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
 
 
        
-    //length of buffer : length of all structures
-               fprintf(fp,"\tint length = ");
-    if(ev->type == 0) fprintf(fp, "0");
-
-    for(pos1=0;pos1<structCount;pos1++){
-      fprintf(fp,"sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
-      if(pos1 != structCount-1) fprintf(fp," + ");
-    }
-
-    //length of buffer : length of all arrays, sequences and strings
-    seqCount = 0;
-    strCount = 0;
-    flag = 0;
-               if(ev->type != 0)
-                       for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
-                               fld  = (field *)ev->type->fields.array[pos1];
-                               td = fld->type;
-                               if(td->type == SEQUENCE || td->type==STRING || td->type==ARRAY){
-                                       if(structCount || flag > 0) fprintf(fp," + ");    
-                                       if(td->type == SEQUENCE) 
-                                               fprintf(fp,"sizeof(%s) + sizeof(%s) * seqlength_%d",
-                                                               uintOutputTypes[td->size], getTypeStr(td), ++seqCount);
-                                       else if(td->type==STRING) fprintf(fp,"strlength_%d + 1", ++strCount);
-                                       else if(td->type==ARRAY) 
-                                               fprintf(fp,"sizeof(%s) * %d", getTypeStr(td),td->size);
-                                       if(structCount == 0) flag = 1;
-                               }
-                       }
-    fprintf(fp,";\n");
-
     //allocate buffer
     // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
     // write directly to the channel
@@ -509,11 +492,14 @@ void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
     fprintf(fp, "\tstruct ltt_trace_struct *trace;\n");
     fprintf(fp, "\tunsigned long _flags;\n");
     fprintf(fp, "\tvoid *buff;\n");
+    fprintf(fp, "\tvoid *old_address;\n");
     fprintf(fp, "\tunsigned int header_length;\n");
-    fprintf(fp, "\tunsigned int event_length;\n");
-    fprintf(fp, "\tint resret;\n");
+    fprintf(fp, "\tunsigned int event_length;\n");     // total size (incl hdr)
+               fprintf(fp, "\tunsigned int length;\n");        // Size of the event var data.
     fprintf(fp, "\tunsigned char _offset;\n");
                fprintf(fp, "\tstruct rchan_buf *buf;\n");
+               fprintf(fp, "\tstruct timeval delta;\n");
+               fprintf(fp, "\tu64 tsc;\n");
 
                if(ev->type != 0)
       fprintf(fp, "\tstruct %s_%s_1* __1;\n\n", ev->name, facName);
@@ -543,18 +529,89 @@ void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
     /* For each trace */
     fprintf(fp, "\tlist_for_each_entry(trace, &ltt_traces.head, list) {\n");
     fprintf(fp, "\t\tif(!trace->active) continue;\n\n");
-    
+
+     //length of buffer : length of all structures
+ //   if(ev->type == 0) fprintf(fp, "0");
+   
     fprintf(fp, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
                fprintf(fp, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
+               fprintf(fp, "\n");
                /* Warning : not atomic reservation : event size depends on the current
                 * address for alignment */
-    fprintf(fp, "\t\theader_length = "
-                "ltt_get_event_header_size(trace, channel,"
-                                                               "buf->data + buf->offset, &_offset);\n");
-    fprintf(fp, "\t\tevent_length = header_length + length;\n");
-   
+               /* NOTE : using cmpxchg in reserve with repeat for atomicity */
+    // Replaces _offset
+               fprintf(fp, "\t\tdo {\n");
+               fprintf(fp, "\t\t\told_address = buf->data + buf->offset;\n");
+    fprintf(fp, "\t\t\tchar *ptr = (char*)old_address;\n");
+
+
+    fprintf(fp, "\t\t\theader_length = ltt_get_event_header_data(trace, "
+                                                                                                                                                                                                                                                               "channel,\n"
+                                                               "\t\t\t\t\t\t\t\t\t\told_address, &_offset, &delta, &tsc);\n");
+
+    fprintf(fp, "\t\t\tptr += _offset + header_length;\n");
+
+    for(pos1=0;pos1<structCount;pos1++){
+
+      if(ev->type->alignment > 1) {
+        fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1) ;\n",
+            ev->type->alignment, ev->type->alignment, ev->type->alignment);
+      }
+      fprintf(fp,"\t\t\tptr += sizeof(struct %s_%s_%d);\n",ev->name,
+          facName,pos1+1);
+//      if(pos1 != structCount-1) fprintf(fp," + ");
+    }
+
+    //length of buffer : length of all arrays, sequences and strings
+    seqCount = 0;
+    strCount = 0;
+    flag = 0;
+               if(ev->type != 0)
+                       for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
+                               fld  = (field *)ev->type->fields.array[pos1];
+                               td = fld->type;
+                               if(td->type == SEQUENCE || td->type==STRING || td->type==ARRAY){
+                                       if(td->type == SEQUENCE) {
+            if(td->alignment > 1) {
+              fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
+                      td->alignment, td->alignment, td->alignment);
+            }
+                                               fprintf(fp,
+                "\t\t\tptr += sizeof(%s) + (sizeof(%s) * seqlength_%d);\n",
+                                                               uintOutputTypes[td->size], getTypeStr(td), ++seqCount);
+          } else if(td->type==STRING) {
+            if(td->alignment > 1) {
+              fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
+                 td->alignment, td->alignment, td->alignment);
+            }
+            fprintf(fp,"ptr += strlength_%d + 1;\n",
+                                                ++strCount);
+          }
+                                       else if(td->type==ARRAY) {
+            if(td->alignment > 1) {
+              fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
+                 td->alignment, td->alignment, td->alignment);
+            }
+                                               fprintf(fp,"\t\t\tptr += sizeof(%s) * %d;\n",
+                getTypeStr(td),td->size);
+                                       if(structCount == 0) flag = 1;
+          }
+                               }
+                       }
+    fprintf(fp,";\n");
+
+    fprintf(fp, "\t\t\tevent_length = (unsigned long)ptr -"
+                               "(unsigned long)old_address;\n");
+
+               fprintf(fp, "\t\t\tbuff = relay_reserve(channel->rchan, event_length, "
+                                                                                               "old_address);\n");
+               fprintf(fp, "\n");
+               fprintf(fp, "\t\t} while(PTR_ERR(buff) == -EAGAIN);\n");
+               fprintf(fp, "\n");
+
+  
     /* Reserve the channel */
-    fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length, &resret);\n");
+    //fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length);\n");
     fprintf(fp, "\t\tif(buff == NULL) {\n");
     fprintf(fp, "\t\t\t/* Buffer is full*/\n");
     fprintf(fp, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
@@ -563,32 +620,45 @@ void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
     fprintf(fp, "\t\t}\n");
                
                /* DEBUG */
-    fprintf(fp, "\t\tif(resret == 1) {\n");
-               fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
-                               facName, checksum, ev->name);
-    fprintf(fp, "\t\t}\n");
+    //fprintf(fp, "\t\tif(resret == 1) {\n");
+               //fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
+               //              facName, checksum, ev->name);
+    //fprintf(fp, "\t\t}\n");
 
     /* Write the header */
+    fprintf(fp, "\n");
+               fprintf(fp,"\t\tlength = event_length - header_length;\n");
     fprintf(fp, "\n");
     fprintf(fp, "\t\tltt_write_event_header(trace, channel, buff, \n"
-                "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset);\n",
+                "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset,\n"
+                                                               "\t\t\t\t&delta, &tsc);\n",
                 facName, checksum, ev->name);
     fprintf(fp, "\n");
-    
+
+    if(ev->type != 0)
+      fprintf(fp, "\t\tchar *ptr = (char*)buff + _offset + header_length;\n");
+
+   
     //declare a char pointer if needed : starts at the end of the structs.
-    if(structCount + hasStrSeq > 1) {
-      fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
-      for(pos1=0;pos1<structCount;pos1++){
-        fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
-      }
-      if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
-    }
+    //if(structCount + hasStrSeq > 1) {
+    //  fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
+    //  for(pos1=0;pos1<structCount;pos1++){
+    //    fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
+    //  }
+    //  if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
+    //}
 
     // Declare an alias pointer of the struct type to the beginning
     // of the reserved area, just after the event header.
-               if(ev->type != 0)
-      fprintf(fp, "\t\t__1 = (struct %s_%s_1 *)(buff + header_length);\n",
+    if(ev->type != 0) {
+      if(ev->type->alignment > 1) {
+        fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
+              ev->type->alignment, ev->type->alignment, ev->type->alignment);
+      }
+    
+      fprintf(fp, "\t\t__1 = (struct %s_%s_1 *)(ptr);\n",
           ev->name, facName);
+    }
     //allocate memory for new struct and initialize it
     //if(whichTypeFirst == 1){ //struct first
       //for(pos1=0;pos1<structCount;pos1++){  
@@ -660,17 +730,30 @@ void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
                                if(td->type == SEQUENCE){
                                        flag = 0;
                                        fprintf(fp,"\t\t//copy sequence length and sequence to buffer\n");
+
+          if(td->alignment > 1) {
+            fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
+                    td->alignment, td->alignment, td->alignment);
+          }
                                        fprintf(fp,"\t\t*ptr = seqlength_%d;\n",++seqCount);
                                        fprintf(fp,"\t\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
+          if(td->alignment > 1) {
+            fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
+                    td->alignment, td->alignment, td->alignment);
+          }
                                        fprintf(fp,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
                                                fld->name, getTypeStr(td), seqCount);
-                                        fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
+                                       fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
                                                getTypeStr(td), seqCount);
                                }
                                else if(td->type==STRING){
                                        flag = 0;
                                        fprintf(fp,"\t\t//copy string to buffer\n");
                                        fprintf(fp,"\t\tif(strlength_%d > 0){\n",++strCount);
+          if(td->alignment > 1) {
+            fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
+                    td->alignment, td->alignment, td->alignment);
+          }
                                        fprintf(fp,"\t\t\tmemcpy(ptr, %s, strlength_%d + 1);\n",
                                                        fld->name, strCount);
                                        fprintf(fp,"\t\t\tptr += strlength_%d + 1;\n",strCount);
@@ -681,6 +764,10 @@ void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
                                }else if(td->type==ARRAY){
                                        flag = 0;
                                        fprintf(fp,"\t//copy array to buffer\n");
+          if(td->alignment > 1) {
+            fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
+                    td->alignment, td->alignment, td->alignment);
+          }
                                        fprintf(fp,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
                                                        fld->name, getTypeStr(td), td->size);
                                        fprintf(fp,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td), td->size);
This page took 0.027653 seconds and 4 git commands to generate.