Example #1
0
int main(int argc, char **argv)
{
    SEQDATA seqdata;
    INIT initial;
    CHAIN chain;
    CONVG cvg;
    int chn;

    param_decomp(argc,argv);

    seqdata=read_data(datafilename,ploid,totalsize,popnum,nloci,missingdata,label,popdata,siglevel,back_refl,type_freq,nstep_check_empty_cluster,prior_flag,mode,n_extra_col,markername_flag,alpha_dpm,print_iter,print_freq,inf_K,distr_fmt,autopoly,data_fmt,max_mem);

    if(inf_K==0)
    {
        initial=read_init(initialfilename,chainnum,popnum,updatenum,burnin,thinning);
    }
    else {
        initial=read_init(initialfilename,chainnum,n_large,updatenum,burnin,thinning);
    }
    if(mem_cal(seqdata,initial)>seqdata.max_mem)
    {
        nrerror("Your request of memory exceeds the maximum memory allowed! Please change the parameter max_mem");
    }

    printinfo(outfilename,argc,argv,seqdata);

    if(inf_K==1)
    {   // make inference of K
        inf_K_val(outfilename,n_small,n_large,&seqdata,initial);
    }
    else {
        if(GR_flag==1) allocate_convg(seqdata,&cvg,chainnum,ckrep,convgfilename);
        for(chn=0; chn<chainnum; chn++)
        {
            chain=mcmc_updating(seqdata,initial,chn,&cvg);
            if(chain.flag_empty_cluster==1)
            {
                free_chain(&chain,seqdata);
                chn--;
                continue;
            }
            chain_stat(outfilename,chain,seqdata,chn);
            free_chain(&chain,seqdata);
        }
        if(GR_flag==1)
        {
            chain_converg(outfilename,&cvg);
            free_convg(&cvg);
        }
    }
    fprintf(stdout,"THE JOB IS SUCCESSFULLY FINISHED\n");
    return(0);
}
Example #2
0
// -----------------------------------------------------
// Free symbol table
void free_symtab( symtab table )
{
  for (int k=0; k<NBuckets; k++) {
    free_chain( table->bucket[ k ] );
  }
  free( table );
}
Example #3
0
static int parse_chain(const char **p, bool usec, CalendarComponent **c) {
        const char *t;
        CalendarComponent *cc = NULL;
        int r;

        assert(p);
        assert(c);

        t = *p;

        if (t[0] == '*') {
                if (usec) {
                        r = const_chain(0, c);
                        if (r < 0)
                                return r;
                        (*c)->repeat = USEC_PER_SEC;
                } else
                        *c = NULL;

                *p = t + 1;
                return 0;
        }

        r = prepend_component(&t, usec, 0, &cc);
        if (r < 0) {
                free_chain(cc);
                return r;
        }

        *p = t;
        *c = cc;
        return 0;
}
Example #4
0
static void free_chain(subst_t *sub)
{
    if (sub == NULL) return;
    free_chain(sub->next);
    free(sub->string);
    free(sub);
}
Example #5
0
static int parse_chain(const char **p, CalendarComponent **c) {
        const char *t;
        CalendarComponent *cc = NULL;
        int r;

        assert(p);
        assert(c);

        t = *p;

        if (t[0] == '*') {
                *p = t + 1;
                *c = NULL;
                return 0;
        }

        r = prepend_component(&t, &cc);
        if (r < 0) {
                free_chain(cc);
                return r;
        }

        *p = t;
        *c = cc;
        return 0;
}
Example #6
0
int di_delete(DiskImage *di, unsigned char *rawpattern, FileType type) {
  RawDirEntry *rde;
  unsigned char delcount = 0;

  switch (type) {

  case T_SEQ:
  case T_PRG:
  case T_USR:
	rde = find_file_entry(di, rawpattern, type);
    while (rde) {
      free_chain(di, rde->startts);
      rde->type = 0;
      ++delcount;
	  rde = find_file_entry(di, rawpattern, type);
    }
    if (delcount) {
      return set_status(di, 1, delcount, 0);
    } else {
      return set_status(di, 62, 0, 0);
    }
    break;

  default:
    return set_status(di, 64, 0, 0);
    break;

  }
}
Example #7
0
// -----------------------------------------------------
// Free symbol table
void free_symtab( symtab* table )
{
  for (int i=0; i<table->size; i++) {
    free_chain( table->bucket[i] );
  }
  free(table->bucket);
  free( table );
}
Example #8
0
int main(int argc, char ** argv) {
    chain_options * ops = parse_ops(argc, argv);
    corpus_root * root = generate_chain(ops);
    output_chain(root);
    free_options(ops);
    free_chain(root);
    return EXIT_SUCCESS;
}
Example #9
0
/**
 * Function to free a chain buffer.
 * This specifically releases a buffer created and populated by ironbee_body_out.
 * It is not for general-purpose use with an arbitrary chain, where it would
 * likely crash and burn.
 *
 * @param[in]  pool  The pool used to allocate buffers being released.
 * @param[in]  chain The chain buffer to free.
 */
static void free_chain(ngx_pool_t *pool, ngx_chain_t *chain)
{
    if (chain) {
        free_chain(pool, chain->next);
        if (chain->buf->last != chain->buf->pos) {
            ngx_pfree(pool, chain->buf->pos);
        }
        ngx_pfree(pool, chain->buf);
        ngx_pfree(pool, chain);
    }
}
Example #10
0
static void spu_cb(void * p)
{
  if (p) {
    dma_chain_t * chain = (dma_chain_t *) p;

    if (chain->src == NULL) {
      free_chain(chain);
    } else {
      sem_signal(chain->sema);
      if (chain->waiting_thd)
	thd_schedule_next(chain->waiting_thd);
      chain->dest = 0; /* mark dma completed */
    }
    
    if (spu_chain_head == NULL)
      ;//draw_unlock();

    vid_border_color(0, 0, 0);
    spu_transfering = 0;
  } else
    ;//bba_lock();
    //asic_evt_disable(ASIC_EVT_EXP_PCI, ASIC_IRQB);

  if (spu_chain_head) {
    dma_chain_t * chain = spu_chain_head;

    spu_transfering = 1;

    vid_border_color(0, 255, 0);
    switch(chain->type) {
/*     case DMA_TYPE_VRAM: */
/*       pvr_txr_load_dma(chain->src, chain->dest,  */
/* 		       chain->count, 0, spu_cb, chain); */
/*       break; */
    case DMA_TYPE_SPU:
      dma_cache_flush(chain->src, chain->count);
      spu_dma_transfer(chain->src, chain->dest, chain->count, 0, 
		       spu_cb, chain);
      break;

    case DMA_TYPE_BBA_RX:
      g2_dma_transfer(chain->dest, chain->src, chain->count, 0, 
		      spu_cb, chain, 1, bba_dma_mode, 1, 3);
      break;
    default:
      panic("got bad dma chain type in spu_cb\n");
    }
    spu_chain_head = chain->next;
  } else {
    //asic_evt_enable(ASIC_EVT_EXP_PCI, ASIC_IRQB);
    ;//bba_unlock();
  }
}
Example #11
0
void calendar_spec_free(CalendarSpec *c) {
        assert(c);

        free_chain(c->year);
        free_chain(c->month);
        free_chain(c->day);
        free_chain(c->hour);
        free_chain(c->minute);
        free_chain(c->second);

        free(c);
}
Example #12
0
void calendar_spec_free(CalendarSpec *c) {

        if (!c)
                return;

        free_chain(c->year);
        free_chain(c->month);
        free_chain(c->day);
        free_chain(c->hour);
        free_chain(c->minute);
        free_chain(c->microsecond);

        free(c);
}
Example #13
0
CalendarSpec* calendar_spec_free(CalendarSpec *c) {

        if (!c)
                return NULL;

        free_chain(c->year);
        free_chain(c->month);
        free_chain(c->day);
        free_chain(c->hour);
        free_chain(c->minute);
        free_chain(c->microsecond);
        free(c->timezone);

        return mfree(c);
}
Example #14
0
//#undef printf
int dma_wait(dma_chain_t * chain)
{
  if (chain == NULL)
    return -1;

  if (irq_inside_int()) {
    panic("dma_wait called inside an irq !\n");
    dma_free(chain);
    return -1;
  }

  printf("\n !!!!!!!!!! waiting ... \n");
  sem_wait(chain->sema);
/*   if (sem_wait_timed(chain->sema, 1000)) { */
/*     printf("dma timeout...\n"); */
/*     dma_free(chain); */
/*     return -1; */
/*   } */
  printf("\n !!!!!!!!!! done !\n");
  free_chain(chain);
  return 0;
}
Example #15
0
int dma_free(dma_chain_t * chain)
{
  int irq = 0;

  if (chain == NULL)
    return -1;

  if (!irq_inside_int())
    irq = irq_disable();

  /* mark we won't wait on the semaphore */
  chain->src = NULL;

  if (!chain->dest) {
    /* the semaphore has been signaled already */
    assert(!sem_trywait(chain->sema));
    free_chain(chain);
  }
    
  if (!irq_inside_int())
    irq_restore(irq);
  return 0;
}
Example #16
0
static int parse_time(const char **p, CalendarSpec *c) {
        CalendarComponent *h = NULL, *m = NULL, *s = NULL;
        const char *t;
        int r;

        assert(p);
        assert(*p);
        assert(c);

        t = *p;

        if (*t == 0) {
                /* If no time is specified at all, but a date of some
                 * kind, then this means 00:00:00 */
                if (c->day || c->weekdays_bits > 0)
                        goto null_hour;

                goto finish;
        }

        r = parse_chain(&t, &h);
        if (r < 0)
                goto fail;

        if (*t != ':') {
                r = -EINVAL;
                goto fail;
        }

        t++;
        r = parse_chain(&t, &m);
        if (r < 0)
                goto fail;

        /* Already at the end? Then it's hours and minutes, and seconds are 0 */
        if (*t == 0) {
                if (m != NULL)
                        goto null_second;

                goto finish;
        }

        if (*t != ':') {
                r = -EINVAL;
                goto fail;
        }

        t++;
        r = parse_chain(&t, &s);
        if (r < 0)
                goto fail;

        /* At the end? Then it's hours, minutes and seconds */
        if (*t == 0)
                goto finish;

        r = -EINVAL;
        goto fail;

null_hour:
        r = const_chain(0, &h);
        if (r < 0)
                goto fail;

        r = const_chain(0, &m);
        if (r < 0)
                goto fail;

null_second:
        r = const_chain(0, &s);
        if (r < 0)
                goto fail;

finish:
        *p = t;
        c->hour = h;
        c->minute = m;
        c->second = s;
        return 0;

fail:
        free_chain(h);
        free_chain(m);
        free_chain(s);
        return r;
}
Example #17
0
void *net_io_config(void *args) {
	/* Get the args passed from parent thread */
	thread_args_t *targs = (thread_args_t *) args;
	cmd_line_args *cmd_args = targs->cmd_args;
	benchmark_test *bmtest = targs->bmtest;
	result_table_t *res_table = targs->res_table;
	test_results_t *result = NULL;
	int retry = 0;
	int test_status;

	/* Other Local variables of this function */
	int loop = 0, done = 0, count = 0;
	struct timespec start_time, end_time;
	long long time_diff = 0;
	pthread_t server_tid = 0;
	struct sockaddr_in server_det;
	int cl_sock_fd = 0;
	server_arguments_t *serv_args = NULL;
	pthread_attr_t attr;

	/* Use this to set the timeout value for the socket */
	struct timeval t;

	char *msg = NULL;
	int msg_size = DEF_NETIO_SZ;
	int new_iters = bmtest->_iterations;
	double clock_accuracy;
	char retry_status = UNACCEPTABLE_DEVIATIONS;
	char print_flag = FALSE;

	/*
	 * Make sure both client and server threads are running
	 * the right sched policy and priority
	 */

	/* Keep server thread alive with this stay_alive argument variable */
	serv_args = (server_arguments_t *) malloc(sizeof(server_arguments_t));
	if (serv_args == (server_arguments_t *) NULL) {
		RTMB_printf(stderr, "net_io_config: malloc() failed\n");
		abort();
	}
	memset(serv_args, 0, sizeof(server_arguments_t));
	serv_args->stay_alive = 1;
	serv_args-> iterations = new_iters;
	pthread_attr_init(&attr);

	clock_accuracy = get_min_exec_time(res_table);
	if (set_pthreadattr_sched_param(&attr, SCHED_FIFO, HIGH_PRIO_VAL) < 0) {
		targs->ret = ERROR;
		return (void *) NULL;
	}

	/* Start the server thread and let the server get into accept() code */
	if (pthread_create(&server_tid, &attr, net_server_impl, serv_args)
	        != SUCCESS) {
		RTMB_printf(stderr,
		        "net_io_config: Error creating server thread\n");
		perror("net_io_config");
		server_tid = 0;
		cleanup(serv_args, server_tid, msg, cl_sock_fd);
		targs->ret = ERROR;
		return (void *) NULL;
	}

	/* Alloc and init the msg buffer */
	msg = (char *) msg_alloc_init(msg, msg_size);
	if (msg == NULL) {
		RTMB_printf(stderr, "net_io_config: malloc() failed\n");
		abort();
	}

	/* Set the params for the server side stuff */
	server_det.sin_family = AF_INET;

	if (get_local_address(&server_det.sin_addr) < 0) {
		RTMB_printf(stderr,
		        "net_io_config: unable to get local IP \n");
		server_tid = 0;
		cleanup(serv_args, server_tid, msg, cl_sock_fd);
		targs->ret = ERROR;
		return (void *) NULL;
	}

	server_det.sin_port = htons(SERVER_PORT);
	memset(server_det.sin_zero, '\0', sizeof(server_det.sin_zero));

	/* Create the socket fd */
	cl_sock_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (cl_sock_fd == -1) {
		RTMB_printf(stderr,
		        "net_io_config: Error creating client socket\n");
		perror("net_io_config");
		cleanup(serv_args, server_tid, msg, cl_sock_fd);
		targs->ret = ERROR;
		return (void *) NULL;
	}

	/*
	 * We do not want the server thread to indefinitely wait.
	 * Set timeout to some safe value (10 secs).
	 */
	t.tv_sec = 10;
	t.tv_usec = 0;
	if (setsockopt(cl_sock_fd, SOL_SOCKET, SO_RCVTIMEO, (void *) &t,
	        sizeof(struct timeval)) != 0) {
		RTMB_printf(stderr,
		        "net_io_config: Error while setting socket option\n");
		cleanup(serv_args, server_tid, msg, cl_sock_fd);
		targs->ret = ERROR;
		return (void *) NULL;
	}

	/* give some time for the server thread to start */
	sleep(2);

	/* Connect to the server */
	while ((connect(cl_sock_fd, (struct sockaddr *) &server_det,
	        sizeof(server_det)) == -1) && (retry <= 10)) {
		do_nano_sleep(400LL * MS);
		retry++;
		RTMB_verbose_printf(stderr, cmd_args, 1,
		        "net_io_config: Retrying connect to the "
			        "server socket\n");
	}

	/* Connection done. Now, try exchanging some msgs with server */
	result = create_test_result(1, new_iters);
	if (result == NULL) {
		RTMB_printf(stderr,
		        "ERROR: Cannot allocate memory for test_results_t");
		RTMB_printf(stderr, " in net_io_config()\n");
		abort();
	}
	strcpy((char *) result->desc, "Network I/O configuration test");

	RTMB_verbose_printf(stdout, cmd_args, 1, "\nTest Report for %s:\n",
	        (char*) &result->desc);
	RTMB_verbose_printf(stdout, cmd_args, 1,
	        "========================================================="
		        "==\n");
	RTMB_verbose_printf(stdout, cmd_args, 1,
	        "\nnet_io_config : Total number of iterations = %d\n\n",
	        new_iters);

	while (!done) {
		int bytes_remaining;
		char* buffer;

		for (loop = 0; loop < new_iters; loop++) {
			int ret = SUCCESS, retry = 0;
			bytes_remaining = msg_size;
			buffer = msg;

			/* Record start time */
			if (get_cur_time(&start_time) == ERROR) {
				cleanup(serv_args, server_tid, msg, cl_sock_fd);
				free_chain(result, 0);
				targs->ret = ERROR;
				return (void *) NULL;
			}

			/* Send the msg */
			if (send(cl_sock_fd, msg, msg_size, 0) != msg_size) {
				cleanup(serv_args, server_tid, msg, cl_sock_fd);
				free_chain(result, 0);
				targs->ret = ERROR;
				return (void *) NULL;
			}

			/* Wait till you recv response */
			do {
				ret = recv(cl_sock_fd, buffer, bytes_remaining,
				        0);
				retry = 0;
				if (ret == ERROR) {
					if (errno== EINTR) {
						retry = 1;
					}
				} else if (ret > 0 && ret < bytes_remaining) {
					buffer += ret;
					bytes_remaining -= ret;
					retry = 1;

#ifdef TRACE_MSG
					RTMB_printf( stdout, "server: "
						"received = %d   "
						"expected = %d "
						"get_next = %d \n",
						ret,
						bytes_remaining + ret,
						bytes_remaining);

				} else if ( ret> 0 && ret == bytes_remaining
					&& ret != msg_size) {
					RTMB_printf( stdout, "server: "
						"received = %d   "
						"expected = %d "
						"msg_size  = %d \n",
						ret,
						bytes_remaining,
						msg_size);
#endif

				}
			} while (retry != 0);

			/*  Now, record end time */
			if (get_cur_time(&end_time) == ERROR) {
				cleanup(serv_args, server_tid, msg, cl_sock_fd);
				free_chain(result, 0);
				targs->ret = ERROR;
				return (void *) NULL;
			}

			/* If there was error other than EINTR, return fail */
			if ((retry == 0) && (ret == ERROR)) {
				cleanup(serv_args, server_tid, msg, cl_sock_fd);
				free_chain(result, 0);
				targs->ret = ERROR;
				return (void *) NULL;
			}

			/* Get the time difference of start and end times */
			time_diff = get_time_diff(start_time, end_time);
			RTMB_verbose_printf(stdout, cmd_args, 2,
			        "net_io_config: Difference between end"
				        " and start times "
				        "= %.3f us \n", MICROSEC(time_diff));

			fflush(stdout);

			add_entry(result, time_diff, 0);
		}

		if (IS_EXEC_TIME_GRT_THAN_CLK(result, clock_accuracy)) {
			print_flag = TRUE;

			/* Check against the computed median for this test */
			test_status = check_pass_criteria(result, cmd_args,
			        bmtest, 0);

			if (test_status == SUCCESS) {
				retry_status = ACCEPTABLE_DEVIATIONS;
				done = 1;
				break;
			} else {
				if (++count == bmtest->_threshold) {
					RTMB_printf(stderr,
					        "net_io_config: exceeded "
						        "maximum attempts \n");
					break;
				}
			}
		}

		if (print_flag) {
			RTMB_verbose_printf(stdout, cmd_args, 1,
			        "\nnet_io_config: Retrying test ");
			RTMB_verbose_printf(stdout, cmd_args, 1,
			        " with bigger work quantum to get"
				        " lesser variance...\n");
		}
		/*
		 * measured times are not consistent so retry with
		 * larger buffer.
		 */
		free_chain(result, 0);
		if (msg) {
			free(msg);
		}
		msg_size = msg_size * MULTIPLIER_FOR_SUB_ITER;
		msg = (char *) msg_alloc_init(msg, (msg_size));

		if (msg == NULL) {
			abort();
		}
	}

	/*net  IO rate is determined*/
	result->opern_amount = msg_size;

	add_result_to_result_table2(res_table, result, NETIO_CONFIG, bmtest);

	fflush(stdout);
	/* Clean up and leave */
	cleanup(serv_args, server_tid, msg, cl_sock_fd);
	fflush(stdout);
	targs->ret = SUCCESS;
	return (void *) NULL;
}
Example #18
0
static int parse_date(const char **p, CalendarSpec *c) {
        const char *t;
        int r;
        CalendarComponent *first, *second, *third;

        assert(p);
        assert(*p);
        assert(c);

        t = *p;

        if (*t == 0)
                return 0;

        r = parse_chain(&t, &first);
        if (r < 0)
                return r;

        /* Already the end? A ':' as separator? In that case this was a time, not a date */
        if (*t == 0 || *t == ':') {
                free_chain(first);
                return 0;
        }

        if (*t != '-') {
                free_chain(first);
                return -EINVAL;
        }

        t++;
        r = parse_chain(&t, &second);
        if (r < 0) {
                free_chain(first);
                return r;
        }

        /* Got two parts, hence it's month and day */
        if (*t == ' ' || *t == 0) {
                *p = t + strspn(t, " ");
                c->month = first;
                c->day = second;
                return 0;
        }

        if (*t != '-') {
                free_chain(first);
                free_chain(second);
                return -EINVAL;
        }

        t++;
        r = parse_chain(&t, &third);
        if (r < 0) {
                free_chain(first);
                free_chain(second);
                return r;
        }

        /* Got tree parts, hence it is year, month and day */
        if (*t == ' ' || *t == 0) {
                *p = t + strspn(t, " ");
                c->year = first;
                c->month = second;
                c->day = third;
                return 0;
        }

        free_chain(first);
        free_chain(second);
        free_chain(third);
        return -EINVAL;
}
Example #19
0
static int parse_calendar_time(const char **p, CalendarSpec *c) {
        CalendarComponent *h = NULL, *m = NULL, *s = NULL;
        const char *t;
        int r;

        assert(p);
        assert(*p);
        assert(c);

        t = *p;

        /* If no time is specified at all, then this means 00:00:00 */
        if (*t == 0)
                goto null_hour;

        r = parse_chain(&t, false, &h);
        if (r < 0)
                goto fail;

        if (*t != ':') {
                r = -EINVAL;
                goto fail;
        }

        t++;
        r = parse_chain(&t, false, &m);
        if (r < 0)
                goto fail;

        /* Already at the end? Then it's hours and minutes, and seconds are 0 */
        if (*t == 0)
                goto null_second;

        if (*t != ':') {
                r = -EINVAL;
                goto fail;
        }

        t++;
        r = parse_chain(&t, true, &s);
        if (r < 0)
                goto fail;

        /* At the end? Then it's hours, minutes and seconds */
        if (*t == 0)
                goto finish;

        r = -EINVAL;
        goto fail;

null_hour:
        r = const_chain(0, &h);
        if (r < 0)
                goto fail;

        r = const_chain(0, &m);
        if (r < 0)
                goto fail;

null_second:
        r = const_chain(0, &s);
        if (r < 0)
                goto fail;

finish:
        *p = t;
        c->hour = h;
        c->minute = m;
        c->microsecond = s;

        return 0;

fail:
        free_chain(h);
        free_chain(m);
        free_chain(s);
        return r;
}
Example #20
0
void inf_K_val(char *outfilename, int n_small, int n_large, SEQDATA *data, INIT initial)
{


    //flag=0;
    int parallelism_enabled = 1; //0=no, not 0 = yes
    int pid = getpid();
    #pragma omp parallel if(parallelism_enabled)
    {

        int K,chn,K_best,K_num;//flag,,temp;
        double **dic,*val_K;
        CONVG cvg;
        FILE *outfile;
        CHAIN chain;

        if(n_large<1||n_small<1||n_small>n_large)
        {
            n_small=1;
            n_large=(int)pow((double)data->totalsize,0.3)+1;
            fprintf(stdout,"The range of value for K is not correct! Change to default value (%d - %d)!\n",n_small,n_large);
        }
        K_num=n_large-n_small+1;
        dic=dmatrix(0,K_num-1,0,initial.chainnum-1);
        val_K=dvector(0,K_num-1);

        /*//flag=0;
        int parallelism_enabled = 1; //0=no, not 0 = yes

        #pragma omp parallel if(parallelism_enabled)
        {*/
        //initialize private variables
        char foutfilename[strlen(outfilename)];

        #pragma omp for

        for(K=n_small; K<=n_large; K++)
        {
            //modify outfilename so each K produces its own output
            strcpy(foutfilename,outfilename); //start with original outfilename

            //int K to char pK
            int ndigits = floor(log10(K)) + 1;
            char pK[ndigits]; //char array to contain int, sized to length of K
            sprintf(pK, "%d", K); //convert integer K into a char array

            //int pid to char pid
            char ppid[(sizeof(int)*CHAR_BIT-1)/3 + 3];
            sprintf(ppid, "%d", pid); //convert integer pid into a char array

            char pp[2] = ".";
            strncat(foutfilename, pp, 1); //add terminal "."
            strncat(foutfilename, ppid, strlen(ppid)); //add process id
            strncat(foutfilename, pp, 1); //add "."
            strncat(foutfilename, pK, strlen(pK)); //add "K"

            int tid = omp_get_thread_num();
            printf("t%d,K%d,pK%s,pp%s,out(%s),fout(%s),pid(%d)\n",tid,K,pK,pp,outfilename,foutfilename,pid);
            //getchar();




            data->popnum=K;

            printf("t%d,data.popnum%d\n",tid,(*data).popnum);

            if((outfile=fopen(foutfilename,"a+"))==NULL)
            {
                nrerror("Cannot open output file!");
            }
            fprintf(outfile,"\n\nThe current K is %d\n",K);


            fclose(outfile);
            if(GR_flag==1) allocate_convg(*data,&cvg,chainnum,ckrep,convgfilename);
            for(chn=0; chn<initial.chainnum; chn++)
            {
                chain=mcmc_updating((*data),initial,chn,&cvg);
                dic[K-n_small][chn]=chain_stat(foutfilename,chain,*data,chn);
                free_chain(&chain,(*data));
            }
            if(GR_flag==1)
            {
                //temp=
                chain_converg(foutfilename,&cvg);
                free_convg(&cvg);
            }
            //if(temp==1) //bad convergence or only one chain
            //{	flag=1;}
        }
    } //end omp parallel if

    //COMBINE SEPARATE OUTPUT FILES
    printf("combining files.\n");
    char foutfilename[strlen(outfilename)];
    int K;
    for(K=n_small; K<=n_large; K++)
    {
        //modify outfilename so each K produces its own output
        strcpy(foutfilename,outfilename); //start with original outfilename

        //int K to char pK
        int ndigits = floor(log10(K)) + 1;
        char pK[ndigits]; //char array to contain int, sized to length of K
        sprintf(pK, "%d", K); //convert integer K into a char array

        //int pid to char pid
        char ppid[(sizeof(int)*CHAR_BIT-1)/3 + 3];
        sprintf(ppid, "%d", pid); //convert integer pid into a char array

        char pp[2] = ".";
        strncat(foutfilename, pp, 1); //add terminal "."
        strncat(foutfilename, ppid, strlen(ppid)); //add process id
        strncat(foutfilename, pp, 1); //add "."
        strncat(foutfilename, pK, strlen(pK)); //add "K"

        //open the base file (head) and the file to append (tail)
        FILE *head = fopen(outfilename, "ab");
        FILE *tail = fopen(foutfilename, "rb");
        if (!head || !tail) abort();

        //append
        char buf[1024];
        size_t n;
        while ((n = fread(buf, 1, sizeof buf, tail)) > 0)
            if (fwrite(buf, 1, n, head) != n) abort();
        if (ferror(tail)) abort();

        //close
        fclose(head);
        fclose(tail);

        //delete the file just appended (to do)
    }




    /*
    //CALCULATE BEST K USING DIC
    //if(flag==1) //use the minimum DIC
    //{
    	for(K=0;K<K_num;K++)
    	{
    		val_K[K]=dic[K][find_min(dic[K],initial.chainnum)];
    	}
    	K_best=find_min(val_K,K_num)+n_small;
    //}
    if((outfile=fopen(outfilename,"a+"))==NULL)
    {	nrerror("Cannot open output file!");}
    fprintf(outfile,"\n\nThe range of value for K is (%d - %d)!\n",n_small,n_large);
    fprintf(outfile,"The optimal K is %d\n",K_best);
    fclose(outfile);
    free_dmatrix(dic,0,K_num-1,0,initial.chainnum-1);
    free_dvector(val_K,0,K_num-1);
    */

}
Example #21
0
void subst_free()
{
    for (int i = 0; i < N_METADATA_TYPES; i++) {
        free_chain(subs[i]);
    }
}
Example #22
0
static int parse_date(const char **p, CalendarSpec *c) {
        const char *t;
        int r;
        CalendarComponent *first, *second, *third;

        assert(p);
        assert(*p);
        assert(c);

        t = *p;

        if (*t == 0)
                return 0;

        /* @TIMESTAMP — UNIX time in seconds since the epoch */
        if (*t == '@') {
                unsigned long value;
                time_t time;

                r = parse_one_number(t + 1, &t, &value);
                if (r < 0)
                        return r;

                time = value;
                if ((unsigned long) time != value)
                        return -ERANGE;

                r = calendarspec_from_time_t(c, time);
                if (r < 0)
                        return r;

                *p = t;
                return 1; /* finito, don't parse H:M:S after that */
        }

        r = parse_chain(&t, false, &first);
        if (r < 0)
                return r;

        /* Already the end? A ':' as separator? In that case this was a time, not a date */
        if (IN_SET(*t, 0, ':')) {
                free_chain(first);
                return 0;
        }

        if (*t == '~')
                c->end_of_month = true;
        else if (*t != '-') {
                free_chain(first);
                return -EINVAL;
        }

        t++;
        r = parse_chain(&t, false, &second);
        if (r < 0) {
                free_chain(first);
                return r;
        }

        /* Got two parts, hence it's month and day */
        if (IN_SET(*t, 0, ' ')) {
                *p = t + strspn(t, " ");
                c->month = first;
                c->day = second;
                return 0;
        } else if (c->end_of_month) {
                free_chain(first);
                free_chain(second);
                return -EINVAL;
        }

        if (*t == '~')
                c->end_of_month = true;
        else if (*t != '-') {
                free_chain(first);
                free_chain(second);
                return -EINVAL;
        }

        t++;
        r = parse_chain(&t, false, &third);
        if (r < 0) {
                free_chain(first);
                free_chain(second);
                return r;
        }

        /* Got three parts, hence it is year, month and day */
        if (IN_SET(*t, 0, ' ')) {
                *p = t + strspn(t, " ");
                c->year = first;
                c->month = second;
                c->day = third;
                return 0;
        }

        free_chain(first);
        free_chain(second);
        free_chain(third);
        return -EINVAL;
}
Example #23
0
/*
 * A parser for values, inspired somewhat by Scheme/LISP S-expressions
 * and Prolog/Erlang terms.
 */
int
value_discern(struct value *top, struct scanner *sc)
{
	if (scanner_tokeq(sc, "<")) {
		struct chain *front, *back;
		struct value tag, inner;
		unsigned int size = 1;

		/* Tuple. */
		scanner_scan(sc);
		value_discern(&tag, sc);
		scanner_expect(sc, ":");
		value_discern(&inner, sc);
		back = front = add_to_chain(NULL, &inner);
		while (scanner_tokeq(sc, ",")) {
			scanner_scan(sc);
			value_discern(&inner, sc);
			back = add_to_chain(back, &inner);
			size++;
		}
		scanner_expect(sc, ">");
		value_tuple_new(top, &tag, size);
		populate_tuple_from_chain(top, front);
		free_chain(front);
		return 1;
	} else if (scanner_tokeq(sc, "[")) {
                struct value inner, *left, right;

		/* List: Sequence of tail-nested Pairs. */
		scanner_scan(sc);
		if (scanner_tokeq(sc, "]")) {
			scanner_scan(sc);
			value_copy(top, &VNULL);
			return 1;
		}
		value_tuple_new(top, &tag_list, 2);
		value_discern(&inner, sc);
		value_tuple_store(top, 0, &inner);
		/*value_tuple_store(top, 1, VNULL);*/
		left = top;
		while (scanner_tokeq(sc, ",")) {
			scanner_scan(sc);
			value_tuple_new(&right, &tag_list, 2);
			value_discern(&inner, sc);
			value_tuple_store(&right, 0, &inner);
			/*value_set_index(right, 1, VNULL);*/
			value_tuple_store(left, 1, &right);
			left = value_tuple_fetch(left, 1);
		}
		if (scanner_tokeq(sc, "|")) {
			scanner_scan(sc);
			value_discern(&right, sc);
			value_tuple_store(left, 1, &right);
		}
		scanner_expect(sc, "]");
		return 1;
	} else if (scanner_tokeq(sc, "{")) {
		struct value left, right;

		/* Dictionary: associations between keys and values. */
		scanner_scan(sc);
		value_dict_new(top, 31);

		value_discern(&left, sc);
		scanner_expect(sc, "=");
		value_discern(&right, sc);
		value_dict_store(top, &left, &right);
		while (scanner_tokeq(sc, ",")) {
			scanner_scan(sc);
			value_discern(&left, sc);
			scanner_expect(sc, "=");
			value_discern(&right, sc);
			value_dict_store(top, &left, &right);
		}
		scanner_expect(sc, "}");
		return 1;
	} else if (k_isdigit(scanner_token_string(sc)[0])) {
		/* Integer. */
		value_integer_set(top, k_atoi(scanner_token_string(sc),
					      scanner_token_length(sc)));
		scanner_scan(sc);
		return 1;
	} else {
		/* Symbol. */
		value_symbol_new(top, scanner_token_string(sc),
				 scanner_token_length(sc));
		scanner_scan(sc);
		return 1;
	}
}
static char*
build_direct_request(char *meth, struct url *url, char *headers, struct request *rq, int flags)
{
    int	rlen, authorization_done = FALSE;
    char	*answer = NULL, *fav=NULL, *httpv, *host=NULL;
    struct	buff 	*tmpbuff;
    struct	av	*av;
    int host_len=0;
    int	via_inserted = FALSE;

    // if (!TEST(flags, DONT_CHANGE_HTTPVER) ) {
//		httpv = "HTTP/1.1";
//		if ( TEST(rq->flags, RQ_HAS_HOST) )
//			host = rq->url.host;
//	} else {
    httpv = url->httpv;
    if ( !TEST(rq->flags, RQ_HAS_HOST) )
        host = rq->url.host;
//	}
    tmpbuff = alloc_buff(CHUNK_SIZE);
    if ( !tmpbuff ) return(NULL);
    rlen = strlen(meth) + 1/*sp*/ + strlen(url->path) + 1/*sp*/ +
           strlen(httpv) + 2/* \r\n */;
    if(TEST(rq->flags,RQ_USE_PROXY)) {
        rlen=rlen+7+strlen(rq->url.host);
        if(rq->url.port!=80)
            rlen=rlen+7;
    }
    answer = (char *)xmalloc(ROUND(rlen+1,CHUNK_SIZE), "build_direct_request(): 1"); /* here answer is actually *request* buffer */
    if ( !answer )
        goto fail;
    memset(answer,0,rlen+1);
    if(TEST(rq->flags,RQ_USE_PROXY)) {
        if(rq->url.port!=80)
            snprintf(answer,rlen,"%s http://%s:%d%s %s\r\n",meth,rq->url.host,rq->url.port,rq->url.path,httpv);
        else
            snprintf(answer,rlen,"%s http://%s%s %s\r\n",meth,rq->url.host,rq->url.path,httpv);
    } else {
        sprintf(answer, "%s %s %s\r\n", meth, rq->url.path, httpv);
    }
//  printf("host=%s.path=%s.\n",rq->url.host,rq->url.path);
//  printf("answer=%s.\n",answer);
    if ( attach_data(answer, strlen(answer), tmpbuff) )
        goto fail;
    if ( headers ) { /* attach what was requested */
        if ( attach_data(headers, strlen(headers), tmpbuff) )
            goto fail;
    }
    host_len=strlen(rq->url.host)+10;
    host=(char *)malloc(host_len);
    memset(host,0,host_len);
    if(rq->url.port!=80)
        snprintf(host,host_len-1,"%s:%d",rq->url.host,rq->url.port);
    else
        snprintf(host,host_len-1,"%s",rq->url.host);
    if(fav=format_av_pair("Host:",host)) {
        if(attach_data(fav,strlen(fav),tmpbuff))
            goto fail;
        xfree(fav);
        fav=NULL;
    }

    free(host);
    av = rq->av_pairs;
    while ( av ) {
        if ( is_attr(av, "Proxy-Connection:") )
            goto do_not_insert;
        if ( is_attr(av, "Proxy-Authorization:") ) /* hop-by-hop */
            goto do_not_insert;
        if ( is_attr(av, "Connection:") )
            goto do_not_insert;
        if( is_attr(av,"Host:"))
            goto do_not_insert;
        if ( is_attr(av, "Via:") && conf.insert_via  && !via_inserted ) {
            /* attach my Via: */
            if ( (fav = format_av_pair(av->attr, av->val)) != 0 ) {
                char    *buf;
                buf = strchr(fav, '\r');
                if ( buf ) *buf = 0;
                if ( !buf ) {
                    buf = strchr(fav, '\n');
                    if ( buf ) *buf = 0;
                }
                int buf_len=strlen(fav)+2+18+7+10+strlen(VER_ID)+2+1;
                buf =(char *)malloc(buf_len);
                if ( !buf ) goto fail;
                memset(buf,0,buf_len);
                snprintf(buf,buf_len-1,"%s,%d.%d %s:%d (kingate/%s)\r\n",fav,rq->http_major,rq->http_minor,rq->client->get_server_name() ,conf.port[HTTP], VER_ID);
                if ( attach_data(buf, strlen(buf), tmpbuff) ) {
                    xfree(buf);
                    goto fail;
                }
                via_inserted = TRUE;
                xfree(buf);
                xfree(fav);
                fav = NULL;
            }
            goto do_not_insert;
        }
        if ( (fav=format_av_pair(av->attr, av->val)) != 0 ) {
            if ( attach_data(fav, strlen(fav), tmpbuff) )
                goto fail;
            xfree(fav);
            fav = NULL;
        }
do_not_insert:
        av = av->next;
    }
    if ( (fav = format_av_pair("Connection:", "close")) != 0 ) {
        if ( attach_data(fav, strlen(fav), tmpbuff) )
            goto fail;
        xfree(fav);
        fav = NULL;
    }
    if(conf.x_forwarded_for) {
        if( (fav=format_av_pair("X-Forwarded-For:",(char *)rq->server->get_client_name()))!=0) {
            if ( attach_data(fav, strlen(fav), tmpbuff) )
                goto fail;
            xfree(fav);
            fav = NULL;
        }
    }
    if (conf.insert_via && !via_inserted ) {
        char *buf;
        int buf_len=4+1+18+7+10+strlen(VER_ID)+2+1;
        buf =(char *) malloc(buf_len);
        if ( !buf ) goto fail;
        memset(buf,0,buf_len);
        snprintf(buf,buf_len-1,"Via: %d.%d %s:%d (kingate/%s)\r\n",rq->http_major,rq->http_minor, rq->client->get_server_name(),conf.port[HTTP], VER_ID);
        if ( attach_data(buf, strlen(buf), tmpbuff) ) {
            xfree(buf);
            goto fail;
        }
        xfree(buf);
        xfree(fav);
        fav = NULL;
    }

    /* CRLF  */
    if ( attach_data("\r\n", 2, tmpbuff) )
        goto fail;
    if ( attach_data("", 1, tmpbuff) )
        goto fail;
    IF_FREE(answer);
    answer = tmpbuff->data;
    tmpbuff->data = NULL;
    free_chain(tmpbuff);
    //printf("%s",answer);
    return answer;
fail:
    IF_FREE(fav);
    IF_FREE(host);
    if (tmpbuff) free_chain(tmpbuff);
    IF_FREE(answer);
    return NULL;
}
Example #25
0
static void dma_cb(void * p)
{
  if (p) {
    dma_chain_t * chain = (dma_chain_t *) p;

    if (chain->count > 0) {
/*       vid_border_color(0, 0, 0); */
/*       ta_block_render = 0; */
/*       ta_render_done_cb = renderdone_cb; */
/*       return; */
    } else {

      vid_border_color(0, 255, 0);
    
      printf("\n!!!!!! dma done !\n");
      if (chain->sema == NULL) {
	free_chain(chain);
      } else {
	sem_signal(chain->sema);
	chain->dest = 0; /* mark dma completed */
      }

      dma_transfering = 0;
    }
  }

  if (chain_head) {
    dma_chain_t * chain = chain_head;
    ta_block_render = 1;

    static int toto;
    toto += 64;
    vid_border_color(255, toto&255, toto&255);
    dma_transfering = 1;

    printf("\n!!!!!! dma transfer ! \n");
    switch(chain->type) {
    case DMA_TYPE_VRAM:
      pvr_txr_load_dma(chain->src, chain->dest, 
		       chain->count, 0, dma_cb, chain);
      break;
/*     case DMA_TYPE_SPU: */
/*       if (chain->count > SPU_MAX_SZ) { */
/* 	//panic("chain->count > SPU_MAX_SZ\n"); */
/* 	dma_cache_flush(chain->src, chain->count); */
/* 	spu_dma_transfer(chain->src, chain->dest, SPU_MAX_SZ, 0,  */
/* 			 (spu_dma_callback_t) dma_cb,  */
/* 			 (ptr_t) chain); */
/* 	chain->count -= SPU_MAX_SZ; */
/* 	chain->dest += SPU_MAX_SZ; */
/* 	chain->src += SPU_MAX_SZ; */
/* 	return; */
/*       } else { */
/* 	spu_dma_transfer(chain->src, chain->dest, chain->count,  */
/* 			 0,  */
/* 			 (spu_dma_callback_t) dma_cb,  */
/* 			 (ptr_t) chain); */
/*       } */
      
/*       break; */
    default:
      assert(0 && "got bad dma chain type in dma_cb");
    }

    chain->count = 0;
    chain_head = chain->next;

  } else {
    printf("\n!!!!!! all dma done !\n");
    ta_block_render = 0;
    vid_border_color(0, 0, 0);
  }
}
Example #26
0
char disk_io_read(test_results_t* result, int iters, cmd_line_args * cmd_args,
        benchmark_test* bmtest, result_table_t* res_table) {
	FILE *read_fp = NULL;
	long long time_diff;
	int block_size = 0;
	int done, loop, j;
	double clock_accuracy;
	char retry_status = UNACCEPTABLE_DEVIATIONS;
	int sub_iters = DEFAULT_SUBITERS;

	int count = 0;
	char *_read_buf = NULL;
	char print_flag = FALSE;
	struct timespec start_time, end_time;

	block_size = get_block_size();

	assert(block_size> 0);

	clock_accuracy = get_min_exec_time(res_table);

	RTMB_verbose_printf(stdout, cmd_args, 1,
	        "\nTest Report for disk I/O read configuration:\n");

	RTMB_verbose_printf(stdout, cmd_args, 1,
	        "=================================================\n");
	RTMB_verbose_printf(stdout, cmd_args, 1,
	        "\ndisk_io_config: Total number of iterations = %d\n\n", iters);

	done = 0;
	while (!done) {
		int n;
		_read_buf = calloc(1, block_size);

		if (_read_buf == NULL) {
			RTMB_printf(stderr,
			        "calloc() failed in disk_io_read_config()\n");
			abort();
		}

		/*Make sure there is data in the file before attempting a read*/
		setup_file_for_read(block_size * sub_iters, 1);

		for (loop = 0; loop < iters; loop++) {
			open_file_for_read(&read_fp);

			if (get_cur_time(&start_time) == ERROR) {
				abort();
			}

			for (j = 0; j < sub_iters; j++) {
				if ((n = fread(_read_buf, sizeof(char),
				        block_size, read_fp)) != block_size) {
					perror("fwrite:");
					abort();
				}
			}

			if (get_cur_time(&end_time) == ERROR) {
				abort();
			}

			/* Get the time difference of start and end times */
			time_diff = get_time_diff(start_time, end_time);
			RTMB_verbose_printf(stdout, cmd_args, 2,
			        "disk_io_read_config: Difference between end"
				        " and start times = %.3f us\n",
			        MICROSEC(time_diff));

			add_entry(result, time_diff, 0);
			fclose(read_fp);
		}

		if (IS_EXEC_TIME_GRT_THAN_CLK(result, clock_accuracy)) {
			print_flag = TRUE;
			if (check_pass_criteria(result, cmd_args, bmtest, 0)
			        == SUCCESS) {
				/*
				 * test passed,
				 * disk IO rate is determined
				 */
				retry_status = ACCEPTABLE_DEVIATIONS;
				done = 1;
				break;
			} else {
				/*If we have completed, return error*/
				if (++count == bmtest->_threshold) {
					RTMB_printf(stderr,
					        "disk_io_read_config: exceeded"
						        " maximum attempts \n");
					break;
				}

			}
		}

		if (print_flag == TRUE) {
			RTMB_verbose_printf(stdout, cmd_args, 1,
			        "\ndisk_io_read_config: Retrying test");
			RTMB_verbose_printf(stdout, cmd_args, 1,
			        " with bigger work quantum to get"
				        " lesser variance...\n");
		}

		/*
		 * measured times are not accurate enough,
		 * hence retry.
		 */
		free_chain(result, 0);
		sub_iters *= MULTIPLIER_FOR_SUB_ITER;
		free(_read_buf);
	}

	result->opern_amount = block_size * sub_iters;

	return retry_status;
}
Example #27
0
/**
 * A body filter to intercept response body and feed it to Ironbee,
 * and to buffer the data if required by Ironbee configuration.
 *
 * @param[in]  r     The nginx request object.
 * @param[in]  in    The data to filter.
 * @return     status propagated from next filter, or OK/Error
 */
static ngx_int_t ironbee_body_out(ngx_http_request_t *r, ngx_chain_t *in)
{
    ngx_log_t *prev_log;
    ngxib_req_ctx *ctx;
    ngx_chain_t *link;
    ib_status_t rc;
    ib_num_t num;
    ngx_int_t rv = NGX_OK;
    ib_txdata_t itxdata;

    if (r->internal)
        return ngx_http_next_body_filter(r, in);

    prev_log = ngxib_log(r->connection->log);

    ctx = ngx_http_get_module_ctx(r, ngx_ironbee_module);
    assert((ctx != NULL) && (ctx->tx != NULL));
    ib_log_debug_tx(ctx->tx, "ironbee_body_out");
    if (in == NULL) {
        /* FIXME: could this happen in circumstances when we should
         * notify Ironbee of end-of-response ?
         */
        ib_log_debug_tx(ctx->tx, "ironbee_body_out: input was null");
        cleanup_return(prev_log) ngx_http_next_body_filter(r, in);
    }
    ctx = ngx_http_get_module_ctx(r, ngx_ironbee_module);
    if (ctx->output_filter_done) {
        ib_log_debug_tx(ctx->tx, "ironbee_body_out: already done");
        cleanup_return(prev_log) ngx_http_next_body_filter(r, in);
    }
    if (!ctx->output_filter_init) {
        ctx->output_filter_init = 1;

        if (ctx->internal_errordoc) {
            /* If it's our own errordoc, pass it straight through */
            /* Should we log anything here?  The error will already
             * have been logged.
             */
            ctx->output_buffering = IOBUF_NOBUF;
            ctx->response_buf = NULL;
            ib_log_debug_tx(ctx->tx, "ironbee_body_out: in internal errordoc");
        }
        else {
            /* Determine whether we're configured to buffer */
            rc = ib_context_get(ctx->tx->ctx, "buffer_res",
                                ib_ftype_num_out(&num), NULL);
            ib_log_debug_tx(ctx->tx, "ironbee_body_out: buffer_res is %d", (int)num);
            if (rc != IB_OK)
                ib_log_error_tx(ctx->tx,
                                "Can't determine output buffer configuration!");
            if (num == 0) {
                ib_log_debug_tx(ctx->tx, "ironbee_body_out: NOBUF");
                ctx->output_buffering = IOBUF_NOBUF;
                ctx->response_buf = NULL;
            }
            else {
                /* If we're buffering, initialise the buffer */
                ib_log_debug_tx(ctx->tx, "ironbee_body_out: BUFFER");
                ctx->output_buffering = IOBUF_BUFFER;
            }
        }
    }

    ngx_regex_malloc_init(r->pool);

    for (link = in; link != NULL; link = link->next) {
        /* Feed the data to ironbee */
        itxdata.data = link->buf->pos;
        itxdata.dlen = link->buf->last - link->buf->pos;
        ib_log_debug_tx(ctx->tx, "ironbee_body_out: %d bytes",
                        (int)itxdata.dlen);
        if (itxdata.dlen > 0) {
            ib_state_notify_response_body_data(ironbee, ctx->tx, &itxdata);
        }

        /* If Ironbee just signalled an error, switch to discard data mode,
         * and dump anything we already have buffered,
         */
        if ( (STATUS_IS_ERROR(ctx->status)) &&
             !ctx->internal_errordoc &&
             (ctx->output_buffering != IOBUF_DISCARD) ) {
            ib_log_debug_tx(ctx->tx, "ironbee_body_out: error %d", ctx->status);
            free_chain(r->pool, ctx->response_buf);
            ctx->response_buf = NULL;
            ctx->output_buffering = IOBUF_DISCARD;
        }
        else if (ctx->output_buffering == IOBUF_BUFFER) {
            /* Copy any data to our buffer */
            if (ctx->response_buf == NULL) {
                ctx->response_buf = ngx_pcalloc(r->pool, sizeof(ngx_chain_t));
                ctx->response_ptr = ctx->response_buf;
            }
            else {
                ctx->response_ptr->next = ngx_pcalloc(r->pool, sizeof(ngx_chain_t));
                ctx->response_ptr = ctx->response_ptr->next;
            }
            /* Not sure if any data types need setaside, but let's be safe */
#if NO_COPY_REQUIRED
            ctx->response_ptr->buf = link->buf;
#else
            if (itxdata.dlen > 0) {
                ctx->response_ptr->buf = ngx_create_temp_buf(r->pool, itxdata.dlen);
                memcpy(ctx->response_ptr->buf->pos, link->buf->pos, itxdata.dlen);
                ctx->response_ptr->buf->last += itxdata.dlen;
            }
            else {
                ctx->response_ptr->buf = ngx_palloc(r->pool, sizeof(ngx_buf_t));
                memcpy(ctx->response_ptr->buf, link->buf, sizeof(ngx_buf_t));
            }
#endif
        }

        if (link->buf->last_buf) {
            ib_log_debug_tx(ctx->tx, "ironbee_body_out: last_buf");
            ctx->output_filter_done = 1;
        }
    }

    if (ctx->output_buffering == IOBUF_NOBUF) {
        /* Normal operation - pass it down the chain */
        ib_log_debug_tx(ctx->tx, "ironbee_body_out: passing on");
        ctx->start_response = 1;
        rv = ngx_http_next_body_filter(r, in);
    }
    else if (ctx->output_buffering == IOBUF_BUFFER) {
        ib_log_debug_tx(ctx->tx, "ironbee_body_out: buffering");
        if (ctx->output_filter_done) {
            /* We can pass on the buffered data all at once */
            ib_log_debug_tx(ctx->tx, "ironbee_body_out: passing buffer");
            ctx->start_response = 1;
            rv = ngx_http_next_body_filter(r, ctx->response_buf);
        }
    }
    else if (ctx->output_buffering == IOBUF_DISCARD) {
        ib_log_debug_tx(ctx->tx, "ironbee_body_out: discarding");
        if (ctx->output_filter_done) {
            /* Pass a last bucket with no data */
            //ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0,
            //              "ironbee_body_out: passing NULL last-buffer");
            //ctx->response_buf = ngx_pcalloc(r->pool, sizeof(ngx_chain_t));
            //ctx->response_buf->buf = ngx_calloc_buf(r->pool);
            //ctx->response_buf->buf->last_buf = ctx->response_buf->buf->last_in_chain = 1;
            //rv = ngx_http_next_body_filter(r, ctx->response_buf);
            /* FIXME: Is setting rv enough to serve error page */
            rv = ctx->status;
        }
    }
    if (ctx->output_filter_done) {
        ib_log_debug_tx(ctx->tx, "ironbee_body_out: notify_postprocess");
        rc = ib_state_notify_postprocess(ironbee, ctx->tx);
        if ((rv == NGX_OK) && (rc != IB_OK)) {
            rv = NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
        rc = ib_state_notify_logging(ironbee, ctx->tx);
        if ((rv == NGX_OK) && (rc != IB_OK)) {
            rv = NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
    }
    cleanup_return(prev_log) rv;
}