Exemple #1
0
int main(void){

    init_heap_and_dp();

#ifdef DEBUG_MODE
    print_heap(HEAP_MAX_LENGTH);
#endif

    /* Heap sort */
    mark_start();
    heap_sort(HEAP_MAX_LENGTH);
    mark_stop();
    get_time_difference(&time_count);

    printf("Time taken by heap sort: %d\n",(int)time_count.tv_usec);

#ifdef DEBUG_MODE
    print_heap(HEAP_MAX_LENGTH);
#endif

#ifdef DEBUG_MODE
    printf("Sort with bitmap.\n");
#endif

    /* Bitmap sort algorithm */
    mark_start();
    for (i = 1; i < HEAP_MAX_LENGTH; i++){
        set_bit_in_map((unsigned)array[i]);
    }
    mark_stop();
    get_time_difference(&time_count);

    printf("Time taken by bitmap sort: %d\n",(int)time_count.tv_usec);

#ifdef DEBUG_MODE
    show_bitmap();
    for (i = 1; i < MAP_MAX_LENGTH; i++){
        if (check_bit_in_map(i)){
            printf("%u\t", i);
        }
    }
    printf("\n");
#endif

    /* Algorithm: dp */
    printf("This is dp result: %d\n", dp_demo(5));

    /* Algorithm: BP(artificial network) */
    test_aritificial_neural_network();

    /* Algorithm: manacher */
    test_manacher();

    return 0;
}
Exemple #2
0
void display_information(int sig)
{

	print_log(INFO,"\n-----------------------------SERVER iNFO-----------------------------");
	print_log(ERROR,"\nCURRENT LOG LEVELS              : ERROR");
	print_log(WARNING,",WARNING");
	print_log(INFO,",INFO");
	print_log(DEBUG,",DEBUG");
	print_log(INFO,"\nDocument Root                    : %s",path_root);
	print_log(INFO,"\nPort No                          : %d",port_number);
	print_log(INFO,"\nResponse Strategy                : %s",strategy_name);
	
	if(strstr(strategy_name,"Fork")) 
	{	
		
		print_log(INFO,"\n---------------------------------------------------------------------\n");
		return;
	}
	if(strcmp(strategy_name,"Thread Pool")==0)
	{
		print_log(INFO,"\nThread Pool Size                 : %d",worker_max);
		print_log(INFO,"\nWorker Size        	         : %d",buffer_max);
	}

	print_log(INFO,"\nTotal Requests handled           : %d",show_total_requests());
	print_log(INFO,"\nTotal amount of data transferred : %d bytes",show_total_size());
	s_stop(&total_uptime);
	get_time_difference(&total_uptime);
	print_log(INFO,"\nTotal uptime                     : %s",show_time_difference(&total_uptime));
	print_log(INFO,"\nTotal time spent serving requets : %s",show_total_time_difference(&requests_time));

	print_log(INFO,"\nAvg time spent serving requests  : %s",show_average_time(&requests_time,show_total_requests()));
	print_log(INFO,"\n---------------------------------------------------------------------\n");
}
Exemple #3
0
void print_metrics(int j, int port, ReflectorUPacket pack) {
    struct timeval recv_resp_time, send_time, recv_time, reflect_time;

    /* Get Time of the received TWAMP-Test response message */
    gettimeofday(&recv_resp_time, NULL);

    /* Get the timestamps from the reflected message */
    timestamp_to_timeval(&pack.sender_time, &send_time);
    timestamp_to_timeval(&pack.receive_time, &recv_time);
    timestamp_to_timeval(&pack.time, &reflect_time);

    /* Print different metrics */

    /* Compute round-trip */
    fprintf(stderr, "Round-trip time for TWAMP-Test packet %d for port %hd is %" PRIu64 " [usec]\n",
            j, port, get_time_difference(&recv_resp_time, &send_time));
    fprintf(stderr, "Receive time - Send time for TWAMP-Test"
            " packet %d for port %d is %" PRIu64 " [usec]\n", j, port,
            get_time_difference(&recv_time, &send_time));
    fprintf(stderr, "Reflect time - Send time for TWAMP-Test"
            " packet %d for port %d is %" PRIu64 " [usec]\n", j, port,
            get_time_difference(&reflect_time, &send_time));

}
Exemple #4
0
static void manage_single_request(int peer_sfd)
{
	s_start(&requests_time);
	http_request_t  *request  = (http_request_t*)malloc(sizeof(http_request_t));	
	http_response_t *response = (http_response_t*)malloc(sizeof(http_response_t));	
	strcpy(response->resource_path,path_root);

	next_request(peer_sfd, request);
	build_response(request, response);
	send_response(peer_sfd, response);

	clear_responses(response);
	free(request);
	free(response);	
	s_stop(&requests_time);
	get_time_difference(&requests_time);
}
Exemple #5
0
/**
 * Main loop of the Powermanga game
 */
void
main_loop (void)
{
  Sint32 pause_delay = 0;
  Sint32 frame_diff = 0;
  do
    {
      loops_counter++;
      if (!power_conf->nosync)
        {
          frame_diff = get_time_difference ();
          if (movie_playing_switch != MOVIE_NOT_PLAYED)
            {
              pause_delay =
                wait_next_frame (MOVIE_FRAME_RATE - frame_diff + pause_delay,
                                 MOVIE_FRAME_RATE);
            }
          else
            {
              pause_delay =
                wait_next_frame (GAME_FRAME_RATE - frame_diff + pause_delay,
                                 GAME_FRAME_RATE);
            }
        }
      /* handle Powermanga game */
      if (!update_frame ())
        {
          quit_game = TRUE;
        }
      /* handle keyboard and joystick events */
      display_handle_events ();

      /* update our main window */
      display_update_window ();

#ifdef USE_SDLMIXER
      /* play music and sounds */
      sound_handle ();
#endif
    }
  while (!quit_game);
}
Exemple #6
0
static int wss_raw_writev(struct tcp_connection *c, int fd,
		const struct iovec *iov, int iovcnt, int tout)
{
	struct timeval snd;
	int i, n, ret = 0;
#ifdef TLS_DONT_WRITE_FRAGMENTS
	static char *buf = NULL;
#endif

	start_expire_timer(snd,tcpthreshold);

#ifndef TLS_DONT_WRITE_FRAGMENTS
	for (i = 0; i < iovcnt; i++) {
		n = tls_blocking_write(c, fd, iov[i].iov_base, iov[i].iov_len, &tls_mgm_api);
		if (n < 0) {
			ret = -1;
			goto end;
		}
		ret += n;
	}
#else
	n = 0;
	for (i = 0; i < iovcnt; i++)
		n += iov[i].iov_len;
	buf = pkg_realloc(buf, n);
	if (!buf) {
		ret = -2;
		goto end;
	}
	n = 0;
	for (i = 0; i < iovcnt; i++) {
		memcpy(buf + n, iov[i].iov_base, iov[i].iov_len);
		n += iov[i].iov_len;
	}
	n = tls_blocking_write(c, fd, buf, n, &tls_mgm_api);

#endif /* TLS_DONT_WRITE_FRAGMENTS */

end:
	get_time_difference(snd, tcpthreshold, tout);
	return ret;
}
Exemple #7
0
/*! \brief Finds a tcpconn & sends on it */
static int proto_ws_send(struct socket_info* send_sock,
											char* buf, unsigned int len,
											union sockaddr_union* to, int id)
{
	struct tcp_connection *c;
	struct timeval get;
	struct ip_addr ip;
	int port = 0;
	int fd, n;

	reset_tcp_vars(tcpthreshold);
	start_expire_timer(get,tcpthreshold);

	if (to){
		su2ip_addr(&ip, to);
		port=su_getport(to);
		n = tcp_conn_get(id, &ip, port, &c, &fd);
	}else if (id){
		n = tcp_conn_get(id, 0, 0, &c, &fd);
	}else{
		LM_CRIT("prot_tls_send called with null id & to\n");
		get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
		return -1;
	}

	if (n<0) {
		/* error during conn get, return with error too */
		LM_ERR("failed to aquire connection\n");
		get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
		return -1;
	}

	/* was connection found ?? */
	if (c==0) {
		if (tcp_no_new_conn) {
			return -1;
		}
		LM_DBG("no open tcp connection found, opening new one\n");
		/* create tcp connection */
		if ((c=ws_connect(send_sock, to, &fd))==0) {
			LM_ERR("connect failed\n");
			return -1;
		}
		goto send_it;
	}
	get_time_difference(get, tcpthreshold, tcp_timeout_con_get);

	/* now we have a connection, let's what we can do with it */
	/* BE CAREFUL now as we need to release the conn before exiting !!! */
	if (fd==-1) {
		/* connection is not writable because of its state */
		/* return error, nothing to do about it */
		tcp_conn_release(c, 0);
		return -1;
	}

send_it:
	LM_DBG("sending via fd %d...\n",fd);

	n = ws_req_write(c, fd, buf, len);
	stop_expire_timer(get, tcpthreshold, "WS ops",buf,(int)len,1);
	tcp_conn_set_lifetime( c, tcp_con_lifetime);

	LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd);
	if (n<0){
		LM_ERR("failed to send\n");
		c->state=S_CONN_BAD;
		if (c->proc_id != process_no)
			close(fd);
		tcp_conn_release(c, 0);
		return -1;
	}

	/* only close the FD if not already in the context of our process
	either we just connected, or main sent us the FD */
	if (c->proc_id != process_no)
		close(fd);

	tcp_conn_release(c, 0);
	return n;
}
Exemple #8
0
// Main searching function (loops inside)
void search(
	    Search_settings *sett,
	    Command_line_opts *opts,
	    Search_range *s_range,
	    FFTW_plans *plans,
	    FFTW_arrays *fftw_arr,
	    Aux_arrays *aux,
	    int *FNum ) {

  // struct stat buffer;
  struct flock lck;

  int pm, mm, nn;       // hemisphere, sky positions 
  int sgnlc=0;          // number of candidates
  FLOAT_TYPE *sgnlv;    // array with candidates data

  char outname[512];
  int fd, status;
  FILE *state;

#ifdef YEPPP
  status = yepLibrary_Init();
  assert(status == YepStatusOk);
#endif

#ifdef TIMERS
  struct timespec tstart = get_current_time(CLOCK_REALTIME), tend;
#endif
  
  // Allocate buffer for triggers
  sgnlv = (FLOAT_TYPE *)calloc(NPAR*2*sett->nfft, sizeof(FLOAT_TYPE));

  state = NULL;
  if(opts->checkp_flag) 
    state = fopen (opts->qname, "w");
  
  /* Loop over hemispheres */ 
  
  for (pm=s_range->pst; pm<=s_range->pmr[1]; ++pm) {

    sprintf (outname, "%s/triggers_%03d_%04d%s_%d.bin", 
	     opts->prefix, opts->ident, opts->band, opts->label, pm);
    
    /* Two main loops over sky positions */ 
    
    for (mm=s_range->mst; mm<=s_range->mr[1]; ++mm) {	
      for (nn=s_range->nst; nn<=s_range->nr[1]; ++nn) {	
	
        if(opts->checkp_flag) {
          ftruncate(fileno(state), 0);  
	  fprintf(state, "%d %d %d %d %d\n", pm, mm, nn, s_range->sst, *FNum);
	  fseek(state, 0, SEEK_SET);
	}
	
	/* Loop over spindowns is inside job_core() */
	status = job_core(
			  pm,           // hemisphere
			  mm,           // grid 'sky position'
			  nn,           // other grid 'sky position'
			  sett,         // search settings
			  opts,         // cmd opts
			  s_range,      // range for searching
			  plans,        // fftw plans 
			  fftw_arr,     // arrays for fftw
			  aux,          // auxiliary arrays
			  &sgnlc,       // current number of candidates
			  sgnlv,        // candidate array
			  FNum);        // candidate signal number
	
	// Get back to regular spin-down range
	s_range->sst = s_range->spndr[0];

	/* Add trigger parameters to a file */
	// if enough signals found (no. of signals > half length of buffer)
	if (sgnlc > sett->nfft) {
	  if((fd = open (outname, 
			 O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|
			 S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
	    perror(outname);
	    return;
	  }

#ifdef USE_LOCKING
	  lck.l_type = F_WRLCK;
	  lck.l_whence = 0;
	  lck.l_start = 0L;
	  lck.l_len = 0L;
          if (fcntl (fd, F_SETLKW, &lck) < 0) perror ("fcntl()");
#endif
          write(fd, (void *)(sgnlv), sgnlc*NPAR*sizeof(FLOAT_TYPE));
          if (close(fd) < 0) perror ("close()");
	  sgnlc=0;

	} /* if sgnlc > sett-nfft */
      } // for nn
      s_range->nst = s_range->nr[0];
    } // for mm
    s_range->mst = s_range->mr[0]; 

    // Write the leftover from the last iteration of the buffer 
    if((fd = open(outname, 
		  O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|
		  S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
      perror(outname);
      return; 
    }

#ifdef USE_LOCKING
    lck.l_type = F_WRLCK;
    lck.l_whence = 0;
    lck.l_start = 0L;
    lck.l_len = 0L;
    if (fcntl (fd, F_SETLKW, &lck) < 0) perror ("fcntl()");
#endif
    write(fd, (void *)(sgnlv), sgnlc*NPAR*sizeof(FLOAT_TYPE));
    if (close(fd) < 0) perror ("close()");
    sgnlc=0; 

  } // for pm
  
  //#mb state file has to be modified accordingly to the buffer
  if(opts->checkp_flag) 
    fclose(state); 

  // Free triggers buffer
  free(sgnlv);

#ifdef TIMERS
  tend = get_current_time(CLOCK_REALTIME);
  double time_elapsed = get_time_difference(tstart, tend);
  printf("Time elapsed: %e s\n", time_elapsed);
#endif

}
Exemple #9
0
int job_core(int pm,                   // Hemisphere
	     int mm,                   // Grid 'sky position'
	     int nn,                   // Second grid 'sky position'
	     Search_settings *sett,    // Search settings
	     Command_line_opts *opts,  // Search options 
	     Search_range *s_range,    // Range for searching
	     FFTW_plans *plans,        // Plans for fftw
	     FFTW_arrays *fftw_arr,    // Arrays for fftw
	     Aux_arrays *aux,          // Auxiliary arrays
	     int *sgnlc,               // Candidate trigger parameters 
	     FLOAT_TYPE *sgnlv,        // Candidate array 
	     int *FNum) {              // Candidate signal number

  int i, j, n;
  int smin = s_range->sst, smax = s_range->spndr[1];
  double al1, al2, sinalt, cosalt, sindelt, cosdelt, sgnlt[NPAR], 
    nSource[3], het0, sgnl0, ft;
  double _tmp1[sett->nifo][sett->N];

#undef NORMTOMAX
#ifdef NORMTOMAX
  double blkavg, threshold = 6.;
  int imax, imax0, iblk, blkstart, ihi;
  int blksize = 1024;
  int nfft = sett->nmax - sett->nmin;
  static int *Fmax;
  if (!Fmax) Fmax = (int *) malloc(nfft*sizeof(int));
#endif

  struct timespec tstart, tend;
  double spindown_timer = 0;
  int spindown_counter  = 0;
  
  //tstart = get_current_time(CLOCK_REALTIME);

  /* Matrix	M(.,.) (defined on page 22 of PolGrawCWAllSkyReview1.pdf file)
     defines the transformation form integers (bin, ss, nn, mm) determining
     a grid point to linear coordinates omega, omegadot, alpha_1, alpha_2),
     where bin is the frequency bin number and alpha_1 and alpha_2 are
     defined on p. 22 of PolGrawCWAllSkyReview1.pdf file.

     [omega]                          [bin]
     [omegadot]       = M(.,.) \times [ss]
     [alpha_1/omega]                  [nn]
     [alpha_2/omega]                  [mm]

     Array M[.] is related to matrix M(.,.) in the following way;

                 [ M[0] M[4] M[8]  M[12] ]
      M(.,.) =   [ M[1] M[5] M[9]  M[13] ]
                 [ M[2] M[6] M[10] M[14] ]
                 [ M[3] M[7] M[11] M[15] ]

     and

     M[1] = M[2] = M[3] = M[6] = M[7] = 0
  */

  // Grid positions
  al1 = nn*sett->M[10] + mm*sett->M[14];
  al2 = nn*sett->M[11] + mm*sett->M[15];

  // check if the search is in an appropriate region of the grid
  // if not, returns NULL
  if ((sqr(al1)+sqr(al2))/sqr(sett->oms) > 1.) return 0;

  int ss;
  double shft1, phase, cp, sp;
  complex double exph;

  // Change linear (grid) coordinates to real coordinates
  lin2ast(al1/sett->oms, al2/sett->oms, 
	  pm, sett->sepsm, sett->cepsm,
	  &sinalt, &cosalt, &sindelt, &cosdelt);

  // calculate declination and right ascention
  // written in file as candidate signal sky positions
  sgnlt[2] = asin(sindelt);
  sgnlt[3] = fmod(atan2(sinalt, cosalt) + 2.*M_PI, 2.*M_PI);

  het0 = fmod(nn*sett->M[8] + mm*sett->M[12], sett->M[0]);

  // Nyquist frequency 
  int nyqst = (sett->nfft)/2 + 1;

  // Loop for each detector 
  /* Amplitude modulation functions aa and bb 
   * for each detector (in signal sub-struct 
   * of _detector, ifo[n].sig.aa, ifo[n].sig.bb) 
   */
  for(n=0; n<sett->nifo; ++n) {
    modvir(sinalt, cosalt, sindelt, cosdelt,
           sett->N, &ifo[n], aux);

    // Calculate detector positions with respect to baricenter
    nSource[0] = cosalt*cosdelt;
    nSource[1] = sinalt*cosdelt;
    nSource[2] = sindelt;
    
    shft1 = nSource[0]*ifo[n].sig.DetSSB[0]
          + nSource[1]*ifo[n].sig.DetSSB[1]
          + nSource[2]*ifo[n].sig.DetSSB[2];

#define CHUNK 4
#pragma omp parallel default(shared) private(phase,cp,sp,exph)
    {
#pragma omp for schedule(static,CHUNK)
      for(i=0; i<sett->N; ++i) {
	ifo[n].sig.shft[i] = nSource[0]*ifo[n].sig.DetSSB[i*3]
	                   + nSource[1]*ifo[n].sig.DetSSB[i*3+1]
	                   + nSource[2]*ifo[n].sig.DetSSB[i*3+2];
	ifo[n].sig.shftf[i] = ifo[n].sig.shft[i] - shft1;
	_tmp1[n][i] = aux->t2[i] + (double)(2*i)*ifo[n].sig.shft[i];
      }

#pragma omp for schedule(static,CHUNK) 
      for(i=0; i<sett->N; ++i) {
	// Phase modulation 
	phase = het0*i + sett->oms*ifo[n].sig.shft[i];
#ifdef NOSINCOS
	cp = cos(phase);
	sp = sin(phase);
#else
	sincos(phase, &sp, &cp);
#endif

	exph = cp - I*sp;

	// Matched filter 
	ifo[n].sig.xDatma[i] = ifo[n].sig.xDat[i]*ifo[n].sig.aa[i]*exph;
	ifo[n].sig.xDatmb[i] = ifo[n].sig.xDat[i]*ifo[n].sig.bb[i]*exph;
      }

      /* Resampling using spline interpolation:
       * This will double the sampling rate 
       */ 
#pragma omp for schedule(static,CHUNK)  
      for(i=0; i < sett->N; ++i) {
	fftw_arr->xa[i] = ifo[n].sig.xDatma[i];
	fftw_arr->xb[i] = ifo[n].sig.xDatmb[i];
      }
 
      // Zero-padding (filling with 0s up to sett->nfft, 
      // the nearest power of 2)
#pragma omp for schedule(static,CHUNK)
      for (i=sett->N; i<sett->nfft; ++i) {
	fftw_arr->xa[i] = 0.;
	fftw_arr->xb[i] = 0.;
      }
      
    } //omp parallel

    fftw_execute_dft(plans->pl_int,fftw_arr->xa,fftw_arr->xa);  //forward fft (len nfft)
    fftw_execute_dft(plans->pl_int,fftw_arr->xb,fftw_arr->xb);  //forward fft (len nfft)

    // move frequencies from second half of spectrum; 
    // and zero frequencies higher than nyquist
    // loop length: nfft - nyqst = nfft - nfft/2 - 1 = nfft/2 - 1

    for(i=nyqst + sett->Ninterp - sett->nfft, j=nyqst; i<sett->Ninterp; ++i, ++j) {
      fftw_arr->xa[i] = fftw_arr->xa[j];
      fftw_arr->xa[j] = 0.;
    }

    for(i=nyqst + sett->Ninterp - sett->nfft, j=nyqst; i<sett->Ninterp; ++i, ++j) {
      fftw_arr->xb[i] = fftw_arr->xb[j];
      fftw_arr->xb[j] = 0.;
    }

    // Backward fft (len Ninterp = nfft*interpftpad)
    fftw_execute_dft(plans->pl_inv,fftw_arr->xa,fftw_arr->xa);
    fftw_execute_dft(plans->pl_inv,fftw_arr->xb,fftw_arr->xb);

    ft = (double)sett->interpftpad / sett->Ninterp; //scale FFT
    for (i=0; i < sett->Ninterp; ++i) {
      fftw_arr->xa[i] *= ft;
      fftw_arr->xb[i] *= ft;
    }

    //  struct timeval tstart = get_current_time(), tend;

    // Spline interpolation to xDatma, xDatmb arrays
    splintpad(fftw_arr->xa, ifo[n].sig.shftf, sett->N, 
	      sett->interpftpad, ifo[n].sig.xDatma);   
    splintpad(fftw_arr->xb, ifo[n].sig.shftf, sett->N, 
	      sett->interpftpad, ifo[n].sig.xDatmb);

  } // end of detector loop 

  // square sums of modulation factors 
  double aa = 0., bb = 0.; 

  for(n=0; n<sett->nifo; ++n) {

    double aatemp = 0., bbtemp = 0.;
 
    for(i=0; i<sett->N; ++i) {
      aatemp += sqr(ifo[n].sig.aa[i]);
      bbtemp += sqr(ifo[n].sig.bb[i]);
    }

    for(i=0; i<sett->N; ++i) {
      ifo[n].sig.xDatma[i] /= ifo[n].sig.sig2;
      ifo[n].sig.xDatmb[i] /= ifo[n].sig.sig2;
    }

    aa += aatemp/ifo[n].sig.sig2; 
    bb += bbtemp/ifo[n].sig.sig2;   
  }

#ifdef YEPPP
#define VLEN 1024
  int bnd = (sett->N/VLEN)*VLEN;
#endif

  // Check if the signal is added to the data or the range file is given:  
  // if not, proceed with the wide range of spindowns 
  // if yes, use smin = s_range->sst, smax = s_range->spndr[1]  
  if(!strcmp(opts->addsig, "") && !strcmp(opts->range, "")) {
    // Spindown range defined using Smin and Smax (settings.c)  
    smin = trunc((sett->Smin - nn*sett->M[9] - mm*sett->M[13])/sett->M[5]);
    smax = trunc(-(nn*sett->M[9] + mm*sett->M[13] + sett->Smax)/sett->M[5]);
  } 
  
  if(opts->s0_flag) smin = smax;
  // if spindown parameter is taken into account, smin != smax
  
  printf ("\n>>%d\t%d\t%d\t[%d..%d]\n", *FNum, mm, nn, smin, smax);

  static fftw_complex *fxa, *fxb;
  static double *F;
#pragma omp threadprivate(fxa,fxb, F)
#pragma omp threadprivate(F)

  //private loop counter: ss
  //private (declared inside): ii,Fc,het1,k,veto_status,a,v,_p,_c,_s,status
  //shared default: nn,mm,sett,_tmp1,ifo,het0,bnd,plans,opts,aa,bb,
  //                fftw_arr (zostawiamy i robimy nowe), FNum (atomic!)
  //we use shared plans and  fftw_execute with 'new-array' interface
#pragma omp parallel default(shared)				\
  private(i, j, n, sgnl0, exph, phase, cp, sp, tstart, tend)	\
  firstprivate(sgnlt)						\
  reduction(+ : spindown_timer, spindown_counter)

  {
#ifdef YEPPP
    Yep64f _p[VLEN], _s[VLEN], _c[VLEN];
    enum YepStatus status;
#endif
#ifdef SLEEF
    double _p[VECTLENDP], _c[VECTLENDP];
    vdouble2 v;
    vdouble a;
#endif
    
    if (!fxa) fxa = (fftw_complex *)fftw_malloc(fftw_arr->arr_len*sizeof(fftw_complex));
    if (!fxb) fxb = (fftw_complex *)fftw_malloc(fftw_arr->arr_len*sizeof(fftw_complex));
    if (!F) F = (double *)calloc(2*sett->nfft, sizeof(double));
  
    /* Spindown loop  */

#pragma omp for schedule(static,4)
    for(ss=smin; ss<=smax; ++ss) {

#if TIMERS>2
      tstart = get_current_time(CLOCK_PROCESS_CPUTIME_ID);
#endif 

      // Spindown parameter
      sgnlt[1] = ss*sett->M[5] + nn*sett->M[9] + mm*sett->M[13];

      int ii;
      double Fc, het1;
      
#ifdef VERBOSE
      //print a 'dot' every new spindown
      printf ("."); fflush (stdout);
#endif 
      
      het1 = fmod(ss*sett->M[4], sett->M[0]);
      if(het1<0) het1 += sett->M[0];

      sgnl0 = het0 + het1;

      // phase modulation before fft

#if defined(SLEEF)
      // use simd sincos from the SLEEF library;
      // VECTLENDP is a simd vector length defined in the SLEEF library
      // and it depends on selected instruction set e.g. -DENABLE_AVX
      for(i=0; i<sett->N; i+=VECTLENDP) {
	for(j=0; j<VECTLENDP; j++)
	  _p[j] =  het1*(i+j) + sgnlt[1]*_tmp1[0][i+j];
	
	a = vloadu(_p);
	v = xsincos(a);
	vstoreu(_p, v.x); // reuse _p for sin
	vstoreu(_c, v.y);
	
	for(j=0; j<VECTLENDP; ++j){
	  exph = _c[j] - I*_p[j];
	  fxa[i+j] = ifo[0].sig.xDatma[i+j]*exph; //ifo[0].sig.sig2;
	  fxb[i+j] = ifo[0].sig.xDatmb[i+j]*exph; //ifo[0].sig.sig2;
	}
      } 
#elif defined(YEPPP)
      // use yeppp! library;
      // VLEN is length of vector to be processed
      // for caches L1/L2 64/256kb optimal value is ~2048
      for (j=0; j<bnd; j+=VLEN) {
	//double *_tmp2 = &_tmp1[0][j];
	for (i=0; i<VLEN; ++i)
	  //_p[i] =  het1*(i+j) + sgnlt[1]*_tmp2[i];
       	  _p[i] =  het1*(i+j) + sgnlt[1]*_tmp1[0][i+j];
	
	status = yepMath_Sin_V64f_V64f(_p, _s, VLEN);
	assert(status == YepStatusOk);
	status = yepMath_Cos_V64f_V64f(_p, _c, VLEN);
	assert(status == YepStatusOk);

	for (i=0; i<VLEN; ++i) {
	  //	  exph = _c[i] - I*_s[i];
	  fxa[i+j] = ifo[0].sig.xDatma[i+j]*_c[i]-I*ifo[0].sig.xDatma[i+j]*_s[i];
	  fxb[i+j] = ifo[0].sig.xDatmb[i+j]*_c[i]-I*ifo[0].sig.xDatmb[i+j]*_s[i];
	}
      }
      // remaining part is shorter than VLEN - no need to vectorize
      for (i=0; i<sett->N-bnd; ++i){
	j = bnd + i;
	_p[i] =  het1*j + sgnlt[1]*_tmp1[0][j];
      }

      status = yepMath_Sin_V64f_V64f(_p, _s, sett->N-bnd);
      assert(status == YepStatusOk);
      status = yepMath_Cos_V64f_V64f(_p, _c, sett->N-bnd);
      assert(status == YepStatusOk);

      for (i=0; i<sett->N-bnd; ++i) {
	j = bnd + i;
	//exph = _c[i] - I*_s[i];
	//fxa[j] = ifo[0].sig.xDatma[j]*exph;
	//fxb[j] = ifo[0].sig.xDatmb[j]*exph;
	fxa[j] = ifo[0].sig.xDatma[j]*_c[i]-I*ifo[0].sig.xDatma[j]*_s[i];
	fxb[j] = ifo[0].sig.xDatmb[j]*_c[i]-I*ifo[0].sig.xDatmb[j]*_s[i];
      }
#elif defined(GNUSINCOS)
      for(i=sett->N-1; i!=-1; --i) {
        phase = het1*i + sgnlt[1]*_tmp1[0][i];
	sincos(phase, &sp, &cp);
	exph = cp - I*sp;
        fxa[i] = ifo[0].sig.xDatma[i]*exph; //ifo[0].sig.sig2;
        fxb[i] = ifo[0].sig.xDatmb[i]*exph; //ifo[0].sig.sig2;
      }
#else
      for(i=sett->N-1; i!=-1; --i) {
        phase = het1*i + sgnlt[1]*_tmp1[0][i];
	cp = cos(phase);
      	sp = sin(phase);
	exph = cp - I*sp;
        fxa[i] = ifo[0].sig.xDatma[i]*exph; //ifo[0].sig.sig2;
        fxb[i] = ifo[0].sig.xDatmb[i]*exph; //ifo[0].sig.sig2;
      }
#endif

      for(n=1; n<sett->nifo; ++n) {
#if defined(SLEEF)
	// use simd sincos from the SLEEF library;
	// VECTLENDP is a simd vector length defined in the SLEEF library
	// and it depends on selected instruction set e.g. -DENABLE_AVX
	for (i=0; i<sett->N; i+=VECTLENDP) {
	  for(j=0; j<VECTLENDP; j++)
	    _p[j] =  het1*(i+j) + sgnlt[1]*_tmp1[n][i+j];
	  
	  a = vloadu(_p);
	  v = xsincos(a);
	  vstoreu(_p, v.x); // reuse _p for sin
	  vstoreu(_c, v.y);
	
	  for(j=0; j<VECTLENDP; ++j){
	    exph = _c[j] - I*_p[j];
	    fxa[i+j] = ifo[n].sig.xDatma[i+j]*exph;
	    fxb[i+j] = ifo[n].sig.xDatmb[i+j]*exph;
	  }
	} 
#elif defined(YEPPP)
	// use yeppp! library;
	// VLEN is length of vector to be processed
	// for caches L1/L2 64/256kb optimal value is ~2048
	for (j=0; j<bnd; j+=VLEN) {
	  //double *_tmp2 = &_tmp1[n][j];
	  for (i=0; i<VLEN; ++i)
	    //  _p[i] =  het1*(i+j) + sgnlt[1]*_tmp2[i];
	    _p[i] =  het1*(j+i) + sgnlt[1]*_tmp1[n][j+i];
	
	  status = yepMath_Sin_V64f_V64f(_p, _s, VLEN);
	  assert(status == YepStatusOk);
	  status = yepMath_Cos_V64f_V64f(_p, _c, VLEN);
	  assert(status == YepStatusOk);
	
	  for (i=0; i<VLEN; ++i) {
	    //exph = _c[i] - I*_s[i];
	    //fxa[j+i] += ifo[n].sig.xDatma[j+i]*exph;
	    //fxb[j+i] += ifo[n].sig.xDatmb[j+i]*exph;
	    fxa[i+j] += ifo[n].sig.xDatma[i+j]*_c[i]-I*ifo[n].sig.xDatma[i+j]*_s[i];
	    fxb[i+j] += ifo[n].sig.xDatmb[i+j]*_c[i]-I*ifo[n].sig.xDatmb[i+j]*_s[i];
	  }
	}
	// remaining part is shorter than VLEN - no need to vectorize
	for (i=0; i<sett->N-bnd; ++i){
	  j = bnd + i;
	  _p[i] =  het1*j + sgnlt[1]*_tmp1[n][j];
	}

	status = yepMath_Sin_V64f_V64f(_p, _s, sett->N-bnd);
	assert(status == YepStatusOk);
	status = yepMath_Cos_V64f_V64f(_p, _c, sett->N-bnd);
	assert(status == YepStatusOk);

	for (i=0; i<sett->N-bnd; ++i) {
	  j = bnd + i;
	  //exph = _c[i] - I*_s[i];
	  //fxa[j] += ifo[n].sig.xDatma[j]*exph;
	  //fxb[j] += ifo[n].sig.xDatmb[j]*exph;
	  fxa[j] += ifo[n].sig.xDatma[j]*_c[i]-I*ifo[n].sig.xDatma[j]*_s[i];
	  fxb[j] += ifo[n].sig.xDatmb[j]*_c[i]-I*ifo[n].sig.xDatmb[j]*_s[i];
	}

#elif defined(GNUSINCOS)
	for(i=sett->N-1; i!=-1; --i) {
	  phase = het1*i + sgnlt[1]*_tmp1[n][i];
	  sincos(phase, &sp, &cp);
	  exph = cp - I*sp;
	  fxa[i] += ifo[n].sig.xDatma[i]*exph;
	  fxb[i] += ifo[n].sig.xDatmb[i]*exph;
	}
#else
	for(i=sett->N-1; i!=-1; --i) {
	  phase = het1*i + sgnlt[1]*_tmp1[n][i];
	  cp = cos(phase);
	  sp = sin(phase);
	  exph = cp - I*sp;
	  fxa[i] += ifo[n].sig.xDatma[i]*exph;
	  fxb[i] += ifo[n].sig.xDatmb[i]*exph;
	}
#endif

      } 

      // Zero-padding 
      for(i = sett->fftpad*sett->nfft-1; i != sett->N-1; --i)
	fxa[i] = fxb[i] = 0.; 

      fftw_execute_dft(plans->plan, fxa, fxa);
      fftw_execute_dft(plans->plan, fxb, fxb);
      
      // Computing F-statistic 
      for (i=sett->nmin; i<sett->nmax; i++) {
	F[i] = (sqr(creal(fxa[i])) + sqr(cimag(fxa[i])))/aa +
	       (sqr(creal(fxb[i])) + sqr(cimag(fxb[i])))/bb;
      }

      //      for (i=sett->nmin; i<sett->nmax; i++) 
      //	F[i] += (sqr(creal(fxb[i])) + sqr(cimag(fxb[i])))/bb;

#pragma omp atomic
      (*FNum)++;

      
#if 0
      FILE *f1 = fopen("fraw-1.dat", "w");
      for(i=sett->nmin; i<sett->nmax; i++)
	fprintf(f1, "%d   %lf   %lf\n", i, F[i], 2.*M_PI*i/((double) sett->fftpad*sett->nfft) + sgnl0);
      fclose(f1);
#endif 

#ifndef NORMTOMAX
      //#define NAVFSTAT 4096
      // Normalize F-statistics 
      if(!(opts->white_flag))  // if the noise is not white noise
        FStat(F + sett->nmin, sett->nmax - sett->nmin, NAVFSTAT, 0);

      // f1 = fopen("fnorm-4096-1.dat", "w");
      //for(i=sett->nmin; i<sett->nmax; i++)
      //fprintf(f1, "%d   %lf   %lf\n", i, F[i], 2.*M_PI*i/((double) sett->fftpad*sett->nfft) + sgnl0);
      //fclose(f1);
      //      exit(EXIT_SUCCESS);

      for(i=sett->nmin; i<sett->nmax; i++) {
        if ((Fc = F[i]) > opts->trl) { // if F-stat exceeds trl (critical value)
          // Find local maximum for neighboring signals 
          ii = i;

	  while (++i < sett->nmax && F[i] > opts->trl) {
	    if(F[i] >= Fc) {
	      ii = i;
	      Fc = F[i];
	    } // if F[i] 
	  } // while i 
	  // Candidate signal frequency
	  sgnlt[0] = 2.*M_PI*ii/((FLOAT_TYPE)sett->fftpad*sett->nfft) + sgnl0;
	  // Signal-to-noise ratio
	  sgnlt[4] = sqrt(2.*(Fc-sett->nd));
	  
	  // Checking if signal is within a known instrumental line 
	  int k, veto_status = 0; 
	  for(k=0; k<sett->numlines_band; k++)
	    if(sgnlt[0]>=sett->lines[k][0] && sgnlt[0]<=sett->lines[k][1]) { 
	      veto_status=1; 
	      break; 
	    }   
	  
	  int _sgnlc;
	  if(!veto_status) {

	    /* 
#pragma omp critical
	    {
	      (*sgnlc)++; // increase found number
	      // Add new parameters to output array 
	      for (j=0; j<NPAR; ++j)    // save new parameters
		sgnlv[NPAR*(*sgnlc-1)+j] = (FLOAT_TYPE)sgnlt[j];
	    }
	    */

#pragma omp atomic capture
	    {
	      (*sgnlc)++; // increase found number
	      _sgnlc = *sgnlc;
	    }
	    // Add new parameters to output array 
	    for (j=0; j<NPAR; ++j)    // save new parameters
	      sgnlv[NPAR*(_sgnlc-1)+j] = (FLOAT_TYPE)sgnlt[j];
	    
#ifdef VERBOSE
	    printf ("\nSignal %d: %d %d %d %d %d snr=%.2f\n", 
		    *sgnlc, pm, mm, nn, ss, ii, sgnlt[4]);
#endif
	  }
	} // if Fc > trl 
      } // for i
      
#else // new version
      imax = -1;
      // find local maxima first
      //printf("nmin=%d   nmax=%d    nfft=%d   nblocks=%d\n", sett->nmin, sett->nmax, nfft, nfft/blksize);
      for(iblk=0; iblk < nfft/blksize; ++iblk) {
	blkavg = 0.;
	blkstart = sett->nmin + iblk*blksize; // block start index in F 
	// in case the last block is shorter than blksize, include its elements in the previous block
	if(iblk==(nfft/blksize-1)) {blksize = sett->nmax - blkstart;}
	imax0 = imax+1; // index of first maximum in current block
	//printf("\niblk=%d   blkstart=%d   blksize=%d    imax0=%d\n", iblk, blkstart, blksize, imax0);
	for(i=1; i <= blksize; ++i) { // include first element of the next block
	  ii = blkstart + i;
	  if(ii < sett->nmax) 
	    {ihi=ii+1;} 
	  else 
	    {ihi = sett->nmax; /*printf("ihi=%d  ii=%d\n", ihi, ii);*/};
	  if(F[ii] > F[ii-1] && F[ii] > F[ihi]) {
	    blkavg += F[ii];
	    Fmax[++imax] = ii;
	    ++i; // next element can't be maximum - skip it
	  }
	} // i
	// now imax points to the last element of Fmax
	// normalize in blocks 
	blkavg /= (double)(imax - imax0 + 1);
	for(i=imax0; i <= imax; ++i)
	  F[Fmax[i]] /= blkavg;

      } // iblk

      //f1 = fopen("fmax.dat", "w");
      //for(i=1; i < imax; i++)
      //fprintf(f1, "%d   %lf \n", Fmax[i], F[Fmax[i]]);
      //fclose(f1);
      //exit(EXIT_SUCCESS);

      // apply threshold limit
      for(i=0; i <= imax; ++i){
	//if(F[Fmax[i]] > opts->trl) {
	if(F[Fmax[i]] > threshold) {
	  sgnlt[0] = 2.*M_PI*i/((FLOAT_TYPE)sett->fftpad*sett->nfft) + sgnl0;
	  // Signal-to-noise ratio
	  sgnlt[4] = sqrt(2.*(F[Fmax[i]] - sett->nd));

	  // Checking if signal is within a known instrumental line 
	  int k, veto_status=0; 
	  for(k=0; k<sett->numlines_band; k++)
	    if(sgnlt[0]>=sett->lines[k][0] && sgnlt[0]<=sett->lines[k][1]) { 
	      veto_status=1; 
	      break; 
	    }   
	  
	  if(!veto_status) { 
	    
	    (*sgnlc)++; // increase number of found candidates
	    // Add new parameters to buffer array 
	    for (j=0; j<NPAR; ++j)
	      sgnlv[NPAR*(*sgnlc-1)+j] = (FLOAT_TYPE)sgnlt[j];
#ifdef VERBOSE
	    printf ("\nSignal %d: %d %d %d %d %d snr=%.2f\n", 
		    *sgnlc, pm, mm, nn, ss, Fmax[i], sgnlt[4]);
#endif 
	  }
	}
      } // i
#endif // old/new version
      
#if TIMERS>2
      tend = get_current_time(CLOCK_PROCESS_CPUTIME_ID);
      spindown_timer += get_time_difference(tstart, tend);
      spindown_counter++;
#endif
      
    } // for ss 
  } // omp parallel
  
#ifndef VERBOSE 
  printf("Number of signals found: %d\n", *sgnlc); 
#endif 

  //  tend = get_current_time(CLOCK_REALTIME);
  //time_elapsed = get_time_difference(tstart, tend);
  //printf("Parallel part: %e  ( per thread %e ) s\n", time_elapsed, time_elapsed/omp_get_max_threads());


#if TIMERS>2
  printf("\nTotal spindown loop time: %e s, mean spindown cpu-time: %e s (%d runs)\n",
	 spindown_timer, spindown_timer/spindown_counter, spindown_counter);
#endif

  return 0;
  
} // jobcore
Exemple #10
0
/*! \brief Finds a tcpconn & sends on it */
int tcp_send(struct socket_info* send_sock, int type, char* buf, unsigned len,
			union sockaddr_union* to, int id)
{
	struct tcp_connection *c;
	struct tcp_connection *tmp;
	struct ip_addr ip;
	int port;
	int fd;
	long response[2];
	int n;
	struct timeval get,rcv,snd;
	
	port=0;

	reset_tcp_vars(tcpthreshold);
	start_expire_timer(get,tcpthreshold);

	if (to){
		su2ip_addr(&ip, to);
		port=su_getport(to);
		c=tcpconn_get(id, &ip, port, tcp_con_lifetime); 
	}else if (id){
		c=tcpconn_get(id, 0, 0, tcp_con_lifetime);
	}else{
		LM_CRIT("tcp_send called with null id & to\n");
		get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
		return -1;
	}
	
	if (id){
		if (c==0) {
			if (to){
				/* try again w/o id */
				c=tcpconn_get(0, &ip, port, tcp_con_lifetime);
				goto no_id;
			}else{
				LM_ERR("id %d not found, dropping\n", id);
				get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
				return -1;
			}
		}else goto get_fd;
	}
no_id:
		if (c==0){
			LM_DBG("no open tcp connection found, opening new one\n");
			/* create tcp connection */
			if ((c=tcpconn_connect(send_sock, to, type))==0){
				LM_ERR("connect failed\n");
				get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
				return -1;
			}
			c->refcnt++; /* safe to do it w/o locking, it's not yet
							available to the rest of the world */
			fd=c->s;
			
			/* send the new tcpconn to "tcp main" */
			response[0]=(long)c;
			response[1]=CONN_NEW;
			n=send_fd(unix_tcp_sock, response, sizeof(response), c->s);
			get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
			if (n<=0){
				LM_ERR("failed send_fd: %s (%d)\n",	strerror(errno), errno);
				n=-1;
				goto end;
			}	
			goto send_it;
		}
get_fd:
		get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
			/* todo: see if this is not the same process holding
			 *  c  and if so send directly on c->fd */
			LM_DBG("tcp connection found (%p), acquiring fd\n", c);
			/* get the fd */
			response[0]=(long)c;
			response[1]=CONN_GET_FD;
			start_expire_timer(rcv,tcpthreshold);
			n=send_all(unix_tcp_sock, response, sizeof(response));
			if (n<=0){
				LM_ERR("failed to get fd(write):%s (%d)\n",	
						strerror(errno), errno);
				n=-1;
				get_time_difference(rcv,tcpthreshold,tcp_timeout_receive_fd);
				goto release_c;
			}
			LM_DBG("c= %p, n=%d\n", c, n);
			tmp=c;
			n=receive_fd(unix_tcp_sock, &c, sizeof(c), &fd, MSG_WAITALL);
			get_time_difference(rcv,tcpthreshold,tcp_timeout_receive_fd);
			if (n<=0){
				LM_ERR("failed to get fd(receive_fd):"
							" %s (%d)\n", strerror(errno), errno);
				n=-1;
				goto release_c;
			}
			if (c!=tmp){
				LM_CRIT("got different connection:"
						"  %p (id= %d, refcnt=%d state=%d != "
						"  %p (id= %d, refcnt=%d state=%d (n=%d)\n",
						  c,   c->id,   c->refcnt,   c->state,
						  tmp, tmp->id, tmp->refcnt, tmp->state, n
				   );
				n=-1; /* fail */
				goto end;
			}
			LM_DBG("after receive_fd: c= %p n=%d fd=%d\n",c, n, fd);
		
	
	
send_it:
	LM_DBG("sending...\n");
	lock_get(&c->write_lock);
#ifdef USE_TLS
	if (c->type==PROTO_TLS)
		n=tls_blocking_write(c, fd, buf, len);
	else
#endif
		/* n=tcp_blocking_write(c, fd, buf, len); */
		start_expire_timer(snd,tcpthreshold);
		n=tsend_stream(fd, buf, len, tcp_send_timeout*1000); 
		get_time_difference(snd,tcpthreshold,tcp_timeout_send);
	
		stop_expire_timer(get,tcpthreshold,0,buf,(int)len,1);
	lock_release(&c->write_lock);
	LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd);
	LM_DBG("buf=\n%.*s\n", (int)len, buf);
	if (n<0){
		LM_ERR("failed to send\n");
		/* error on the connection , mark it as bad and set 0 timeout */
		c->state=S_CONN_BAD;
		c->timeout=0;
		/* tell "main" it should drop this (optional it will t/o anyway?)*/
		response[0]=(long)c;
		response[1]=CONN_ERROR;
		n=send_all(unix_tcp_sock, response, sizeof(response));
		/* CONN_ERROR will auto-dec refcnt => we must not call tcpconn_put !!*/
		if (n<=0){
			LM_ERR("return failed (write):%s (%d)\n",
					strerror(errno), errno);
		}
		close(fd);
		return -1; /* error return, no tcpconn_put */
	}
end:
	close(fd);
release_c:
	tcpconn_put(c); /* release c (lock; dec refcnt; unlock) */
	return n;
}
Exemple #11
0
/*! \brief Finds a tcpconn & sends on it */
static int proto_tcp_send(struct socket_info* send_sock,
											char* buf, unsigned int len,
											union sockaddr_union* to, int id)
{
	struct tcp_connection *c;
	struct ip_addr ip;
	int port;
	struct timeval get,snd;
	int fd, n;

	port=0;

	reset_tcp_vars(tcpthreshold);
	start_expire_timer(get,tcpthreshold);

	if (to){
		su2ip_addr(&ip, to);
		port=su_getport(to);
		n = tcp_conn_get(id, &ip, port, &c, &fd);
	}else if (id){
		n = tcp_conn_get(id, 0, 0, &c, &fd);
	}else{
		LM_CRIT("tcp_send called with null id & to\n");
		get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
		return -1;
	}

	if (n<0) {
		/* error during conn get, return with error too */
		LM_ERR("failed to acquire connection\n");
		get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
		return -1;
	}

	/* was connection found ?? */
	if (c==0) {
		if (tcp_no_new_conn) {
			return -1;
		}
		LM_DBG("no open tcp connection found, opening new one, async = %d\n",tcp_async);
		/* create tcp connection */
		if (tcp_async) {
			n = tcpconn_async_connect(send_sock, to, buf, len, &c, &fd);
			if ( n<0 ) {
				LM_ERR("async TCP connect failed\n");
				get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
				return -1;
			}
			/* connect succeeded, we have a connection */
			if (n==0) {
				/* connect is still in progress, break the sending
				 * flow now (the actual write will be done when 
				 * connect will be completed */
				LM_DBG("Successfully started async connection \n");
				tcp_conn_release(c, 0);
				return len;
			}

			LM_DBG("First connect attempt succeeded in less than %d ms, "
				"proceed to writing \n",tcp_async_local_connect_timeout);
			/* our first connect attempt succeeded - go ahead as normal */
		} else if ((c=tcp_sync_connect(send_sock, to, &fd))==0) {
			LM_ERR("connect failed\n");
			get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
			return -1;
		}
	
		goto send_it;
	}
	get_time_difference(get,tcpthreshold,tcp_timeout_con_get);

	/* now we have a connection, let's see what we can do with it */
	/* BE CAREFUL now as we need to release the conn before exiting !!! */
	if (fd==-1) {
		/* connection is not writable because of its state - can we append
		 * data to it for later writting (async writting)? */
		if (c->state==S_CONN_CONNECTING) {
			/* the connection is currently in the process of getting
			 * connected - let's append our send chunk as well - just in
			 * case we ever manage to get through */
			LM_DBG("We have acquired a TCP connection which is still "
				"pending to connect - delaying write \n");
			n = add_write_chunk(c,buf,len,1);
			if (n < 0) {
				LM_ERR("Failed to add another write chunk to %p\n",c);
				/* we failed due to internal errors - put the
				 * connection back */
				tcp_conn_release(c, 0);
				return -1;
			}

			/* we successfully added our write chunk - success */
			tcp_conn_release(c, 0);
			return len;
		} else {
			/* return error, nothing to do about it */
			tcp_conn_release(c, 0);
			return -1;
		}
	}


send_it:
	LM_DBG("sending via fd %d...\n",fd);

	start_expire_timer(snd,tcpthreshold);

	n = _tcp_write_on_socket(c, fd, buf, len);

	get_time_difference(snd,tcpthreshold,tcp_timeout_send);
	stop_expire_timer(get,tcpthreshold,"tcp ops",buf,(int)len,1);

	tcp_conn_set_lifetime( c, tcp_con_lifetime);

	LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd);
	/* LM_DBG("buf=\n%.*s\n", (int)len, buf); */
	if (n<0){
		LM_ERR("failed to send\n");
		c->state=S_CONN_BAD;
		if (c->proc_id != process_no)
			close(fd);
		tcp_conn_release(c, 0);
		return -1;
	}

	/* only close the FD if not already in the context of our process
	either we just connected, or main sent us the FD */
	if (c->proc_id != process_no)
		close(fd);

	tcp_conn_release(c, (n<len)?1:0/*pending data in async mode?*/ );
	return n;
}
Exemple #12
0
/*! \brief Finds a tcpconn & sends on it */
static int proto_wss_send(struct socket_info* send_sock,
											char* buf, unsigned int len,
											union sockaddr_union* to, int id)
{
	struct tcp_connection *c;
	struct timeval get;
	struct ip_addr ip;
	int port = 0;
	int fd, n;
	struct ws_data* d;

	reset_tcp_vars(tcpthreshold);
	start_expire_timer(get,tcpthreshold);

	if (to){
		su2ip_addr(&ip, to);
		port=su_getport(to);
		n = tcp_conn_get(id, &ip, port, PROTO_WSS, &c, &fd);
	}else if (id){
		n = tcp_conn_get(id, 0, 0, PROTO_NONE, &c, &fd);
	}else{
		LM_CRIT("prot_tls_send called with null id & to\n");
		get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
		return -1;
	}

	if (n<0) {
		/* error during conn get, return with error too */
		LM_ERR("failed to acquire connection\n");
		get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
		return -1;
	}

	/* was connection found ?? */
	if (c==0) {
		if (tcp_no_new_conn) {
			return -1;
		}
		if (!to) {
			LM_ERR("Unknown destination - cannot open new tcp connection\n");
			return -1;
		}
		LM_DBG("no open tcp connection found, opening new one\n");
		/* create tcp connection */
		if ((c=ws_connect(send_sock, to, &fd))==0) {
			LM_ERR("connect failed\n");
			return -1;
		}
		goto send_it;
	}
	get_time_difference(get, tcpthreshold, tcp_timeout_con_get);

	/* now we have a connection, let's what we can do with it */
	/* BE CAREFUL now as we need to release the conn before exiting !!! */
	if (fd==-1) {
		/* connection is not writable because of its state */
		/* return error, nothing to do about it */
		tcp_conn_release(c, 0);
		return -1;
	}

send_it:
	LM_DBG("sending via fd %d...\n",fd);

	n = ws_req_write(c, fd, buf, len);
	stop_expire_timer(get, tcpthreshold, "WSS ops",buf,(int)len,1);
	tcp_conn_set_lifetime( c, tcp_con_lifetime);

	/* only here we will have all tracing data TLS + WS */
	d = c->proto_data;

	if ( (c->flags&F_CONN_ACCEPTED)==0 && d && d->dest && d->tprot ) {
		if ( d->message ) {
			send_trace_message( d->message, t_dst);
			d->message = NULL;
		}

		/* don't allow future traces for this cnection */
		d->tprot = 0;
		d->dest  = 0;
	}


	LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd);
	if (n<0){
		LM_ERR("failed to send\n");
		c->state=S_CONN_BAD;
		if (c->proc_id != process_no)
			close(fd);
		tcp_conn_release(c, 0);
		return -1;
	}

	/* only close the FD if not already in the context of our process
	either we just connected, or main sent us the FD */
	if (c->proc_id != process_no)
		close(fd);

	/* mark the ID of the used connection (tracing purposes) */
	last_outgoing_tcp_id = c->id;

	tcp_conn_release(c, 0);
	return n;
}