int calculate_deviation(long long *times, int events, double *average,double *deviation, int type) { /* Calculate averages */ double dev,temp; int kernel,run; double total; int num_kernels; num_kernels=get_num_kernels(type); for(kernel=0;kernel<num_kernels;kernel++) { total=0.0; for(run=0;run<NUM_RUNS;run++) { total+=(double)*(get_runs(times,kernel,events)+run); } average[kernel]=total/(double)NUM_RUNS; // printf("%s: avg=%.2f\n",kernel_names[kernel],average[kernel]); } /* Calculate Deviation */ for(kernel=0;kernel<num_kernels;kernel++) { dev=0.0; for(run=0;run<NUM_RUNS;run++) { temp=(double)(*(get_runs(times,kernel,events)+run))- average[kernel]; temp*=temp; dev+=temp; } deviation[kernel]=dev/(double)(NUM_RUNS-1); deviation[kernel]=sqrt(deviation[kernel]); } return 0; }
int main(int argc, char* argv[]) { int runs = get_runs(argc, argv); int i; for (i = 0; i < runs; i++) { pid_t pid = fork(); if (pid == -1) { printf("Fail!\n"); return 0; } if (pid == 0) { unsigned long long start, end, diff; start = rdtsc(); getpid(); end = rdtsc(); diff = end - start; printf("%llu\n", diff); return 0; } if (i%7000 == 0) { sleep(1); } } }
int calculate_boxplot_data(long long *times, int events, double *median, double *twentyfive, double *seventyfive, int type) { int kernel,num_kernels; num_kernels=get_num_kernels(type); /* calculate median, twentyfive, seventyfive */ for(kernel=0;kernel<num_kernels;kernel++) { median[kernel]=*(get_runs(times,kernel,events)+(NUM_RUNS/2)); twentyfive[kernel]=*(get_runs(times,kernel,events)+(NUM_RUNS/4)); seventyfive[kernel]=*(get_runs(times,kernel,events)+((NUM_RUNS*3)/4)); } return 0; }
int sort_data(long long *times, int events, int type) { int kernel,num_kernels; num_kernels=get_num_kernels(type); /* sort data */ for(kernel=0;kernel<num_kernels;kernel++) { qsort(get_runs(times,kernel,events),NUM_RUNS, sizeof(long long),comp); } return 0; }
int main(int argc, char **argv) { int events,kernel,i; int plot_type=PLOT_TYPE_START; int machine_num=0; double maxy; double average[NUM_FINAL_KERNELS],deviation[NUM_FINAL_KERNELS]; double median[NUM_FINAL_KERNELS],twentyfive[NUM_FINAL_KERNELS], seventyfive[NUM_FINAL_KERNELS]; long long *times=NULL; /* parse command line args */ if (argc<4) { printf("Must specify machine type, machine num, " "and start/stop/read/total\n"); exit(1); } machine_num=atoi(argv[2]); /* allocate memory */ times=calloc(NUM_FINAL_KERNELS*NUM_EVENTS*NUM_RUNS,sizeof(long long)); if (times==NULL) { fprintf(stderr,"Error allocating!\n"); return -1; } /* read in data */ plot_type=read_data(argv[1],machine_num,argv[3],FINAL_KERNELS, times); if (plot_type<0) { fprintf(stderr,"Some sort of error reading!\n"); return -1; } events=EVENT_TO_PLOT; /* sort data */ sort_data(times,events,FINAL_KERNELS); /* calculate median, twentyfive, seventyfive */ calculate_boxplot_data(times,events, median, twentyfive, seventyfive, FINAL_KERNELS); /* Calculate averages and deviation */ calculate_deviation(times,events,average,deviation,FINAL_KERNELS); /* calculate mins and maxes */ maxy=calculate_maxy(average,deviation,FINAL_KERNELS); /* Make graph */ printf("(* Begin Graph *)\n"); printf("newgraph\n"); printf("\n"); printf("X 6.5\n"); printf("Y 6.5\n"); printf("clip\n"); printf("\n"); printf("(* Legend *)\n"); printf("legend custom\n"); printf("\n"); printf("(* Y-Axis *)\n"); printf("yaxis size 4 min 0 max %.0f\n",maxy); printf("(* grid_gray 0.9 grid_lines *)\n"); printf("label font Helvetica fontsize %d : Average Overhead (Cycles)\n", FONTSIZE); printf("hash_labels font Helvetica fontsize %d\n",FONTSIZE); printf("\n"); printf("(* X-Axis *)\n"); printf("xaxis size 6.5 min %d max %d\n",-1,NUM_FINAL_KERNELS); //minx,maxx); printf("grid_gray 0.9 grid_lines\n"); printf("hash_labels font Helvetica fontsize %d vjc hjr rotate 45\n", FONTSIZE); printf("(* label font Helvetica fontsize %d : Kernels *)\n", FONTSIZE); printf("no_auto_hash_marks\n"); for(i=0;i<NUM_FINAL_KERNELS;i++) { printf("hash_at %d\n",i); } printf("no_auto_hash_labels\n"); for(i=0;i<NUM_FINAL_KERNELS;i++) { printf("hash_label at %d : %s\n",i,final_kernels[i].name); } printf("\n"); printf("(* Title *)\n"); printf("title font Helvetica fontsize %d y %lf : " "%s Overhead of ", FONTSIZE, (double)maxy+((double)maxy/8.0),argv[1]); if (plot_type==PLOT_TYPE_START) printf("Start"); if (plot_type==PLOT_TYPE_STOP) printf("Stop"); if (plot_type==PLOT_TYPE_READ) printf("Read"); if (plot_type==PLOT_TYPE_TOTAL) printf("Start/Stop/Read"); printf(" with %d Event%s\n",events,events==1?"":"s"); printf("\n"); for(kernel=0;kernel<NUM_FINAL_KERNELS;kernel++) { if (average[kernel]==0) { printf("newstring vjc x %d y %lf rotate 90 " "font Helvetica fontsize 16 lcolor ", kernel,maxy/10.0); if (final_kernels[kernel].type==INTERFACE_PERFCTR) { printf("1.0 0.0 0.0"); } else if (final_kernels[kernel].type==INTERFACE_PERFMON2) { printf("0.0 0.0 1.0"); } else if (final_kernels[kernel].type==INTERFACE_PERF_EVENT) { printf("0.0 0.0 0.0"); } else if (final_kernels[kernel].type==INTERFACE_PERF_EVENT_RDPMC) { printf("0.11 0.40 0.11"); } else { printf("0.3 0.3 0.0"); } printf(" : n/a\n"); continue; } /* plot standard deviation */ printf("newcurve "); if (final_kernels[kernel].type==INTERFACE_PERFCTR) { printf("marktype x linetype none color 1.0 0.0 0.0\n"); } else if (final_kernels[kernel].type==INTERFACE_PERFMON2) { printf("marktype x linetype none color 0.0 0.0 1.0\n"); } else if (final_kernels[kernel].type==INTERFACE_PERF_EVENT) { printf("marktype x linetype none color 0.0 0.0 0.0\n"); } else if (final_kernels[kernel].type==INTERFACE_PERF_EVENT_RDPMC) { printf("marktype x linetype none color 0.11 0.40 0.11\n"); } else { printf("marktype x linetype none color 0.3 0.3 0.0\n"); } printf("y_epts\n"); printf("\t%d %.2f %.2f %.2f (* %s standard dev *)\n", kernel,average[kernel], average[kernel]-deviation[kernel], average[kernel]+deviation[kernel], final_kernels[kernel].name); /* plot 25th to 75th box */ printf("newcurve "); printf("marktype box marksize 0.5 %lf linetype none ", seventyfive[kernel]-twentyfive[kernel]); if (final_kernels[kernel].type==INTERFACE_PERFCTR) { printf("color 1.0 0.0 0.0\n"); } else if (final_kernels[kernel].type==INTERFACE_PERFMON2) { printf("color 0.0 0.0 1.0\n"); } else if (final_kernels[kernel].type==INTERFACE_PERF_EVENT) { printf("color 0.0 0.0 0.0\n"); } else if (final_kernels[kernel].type==INTERFACE_PERF_EVENT_RDPMC) { printf("color 0.11 0.40 0.11\n"); } else { printf("color 0.3 0.3 0.0\n"); } printf("pts\n"); printf("\t%d %lf\n",kernel, (twentyfive[kernel]+seventyfive[kernel])/2.0); printf("\t(* %lf %lf %lf *)\n",median[kernel],twentyfive[kernel],seventyfive[kernel]); /* plot median */ printf("newcurve "); printf("marktype box marksize 0.5 1 linetype none color 1.0 1.0 1.0\n"); printf("pts\n"); printf("\t%d %lf\n",kernel,median[kernel]); /* plot outliers */ printf("newcurve "); if (final_kernels[kernel].type==INTERFACE_PERFCTR) { printf("marktype x linetype none color 1.0 0.0 0.0\n"); } else if (final_kernels[kernel].type==INTERFACE_PERFMON2) { printf("marktype x linetype none color 0.0 0.0 1.0\n"); } else if (final_kernels[kernel].type==INTERFACE_PERF_EVENT) { printf("marktype x linetype none color 0.0 0.0 0.0\n"); } else if (final_kernels[kernel].type==INTERFACE_PERF_EVENT_RDPMC) { printf("marktype x linetype none color 0.11 0.40 0.11\n"); } else { printf("marktype x linetype none color 0.3 0.3 0.0\n"); } printf("pts\n"); for(i=0;i<NUM_RUNS;i++) { if (*(get_runs(times,kernel,events)+i) > average[kernel] + deviation[kernel]) { printf("\t%d %lld\n",kernel, *(get_runs(times,kernel,events)+i)); } if (*(get_runs(times,kernel,events)+i) < average[kernel]-deviation[kernel]) { printf("\t%d %lld\n",kernel, *(get_runs(times,kernel,events)+i)); } } printf("\n"); } return 0; }
int main(int argc, char **argv) { int kernel,i,krg; int plot_type=PLOT_TYPE_START; int machine_num=0; double maxy; double average[NUM_READS][NUM_KERNELS],deviation[NUM_READS][NUM_KERNELS]; double median[NUM_READS][NUM_KERNELS],twentyfive[NUM_READS][NUM_KERNELS], seventyfive[NUM_READS][NUM_KERNELS]; long long *times=NULL; /* parse command line args */ if (argc<4) { printf("Must specify machine type, machine num, " "and start/stop/read/total\n"); exit(1); } machine_num=atoi(argv[2]); /* allocate memory */ times=calloc(NUM_MANYREAD_KERNELS*NUM_EVENTS*NUM_RUNS,sizeof(long long)); if (times==NULL) { fprintf(stderr,"Error allocating!\n"); return -1; } /* read in data */ /* default */ plot_type=read_data_many(argv[1],machine_num,argv[3],MANYREAD_KERNELS, times,1,0); /* For l1 cache misses */ // plot_type=read_data_many(argv[1],machine_num,argv[3],MANYREAD_KERNELS, // times,2,1); if (plot_type<0) { fprintf(stderr,"Some sort of error reading!\n"); return -1; } for(krg=0;krg<10;krg++) { /* sort data */ sort_data(times,krg,MANYREAD_KERNELS); /* calculate median, twentyfive, seventyfive */ calculate_boxplot_data(times,krg, median[krg], twentyfive[krg], seventyfive[krg], MANYREAD_KERNELS); /* Calculate averages and deviation */ calculate_deviation(times,krg,average[krg],deviation[krg], MANYREAD_KERNELS); } /* calculate mins and maxes */ maxy=calculate_maxy(average[0],deviation[0],MANYREAD_KERNELS); /* Make graph */ printf("(* Begin Graph *)\n"); printf("newgraph\n"); printf("\n"); printf("X 8.5\n"); printf("Y 6\n"); printf("clip\n"); printf("\n"); printf("(* Legend *)\n"); printf("legend custom\n"); printf("\n"); printf("(* Y-Axis *)\n"); printf("yaxis size 4 min 0 max %.0f\n",maxy); printf("(* grid_gray 0.9 grid_lines *)\n"); printf("label font Helvetica fontsize %d : Average Overhead (Cycles)\n", FONTSIZE); printf("hash_labels font Helvetica fontsize %d\n",FONTSIZE); printf("\n"); printf("(* X-Axis *)\n"); printf("xaxis size 6.5 min %d max %d\n",0,10); //minx,maxx); printf("grid_gray 0.9 grid_lines\n"); printf("hash_labels font Helvetica fontsize %d vjc hjr rotate 45\n", FONTSIZE); printf("(* label font Helvetica fontsize %d : Kernels *)\n", FONTSIZE); printf("no_auto_hash_marks\n"); for(i=0;i<NUM_MANYREAD_KERNELS;i++) { printf("hash_at %d\n",i); } printf("no_auto_hash_labels\n"); for(i=0;i<10;i++) { printf("hash_label at %d : %d\n",i,i+1); } printf("\n"); printf("(* Title *)\n"); printf("title font Helvetica fontsize %d y %lf : " "%s Overhead of ", FONTSIZE, (double)maxy+((double)maxy/8.0),argv[1]); if (plot_type==PLOT_TYPE_START) printf("Start"); if (plot_type==PLOT_TYPE_STOP) printf("Stop"); if (plot_type==PLOT_TYPE_READ) printf("Read"); if (plot_type==PLOT_TYPE_TOTAL) printf("Start/Stop/Read"); printf(" "); printf("\n"); for(krg=0;krg<10;krg++) { for(kernel=0;kernel<NUM_MANYREAD_KERNELS;kernel++) { /* plot standard deviation */ printf("newcurve "); if (kernel==0) { printf("marktype x linetype none color 0.0 0.0 0.0\n"); } else if (kernel==1) { printf("marktype x linetype none color 0.3 0.3 0.3\n"); } else { printf("marktype x linetype none color 0.3 0.3 0.0\n"); } printf("y_epts\n"); printf("\t%d %.2f %.2f %.2f (* %s standard dev *)\n", krg,average[krg][kernel], average[krg][kernel]-deviation[krg][kernel], average[krg][kernel]+deviation[krg][kernel], manyread_kernels[kernel].name); /* plot 25th to 75th box */ printf("newcurve "); printf("marktype box marksize 0.5 %lf linetype none ", seventyfive[krg][kernel]-twentyfive[krg][kernel]); if (kernel==0) { printf("color 0.0 0.0 0.0\n"); } else if (kernel==1) { printf("color 0.3 0.3 0.3\n"); } else { printf("color 0.3 0.3 0.0\n"); } printf("pts\n"); printf("\t%d %lf\n",krg, (twentyfive[krg][kernel]+seventyfive[krg][kernel])/2.0); printf("\t(* %lf %lf %lf *)\n",median[krg][kernel],twentyfive[krg][kernel],seventyfive[krg][kernel]); /* plot median */ printf("newcurve "); printf("marktype box marksize 0.5 1 linetype none color 1.0 1.0 1.0\n"); printf("pts\n"); printf("\t%d %lf\n",krg,median[krg][kernel]); /* plot outliers */ printf("newcurve "); if (kernel==0) { printf("marktype x linetype none color 0.0 0.0 0.0\n"); } else if (kernel==1) { printf("marktype x linetype none color 0.3 0.3 0.3\n"); } else { printf("marktype x linetype none color 0.3 0.3 0.0\n"); } printf("pts\n"); for(i=0;i<NUM_RUNS;i++) { if (*(get_runs(times,kernel,krg)+i) > average[krg][kernel] + deviation[krg][kernel]) { printf("\t%d %lld\n",krg, *(get_runs(times,kernel,krg)+i)); } if (*(get_runs(times,kernel,krg)+i) < average[kernel]-deviation[kernel]) { printf("\t%d %lld\n",krg, *(get_runs(times,kernel,krg)+i)); } } printf("\n"); } } return 0; }
int read_data(char *machine, int which, char *plot_name, int type, long long *times) { int events,run,kernel,runs; char filename[BUFSIZ]; FILE *fff; char string[BUFSIZ]; char *result; int plot_type=PLOT_TYPE_START; long long times_start,times_stop,times_read; int num_kernels; char hostname[BUFSIZ]="Unknown",kernel_name[BUFSIZ]="Unknown"; char gathered_version[BUFSIZ]="Unknown"; int interface=INTERFACE_PERF_EVENT; num_kernels=get_num_kernels(type); if (!strcmp(plot_name,"start")) { plot_type=PLOT_TYPE_START; } else if (!strcmp(plot_name,"stop")) { plot_type=PLOT_TYPE_STOP; } else if (!strcmp(plot_name,"read")) { plot_type=PLOT_TYPE_READ; } else if (!strcmp(plot_name,"total")) { plot_type=PLOT_TYPE_TOTAL; } else { printf("Unknown plot type %s\n",plot_name); exit(1); } for(kernel=0;kernel<num_kernels;kernel++) { for(events=0;events<NUM_EVENTS;events++) { for(run=0;run<NUM_RUNS;run++) { *(get_runs(times,kernel,events)+run)=0LL; } } } fprintf(stderr,"Reading in data for %s...\n",machine); for(kernel=0;kernel<num_kernels;kernel++) { if (type==STANDARD_KERNELS) { fprintf(stderr,"\tReading data for kernel %s\n", kernels[kernel].name); } else if (type==RDPMC_KERNELS) { fprintf(stderr,"\tReading data for kernel %s\n", rdpmc_kernels[kernel].name); } else if (type==GCC_KERNELS) { fprintf(stderr,"\tReading data for kernel %s\n", gcc_kernels[kernel].name); } else if (type==BREAKDOWN_KERNELS) { fprintf(stderr,"\tReading data for kernel %s\n", breakdown_kernels[kernel].name); } else if (type==FINAL_KERNELS) { fprintf(stderr,"\tReading data for kernel %s\n", final_kernels[kernel].name); } else if (type==VARYING_KERNELS) { fprintf(stderr,"\tReading data for kernel %s\n", varying_kernels[kernel].name); } else if (type==MANYREAD_KERNELS) { fprintf(stderr,"\tReading data for kernel %s\n", manyread_kernels[kernel].name); } for(events=0;events<NUM_EVENTS;events++) { fprintf(stderr,"%d ",events); if (type==STANDARD_KERNELS) { sprintf(filename,"%s/%d/%s/%d/results", machine,which, kernels[kernel].name, events); } else if (type==RDPMC_KERNELS) { sprintf(filename,"%s/%d/%s/%d/results", machine,which, rdpmc_kernels[kernel].name, events); } else if (type==GCC_KERNELS) { sprintf(filename,"%s/%d/%s/%d/results", machine,which, gcc_kernels[kernel].name, events); } else if (type==BREAKDOWN_KERNELS) { sprintf(filename,"%s/%d/%s/%d/results", machine,which, breakdown_kernels[kernel].name, events); } else if (type==FINAL_KERNELS) { sprintf(filename,"%s/%d/%s/%d/results", machine,which, final_kernels[kernel].name, events); } else if (type==VARYING_KERNELS) { sprintf(filename,"%s/%d/%s/%d/results", machine,which, varying_kernels[kernel].name, events); } else if (type==MANYREAD_KERNELS) { sprintf(filename,"%s/%d/%s/%d/results", machine,which, manyread_kernels[kernel].name, events); } fff=fopen(filename,"r"); if (fff==NULL) { fprintf(stderr,"Can't open %s\n",filename); break; } /**********************/ /* Find System Header */ /**********************/ while(1) { result=fgets(string,BUFSIZ,fff); if (result==NULL) return -1; if (!strncmp(string,"### System info",15)) { break; } } /**********************/ /* Read System Header */ /**********************/ while(1) { result=fgets(string,BUFSIZ,fff); if (result==NULL) return -1; /* Break if reach end of header */ if (!strncmp(string,"###",3)) { break; } if (!strncmp(string,"Kernel:",7)) { strcpy(kernel_name,string+8); kernel_name[strlen(kernel_name)-1]=0; } if (!strncmp(string,"Hostname:",9)) { sscanf(string,"%*s %s",hostname); } if (!strncmp(string,"Family:",7)) { sscanf(string,"%*s %d",&cpuinfo.family); } if (!strncmp(string,"Model:",6)) { sscanf(string,"%*s %d",&cpuinfo.model); } if (!strncmp(string,"Stepping:",9)) { sscanf(string,"%*s %d",&cpuinfo.stepping); } if (!strncmp(string,"Modelname:",10)) { strcpy(cpuinfo.modelname,string+11); cpuinfo.modelname[strlen(cpuinfo.modelname)-1]=0; } if (!strncmp(string,"Generic:",8)) { /* should check that this matches */ strcpy(cpuinfo.generic_modelname,string+9); cpuinfo.generic_modelname[strlen(cpuinfo.generic_modelname)-1]=0; } if (!strncmp(string,"generate_results version:",25)) { sscanf(string,"%*s %*s %s",gathered_version); } if (!strncmp(string,"Interface:",10)) { if (strstr(string,"perf_event_rdpmc")) { interface=INTERFACE_PERF_EVENT_RDPMC; } else if (strstr(string,"perf_event")) { interface=INTERFACE_PERF_EVENT; } else if (strstr(string,"perfmon")) { interface=INTERFACE_PERFMON2; } else if (strstr(string,"perfctr")) { interface=INTERFACE_PERFCTR; } else { fprintf(stderr,"Unknown interface!\n"); interface=INTERFACE_UNKNOWN; } } if (!strncmp(string,"Counters:",7)) { } if (!strncmp(string,"Runs:",4)) { sscanf(string,"%*s %d",&runs); } } /* Print header if first time through */ if (debug) { printf("#### Events %d\n",events); printf("\tHostname: %s\n",hostname); printf("\tKernel: %s\n",kernel_name); printf("\tInterface: "); if (interface==INTERFACE_PERF_EVENT) printf("perf_event\n"); else if (interface==INTERFACE_PERFMON2) printf("perfmon2\n"); else if (interface==INTERFACE_PERFCTR) printf("perfctr\n"); else if (interface==INTERFACE_PERF_EVENT_RDPMC) printf("perf_event_rdpmc\n"); else printf("Unknown\n"); printf("\tCPU: %d/%d/%d\n", cpuinfo.family,cpuinfo.model,cpuinfo.stepping); printf("\tCPU type: %s\n",cpuinfo.generic_modelname); printf("\tCPU name: %s\n",cpuinfo.modelname); printf("\tdata gathered with tool version: %s\n",gathered_version); printf("\truns: %d\n",runs); printf("\tdata analyzed with tool version: %s\n", PERF_EVENT_OVERHEAD_VERSION); } /* ### Perf Results 0 init_latency: 69 cycles Eventset_creation_3: 150420 cycles start latency: 34765 cycles stop latency: 11431 cycles read latency: 12282 cycles 53003c 2017 5300c0 1129 5300c4 356 ### Perf Results 1 */ /* read data */ run=0; loop: while(1) { if (fgets(string,BUFSIZ,fff)==NULL) break; if (!strncmp(string,"###",3)) break; if (!strncmp(string,"start latency",13)) { sscanf(string,"%*s %*s %lld",×_start); } if (!strncmp(string,"stop latency",12)) { sscanf(string,"%*s %*s %lld",×_stop); } if (!strncmp(string,"read latency",12)) { sscanf(string,"%*s %*s %lld",×_read); } } // printf("%d %lld\n",run,times_start); if (plot_type==PLOT_TYPE_START) { *(get_runs(times,kernel,events)+run)=times_start; } if (plot_type==PLOT_TYPE_STOP) { *(get_runs(times,kernel,events)+run)=times_stop; } if (plot_type==PLOT_TYPE_READ) { *(get_runs(times,kernel,events)+run)=times_read; } if (plot_type==PLOT_TYPE_TOTAL) { *(get_runs(times,kernel,events)+run)=times_start+times_stop+times_read; } run++; if (run<runs) goto loop; fclose(fff); } fprintf(stderr,"\n"); } return plot_type; }
char * encode_t4 (int k_param, char *inbuf, int eolnskip) { bit_string ref_line; /* Reference line */ bit_string t4_line; /* Output encoded line */ bit_string code_line; /* Line we are codeing */ short i,j; /* Loop variable */ int run_buf [LINEBUF], run_buf2 [LINEBUF]; if (a3Width) forcesize = 2432; if (b4Width) forcesize = 2048; if (standardwidth) forcesize = 1728; if (k_param > 1) twoDimensional = 1; ref_line.run_top = run_buf; code_line.run_top = run_buf2; code_line.dbuf_top = inbuf; t4_line.dbuf_top = malloc ((unsigned int)((PIC_LINESIZE * NUMLINES) + 28)); set_input (&code_line); set_output (&t4_line); /* Repeat this loop once for every input line expected */ for (i = 0; i < NUMLINES; i++) { if (code_line.run_top == run_buf) { /*swap buffers*/ ref_line.run_top = run_buf; code_line.run_top = run_buf2; } else { ref_line.run_top = run_buf2; code_line.run_top = run_buf; } /* reset pointers */ code_line.run_pos = code_line.run_top; ref_line.run_pos = ref_line.run_top; /* fill buffer for coding line */ get_runs (&code_line); code_line.run_pos = code_line.run_top; put_eoln (&t4_line); if (k_param > 1) { if (i % k_param == 0) { set_bit (&t4_line); /* tag bit, 1-d line follows */ code_one (&code_line, &t4_line); } else { clr_bit (&t4_line); /* tag bit, 2-d line follows */ code_two (&ref_line, &code_line, &t4_line); } } else code_one (&code_line, &t4_line); /* skip any extra eoln bit in orig data */ for (j = 0; j < eolnskip; j++) get_bit (&code_line); } /* now finish with 6 EOL's, as per T.4 */ for (i = 0; i < 5; ++i) { put_eoln (&t4_line); if (k_param > 1) set_bit (&t4_line); } /* flush buffers, write preamble */ flush_output (&t4_line); return (t4_line.dbuf_top); }