<commit_before>#include <sys/time.h>
#include <sys/types.h>
#include <omp.h>
#include <math.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

// Solver
#include "include/defines.h"
#include "include/stencils.h"
#include "include/file_io.h"
#include "include/utils.h"

const double PI = 3.14159265;

uint N = 0;
uint OutputStep = 0;

double dx       =  0.0;
double idx      =  0.0;
double dt       =  0.1;
double h        = 16.0;
double omega    =  1.0;
double maxv     =  0.0;
double CFL      =  2.0;
double cellSize =  1.0;

typedef double Triple[3];

void GlobalToLocal(Triple coord, double f) {
  if(f==1.0)
    return;
  for(int d = 0; d < 3; d++) {
    coord[d] *= f;
  }
}

void LocalToGlobal(Triple coord, double f) {
  if(f==1.0)
    return;
  for(int d = 0; d < 3; d++) {
    coord[d] *= f;
  }
}

template <typename T>
void Initialize(T * gridA, T * gridB,
    const uint &X, const uint &Y, const uint &Z) {

  for(uint k = BWP; k < Z - BWP; k++) {
    for(uint j = BWP; j < Y - BWP; j++) {
      for(uint i = BWP; i < X - BWP; i++ ) {
        gridA[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i] = 0.0;
        gridB[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i] = 0.0;
      }
    }
  }

}

void InitializeVelocity(Triple * field,
    const uint &X, const uint &Y, const uint &Z) {

  for(uint k = 0; k < Z + BW; k++) {
    for(uint j = 0; j < Y + BW; j++) {
      for(uint i = 0; i < X + BW; i++) {
        field[k*(Y+BW)*(X+BW)+j*(X+BW)+i][0] = 0.0;
        field[k*(Y+BW)*(X+BW)+j*(X+BW)+i][1] = 0.0;
        field[k*(Y+BW)*(X+BW)+j*(X+BW)+i][2] = 0.0;
      }
    }
  }

  for(uint k = BWP; k < Z + BWP; k++) {
    for(uint j = BWP; j < Y + BWP; j++) {
      for(uint i = BWP; i < X + BWP; i++ ) {
        field[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i][0] = -omega * (double)(j-(Y+1.0)/2.0);
        field[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i][1] =  omega * (double)(i-(X+1.0)/2.0);
        field[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i][2] =  0.0;

        maxv = std::max((double)abs(field[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i][0]),maxv);
        maxv = std::max((double)abs(field[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i][1]),maxv);
      }
    }
  }

}

template <typename T>
void WriteHeatFocus(T * gridA,
    const uint &X, const uint &Y, const uint &Z) {

  uint Xc, Yc, Zc;

  Xc = 2.0/5.0*(X);
  Yc = 2.0/5.5*(Y);
  Zc = 1.0/2.0*(Z);

  for(uint k = 0; k < Z + BW; k++) {
    for(uint j = 0; j < Y + BW; j++) {
      for(uint i = 0; i < Z + BW; i++) {

        double d2 = pow((Xc - (double)(i)),2) + pow((Yc - (double)(j)),2) + pow((Zc - (double)(k)),2);
        double rr = pow(X/6.0,2);

        if(d2 < rr)
          gridA[k*(Y+BW)*(X+BW)+j*(X+BW)+i] = 1.0 - d2/rr;
      }
    }
  }

}

void Interpolate(Triple prevDelta, Triple prevVeloc, Triple * field,
    const uint &X, const uint &Y, const uint &Z) {

  uint pi,pj,pk,ni,nj,nk;

  GlobalToLocal(prevDelta,idx);

  pi = floor(prevDelta[0]); ni = pi+1;
  pj = floor(prevDelta[1]); nj = pj+1;
  pk = floor(prevDelta[2]); nk = pk+1;

  PrecisionType Nx, Ny, Nz;

  Nx = 1-(prevDelta[0] - floor(prevDelta[0]));
  Ny = 1-(prevDelta[1] - floor(prevDelta[1]));
  Nz = 1-(prevDelta[2] - floor(prevDelta[2]));

  for(int d = 0; d < 3; d++) {
    prevVeloc[d] = (
      field[pk*(Z+BW)*(Y+BW)+pj*(Y+BW)+pi][d] * (    Nx) * (    Ny) * (    Nz) +
      field[pk*(Z+BW)*(Y+BW)+pj*(Y+BW)+ni][d] * (1 - Nx) * (    Ny) * (    Nz) +
      field[pk*(Z+BW)*(Y+BW)+nj*(Y+BW)+pi][d] * (    Nx) * (1 - Ny) * (    Nz) +
      field[pk*(Z+BW)*(Y+BW)+nj*(Y+BW)+ni][d] * (1 - Nx) * (1 - Ny) * (    Nz) +
      field[nk*(Z+BW)*(Y+BW)+pj*(Y+BW)+pi][d] * (    Nx) * (    Ny) * (1 - Nz) +
      field[nk*(Z+BW)*(Y+BW)+pj*(Y+BW)+ni][d] * (1 - Nx) * (    Ny) * (1 - Nz) +
      field[nk*(Z+BW)*(Y+BW)+nj*(Y+BW)+pi][d] * (    Nx) * (1 - Ny) * (1 - Nz) +
      field[nk*(Z+BW)*(Y+BW)+nj*(Y+BW)+ni][d] * (1 - Nx) * (1 - Ny) * (1 - Nz)
    );
  }
}

template <typename T>
double Interpolate(Triple prevDelta, T * gridA,
    const uint &X, const uint &Y, const uint &Z) {

  uint pi,pj,pk,ni,nj,nk;

  pi = floor(prevDelta[0]); ni = pi+1;
  pj = floor(prevDelta[1]); nj = pj+1;
  pk = floor(prevDelta[2]); nk = pk+1;

  double Nx, Ny, Nz;

  Nx = 1-(prevDelta[0] - floor(prevDelta[0]));
  Ny = 1-(prevDelta[1] - floor(prevDelta[1]));
  Nz = 1-(prevDelta[2] - floor(prevDelta[2]));

  return (
    gridA[pk*(Z+BW)*(Y+BW)+pj*(Y+BW)+pi] * (    Nx) * (    Ny) * (    Nz) +
    gridA[pk*(Z+BW)*(Y+BW)+pj*(Y+BW)+ni] * (1 - Nx) * (    Ny) * (    Nz) +
    gridA[pk*(Z+BW)*(Y+BW)+nj*(Y+BW)+pi] * (    Nx) * (1 - Ny) * (    Nz) +
    gridA[pk*(Z+BW)*(Y+BW)+nj*(Y+BW)+ni] * (1 - Nx) * (1 - Ny) * (    Nz) +
    gridA[nk*(Z+BW)*(Y+BW)+pj*(Y+BW)+pi] * (    Nx) * (    Ny) * (1 - Nz) +
    gridA[nk*(Z+BW)*(Y+BW)+pj*(Y+BW)+ni] * (1 - Nx) * (    Ny) * (1 - Nz) +
    gridA[nk*(Z+BW)*(Y+BW)+nj*(Y+BW)+pi] * (    Nx) * (1 - Ny) * (1 - Nz) +
    gridA[nk*(Z+BW)*(Y+BW)+nj*(Y+BW)+ni] * (1 - Nx) * (1 - Ny) * (1 - Nz)
  );
}

template <typename U>
void precalculateBackAndForw(U * fieldA, U * backward, U * forward,
    const uint &X, const uint &Y, const uint &Z) {

  Triple origin;

  for(uint k = BWP + omp_get_thread_num(); k < Z + BWP; k+=omp_get_num_threads()) {
    for(uint j = BWP; j < Y + BWP; j++) {
      for(uint i = BWP; i < X + BWP; i++) {
        uint cell = k*(Z+BW)*(Y+BW)+j*(Y+BW)+i;

        origin[0] = i;
        origin[1] = j;
        origin[2] = k;

        for(int d = 0; d < 3; d++) {
          backward[cell][d] = origin[d]*h-fieldA[cell][d]*dt;
          forward[cell][d]  = origin[d]*h+fieldA[cell][d]*dt;
        }
      }
    }
  }

}

template <typename T, typename U>
void advection(T * gridA, T * gridB, T * gridC, U * fieldA, U * backward, U * forward,
    const uint &X, const uint &Y, const uint &Z) {

  for(uint k = BWP + omp_get_thread_num(); k < Z + BWP; k+=omp_get_num_threads()) {
    for(uint j = BWP; j < Y + BWP; j++) {
      for(uint i = BWP; i < X + BWP; i++) {
        uint cell = k*(Z+BW)*(Y+BW)+j*(Y+BW)+i;
        gridB[cell] = Interpolate(backward[cell],gridA,N,N,N);
      }
    }
  }

  #pragma omp barrier

  for(uint k = BWP + omp_get_thread_num(); k < Z + BWP; k+=omp_get_num_threads()) {
    for(uint j = BWP; j < Y + BWP; j++) {
      for(uint i = BWP; i < X + BWP; i++) {
        uint cell = k*(Z+BW)*(Y+BW)+j*(Y+BW)+i;
        gridC[cell] = 1.5 * gridA[cell] - 0.5 * Interpolate(forward[cell],gridB,N,N,N);
      }
    }
  }

  #pragma omp barrier

  for(uint k = BWP + omp_get_thread_num(); k < Z + BWP; k+=omp_get_num_threads()) {
    for(uint j = BWP; j < Y + BWP; j++) {
      for(uint i = BWP; i < X + BWP; i++) {
        uint cell = k*(Z+BW)*(Y+BW)+j*(Y+BW)+i;
        gridA[cell] = Interpolate(backward[cell],gridC,N,N,N);
      }
    }
  }
}

template <typename T>
void difussion(T * &gridA, T * &gridB,
    const uint &X, const uint &Y, const uint &Z) {

  for(uint k = BWP + omp_get_thread_num(); k < Z + BWP; k+=omp_get_num_threads()) {
    for(uint j = BWP; j < Y + BWP; j++) {
      uint cell = k*(Z+BW)*(Y+BW)+j*(Y+BW)+BWP;
      for(uint i = BWP; i < X + BWP; i++) {
        stencilCross(gridA,gridB,cell++,X,Y,Z);
      }
    }
  }
}

int main(int argc, char *argv[]) {

  N           = atoi(argv[1]);
  int steeps  = atoi(argv[2]);
  h           = atoi(argv[3]);

  NB          = atoi(argv[4]);
  NE          = N/NB;

  dx          = h/N;
  idx         = 1.0/dx;

  struct timeval start, end;

  FileIO<PrecisionType> io("grid",N);

  PrecisionType * step0 = NULL;
  PrecisionType * step1 = NULL;
  PrecisionType * step2 = NULL;

  Triple * velf0 = NULL;
  Triple * velf1 = NULL;
  Triple * velf2 = NULL;

  double duration = 0.0;

  // Temperature
  AllocateGrid(&step0,N,N,N);
  AllocateGrid(&step1,N,N,N);
  AllocateGrid(&step2,N,N,N);

  // Velocity
  AllocateGrid(&velf0,N,N,N);
  AllocateGrid(&velf1,N,N,N);
  AllocateGrid(&velf2,N,N,N);

  printf("Allocation correct\n");
  printf("Initialize\n");

  Initialize(step0,step1,N,N,N);
  WriteHeatFocus(step0,N,N,N);
  InitializeVelocity(velf0,N,N,N);

  dt = 0.25 * CFL*h/maxv;

  io.WriteGidMesh(step0,N,N,N);

  #pragma omp parallel
  #pragma omp single
  {
    printf("-------------------\n");
    printf("Running with OMP %d\n",omp_get_num_threads());
    printf("-------------------\n");
  }

  gettimeofday(&start, NULL);

  #pragma omp parallel
  {
    precalculateBackAndForw(velf0,velf1,velf2,N,N,N);
    for(int i = 0; i < steeps; i++) {
      advection(step0,step1,step2,velf0,velf1,velf2,N,N,N);
    }
  }

  gettimeofday(&end, NULL);

  duration = FETCHTIME

  printf("Total time:\t %d s\n",duration);
  printf("Step  time:\t %d s\n",duration\steeps);

  ReleaseGrid(&step0);
  ReleaseGrid(&step1);
  ReleaseGrid(&step2);

  ReleaseGrid(&velf0);
  ReleaseGrid(&velf1);

  printf("De-Allocation correct\n");
}
<commit_msg>Added support for blocking in the advection function<commit_after>#include <sys/time.h>
#include <sys/types.h>
#include <omp.h>
#include <math.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

// Solver
#include "include/defines.h"
#include "include/stencils.h"
#include "include/file_io.h"
#include "include/utils.h"

const double PI = 3.14159265;

uint N = 0;
uint OutputStep = 0;

double dx       =  0.0;
double idx      =  0.0;
double dt       =  0.1;
double h        = 16.0;
double omega    =  1.0;
double maxv     =  0.0;
double CFL      =  2.0;
double cellSize =  1.0;

typedef double Triple[3];

void GlobalToLocal(Triple coord, double f) {
  if(f==1.0)
    return;
  for(int d = 0; d < 3; d++) {
    coord[d] *= f;
  }
}

void LocalToGlobal(Triple coord, double f) {
  if(f==1.0)
    return;
  for(int d = 0; d < 3; d++) {
    coord[d] *= f;
  }
}

template <typename T>
void Initialize(T * gridA, T * gridB,
    const uint &X, const uint &Y, const uint &Z) {

  for(uint k = BWP; k < Z - BWP; k++) {
    for(uint j = BWP; j < Y - BWP; j++) {
      for(uint i = BWP; i < X - BWP; i++ ) {
        gridA[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i] = 0.0;
        gridB[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i] = 0.0;
      }
    }
  }

}

void InitializeVelocity(Triple * field,
    const uint &X, const uint &Y, const uint &Z) {

  for(uint k = 0; k < Z + BW; k++) {
    for(uint j = 0; j < Y + BW; j++) {
      for(uint i = 0; i < X + BW; i++) {
        field[k*(Y+BW)*(X+BW)+j*(X+BW)+i][0] = 0.0;
        field[k*(Y+BW)*(X+BW)+j*(X+BW)+i][1] = 0.0;
        field[k*(Y+BW)*(X+BW)+j*(X+BW)+i][2] = 0.0;
      }
    }
  }

  for(uint k = BWP; k < Z + BWP; k++) {
    for(uint j = BWP; j < Y + BWP; j++) {
      for(uint i = BWP; i < X + BWP; i++ ) {
        field[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i][0] = -omega * (double)(j-(Y+1.0)/2.0);
        field[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i][1] =  omega * (double)(i-(X+1.0)/2.0);
        field[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i][2] =  0.0;

        maxv = std::max((double)abs(field[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i][0]),maxv);
        maxv = std::max((double)abs(field[k*(Z+BW)*(Y+BW)+j*(Y+BW)+i][1]),maxv);
      }
    }
  }

}

template <typename T>
void WriteHeatFocus(T * gridA,
    const uint &X, const uint &Y, const uint &Z) {

  uint Xc, Yc, Zc;

  Xc = 2.0/5.0*(X);
  Yc = 2.0/5.5*(Y);
  Zc = 1.0/2.0*(Z);

  for(uint k = 0; k < Z + BW; k++) {
    for(uint j = 0; j < Y + BW; j++) {
      for(uint i = 0; i < Z + BW; i++) {

        double d2 = pow((Xc - (double)(i)),2) + pow((Yc - (double)(j)),2) + pow((Zc - (double)(k)),2);
        double rr = pow(X/6.0,2);

        if(d2 < rr)
          gridA[k*(Y+BW)*(X+BW)+j*(X+BW)+i] = 1.0 - d2/rr;
      }
    }
  }

}

void Interpolate(Triple prevDelta, Triple prevVeloc, Triple * field,
    const uint &X, const uint &Y, const uint &Z) {

  uint pi,pj,pk,ni,nj,nk;

  GlobalToLocal(prevDelta,idx);

  pi = floor(prevDelta[0]); ni = pi+1;
  pj = floor(prevDelta[1]); nj = pj+1;
  pk = floor(prevDelta[2]); nk = pk+1;

  PrecisionType Nx, Ny, Nz;

  Nx = 1-(prevDelta[0] - floor(prevDelta[0]));
  Ny = 1-(prevDelta[1] - floor(prevDelta[1]));
  Nz = 1-(prevDelta[2] - floor(prevDelta[2]));

  for(int d = 0; d < 3; d++) {
    prevVeloc[d] = (
      field[pk*(Z+BW)*(Y+BW)+pj*(Y+BW)+pi][d] * (    Nx) * (    Ny) * (    Nz) +
      field[pk*(Z+BW)*(Y+BW)+pj*(Y+BW)+ni][d] * (1 - Nx) * (    Ny) * (    Nz) +
      field[pk*(Z+BW)*(Y+BW)+nj*(Y+BW)+pi][d] * (    Nx) * (1 - Ny) * (    Nz) +
      field[pk*(Z+BW)*(Y+BW)+nj*(Y+BW)+ni][d] * (1 - Nx) * (1 - Ny) * (    Nz) +
      field[nk*(Z+BW)*(Y+BW)+pj*(Y+BW)+pi][d] * (    Nx) * (    Ny) * (1 - Nz) +
      field[nk*(Z+BW)*(Y+BW)+pj*(Y+BW)+ni][d] * (1 - Nx) * (    Ny) * (1 - Nz) +
      field[nk*(Z+BW)*(Y+BW)+nj*(Y+BW)+pi][d] * (    Nx) * (1 - Ny) * (1 - Nz) +
      field[nk*(Z+BW)*(Y+BW)+nj*(Y+BW)+ni][d] * (1 - Nx) * (1 - Ny) * (1 - Nz)
    );
  }
}

template <typename T>
double Interpolate(Triple prevDelta, T * gridA,
    const uint &X, const uint &Y, const uint &Z) {

  uint pi,pj,pk,ni,nj,nk;

  GlobalToLocal(prevDelta,idx);

  pi = floor(prevDelta[0]); ni = pi+1;
  pj = floor(prevDelta[1]); nj = pj+1;
  pk = floor(prevDelta[2]); nk = pk+1;

  double Nx, Ny, Nz;

  Nx = 1-(prevDelta[0] - floor(prevDelta[0]));
  Ny = 1-(prevDelta[1] - floor(prevDelta[1]));
  Nz = 1-(prevDelta[2] - floor(prevDelta[2]));

  return (
    gridA[pk*(Z+BW)*(Y+BW)+pj*(Y+BW)+pi] * (    Nx) * (    Ny) * (    Nz) +
    gridA[pk*(Z+BW)*(Y+BW)+pj*(Y+BW)+ni] * (1 - Nx) * (    Ny) * (    Nz) +
    gridA[pk*(Z+BW)*(Y+BW)+nj*(Y+BW)+pi] * (    Nx) * (1 - Ny) * (    Nz) +
    gridA[pk*(Z+BW)*(Y+BW)+nj*(Y+BW)+ni] * (1 - Nx) * (1 - Ny) * (    Nz) +
    gridA[nk*(Z+BW)*(Y+BW)+pj*(Y+BW)+pi] * (    Nx) * (    Ny) * (1 - Nz) +
    gridA[nk*(Z+BW)*(Y+BW)+pj*(Y+BW)+ni] * (1 - Nx) * (    Ny) * (1 - Nz) +
    gridA[nk*(Z+BW)*(Y+BW)+nj*(Y+BW)+pi] * (    Nx) * (1 - Ny) * (1 - Nz) +
    gridA[nk*(Z+BW)*(Y+BW)+nj*(Y+BW)+ni] * (1 - Nx) * (1 - Ny) * (1 - Nz)
  );
}

template <typename U>
void precalculateBackAndForw(U * fieldA, U * backward, U * forward,
    const uint &X, const uint &Y, const uint &Z) {

  Triple origin;

  for(uint k = BWP + omp_get_thread_num(); k < Z + BWP; k+=omp_get_num_threads()) {
    for(uint j = BWP; j < Y + BWP; j++) {
      for(uint i = BWP; i < X + BWP; i++) {
        uint cell = k*(Z+BW)*(Y+BW)+j*(Y+BW)+i;

        origin[0] = i;
        origin[1] = j;
        origin[2] = k;

        for(int d = 0; d < 3; d++) {
          backward[cell][d] = origin[d]*h-fieldA[cell][d]*dt;
          forward[cell][d]  = origin[d]*h+fieldA[cell][d]*dt;
        }
      }
    }
  }

}

template <typename T, typename U>
void advection(T * gridA, T * gridB, T * gridC, U * fieldA, U * backward, U * forward,
    const uint &X, const uint &Y, const uint &Z) {

  for(uint k = BWP + omp_get_thread_num(); k < Z + BWP; k+=omp_get_num_threads()) {
    for(uint j = BWP; j < Y + BWP; j++) {
      for(uint i = BWP; i < X + BWP; i++) {
        uint cell = k*(Z+BW)*(Y+BW)+j*(Y+BW)+i;
        gridB[cell] = Interpolate(backward[cell],gridA,N,N,N);
      }
    }
  }

  #pragma omp barrier

  for(uint k = BWP + omp_get_thread_num(); k < Z + BWP; k+=omp_get_num_threads()) {
    for(uint j = BWP; j < Y + BWP; j++) {
      for(uint i = BWP; i < X + BWP; i++) {
        uint cell = k*(Z+BW)*(Y+BW)+j*(Y+BW)+i;
        gridC[cell] = 1.5 * gridA[cell] - 0.5 * Interpolate(forward[cell],gridB,N,N,N);
      }
    }
  }

  #pragma omp barrier

  for(uint k = BWP + omp_get_thread_num(); k < Z + BWP; k+=omp_get_num_threads()) {
    for(uint j = BWP; j < Y + BWP; j++) {
      for(uint i = BWP; i < X + BWP; i++) {
        uint cell = k*(Z+BW)*(Y+BW)+j*(Y+BW)+i;
        gridA[cell] = Interpolate(backward[cell],gridC,N,N,N);
      }
    }
  }
}

template <typename T>
void difussion(T * &gridA, T * &gridB,
    const uint &X, const uint &Y, const uint &Z) {

  for(uint k = BWP + omp_get_thread_num(); k < Z + BWP; k+=omp_get_num_threads()) {
    for(uint j = BWP; j < Y + BWP; j++) {
      uint cell = k*(Z+BW)*(Y+BW)+j*(Y+BW)+BWP;
      for(uint i = BWP; i < X + BWP; i++) {
        stencilCross(gridA,gridB,cell++,X,Y,Z);
      }
    }
  }
}

template <typename T, typename U>
void advection(T * gridA, T * gridB, T * gridC, U * fieldA, U * fieldB,
    const uint &X, const uint &Y, const uint &Z) {

  // Backward
  for(uint kk = 0; kk < NB; kk++)
    for(uint jj = 0; jj < NB; jj++)
      for(uint ii = 0; ii < NB; ii++)
        for(uint k = BWP + (kk * NE) + omp_get_thread_num(); k < BWP + ((kk+1) * NE); k+=omp_get_num_threads())
          for(uint j = BWP + (jj * NE); j < BWP + ((jj+1) * NE); j++)
            for(uint i = BWP + (ii * NE); i < BWP + ((ii+1) * NE); i++)
              bfecc_kernel(gridB,gridA,gridA,fieldA,-1.0,0.0,1.0,i,j,k,X,Y,Z);

  #pragma omp barrier

  // Forward
  for(uint kk = 0; kk < NB; kk++)
    for(uint jj = 0; jj < NB; jj++)
      for(uint ii = 0; ii < NB; ii++)
        for(uint k = BWP + (kk * NE) + omp_get_thread_num(); k < BWP + ((kk+1) * NE); k+=omp_get_num_threads())
          for(uint j = BWP + (jj * NE); j < BWP + ((jj+1) * NE); j++)
            for(uint i = BWP + (ii * NE); i < BWP + ((ii+1) * NE); i++)
              bfecc_kernel(gridC,gridA,gridB,fieldA,1.0,1.5,-0.5,i,j,k,X,Y,Z);

  #pragma omp barrier

  // Backward
  for(uint kk = 0; kk < NB; kk++)
    for(uint jj = 0; jj < NB; jj++)
      for(uint ii = 0; ii < NB; ii++)
        for(uint k = BWP + (kk * NE) + omp_get_thread_num(); k < BWP + ((kk+1) * NE); k+=omp_get_num_threads())
          for(uint j = BWP + (jj * NE); j < BWP + ((jj+1) * NE); j++)
            for(uint i = BWP + (ii * NE); i < BWP + ((ii+1) * NE); i++)
              bfecc_kernel(gridA,gridA,gridC,fieldA,-1.0,0.0,1.0,i,j,k,X,Y,Z);
}

int main(int argc, char *argv[]) {

  N           = atoi(argv[1]);
  int steeps  = atoi(argv[2]);
  h           = atoi(argv[3]);

  NB          = atoi(argv[4]);
  NE          = N/NB;

  dx          = h/N;
  idx         = 1.0/dx;

  struct timeval start, end;

  FileIO<PrecisionType> io("grid",N);

  PrecisionType * step0 = NULL;
  PrecisionType * step1 = NULL;
  PrecisionType * step2 = NULL;

  Triple * velf0 = NULL;
  Triple * velf1 = NULL;
  Triple * velf2 = NULL;

  double duration = 0.0;

  // Temperature
  AllocateGrid(&step0,N,N,N);
  AllocateGrid(&step1,N,N,N);
  AllocateGrid(&step2,N,N,N);

  // Velocity
  AllocateGrid(&velf0,N,N,N);
  AllocateGrid(&velf1,N,N,N);
  AllocateGrid(&velf2,N,N,N);

  printf("Allocation correct\n");
  printf("Initialize\n");

  Initialize(step0,step1,N,N,N);
  WriteHeatFocus(step0,N,N,N);
  InitializeVelocity(velf0,N,N,N);

  dt = 0.25 * CFL*h/maxv;

  io.WriteGidMesh(step0,N,N,N);

  #pragma omp parallel
  #pragma omp single
  {
    printf("-------------------\n");
    printf("Running with OMP %d\n",omp_get_num_threads());
    printf("-------------------\n");
  }

  gettimeofday(&start, NULL);

  #pragma omp parallel
  {
    precalculateBackAndForw(velf0,velf1,velf2,N,N,N);
    for(int i = 0; i < steeps; i++) {
      advection(step0,step1,step2,velf0,velf1,velf2,N,N,N);
    }
  }

  gettimeofday(&end, NULL);

  duration = FETCHTIME

  printf("Total time:\t %d s\n",duration);
  printf("Step  time:\t %d s\n",duration\steeps);

  ReleaseGrid(&step0);
  ReleaseGrid(&step1);
  ReleaseGrid(&step2);

  ReleaseGrid(&velf0);
  ReleaseGrid(&velf1);

  printf("De-Allocation correct\n");
}
<|endoftext|>


<commit_before>/*
 * nghttp2 - HTTP/2 C Library
 *
 * Copyright (c) 2012 Tatsuhiro Tsujikawa
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "nghttp2_config.h"

#include <unistd.h>
#include <signal.h>
#include <getopt.h>

#include <cstdlib>
#include <cstring>
#include <cassert>
#include <string>
#include <iostream>
#include <string>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#include <nghttp2/nghttp2.h>

#include "app_helper.h"
#include "HttpServer.h"
#include "util.h"
#include "ssl.h"

namespace nghttp2 {

namespace {
int parse_push_config(Config &config, const char *optarg) {
  const auto eq = strchr(optarg, '=');
  if (eq == NULL) {
    return -1;
  }
  auto &paths = config.push[std::string(optarg, eq)];
  auto optarg_end = optarg + strlen(optarg);
  auto i = eq + 1;
  for (;;) {
    auto j = strchr(i, ',');
    if (j == NULL) {
      j = optarg_end;
    }
    paths.emplace_back(i, j);
    if (j == optarg_end) {
      break;
    }
    i = j;
    ++i;
  }

  return 0;
}
} // namespace

namespace {
void print_version(std::ostream &out) {
  out << "nghttpd nghttp2/" NGHTTP2_VERSION << std::endl;
}
} // namespace

namespace {
void print_usage(std::ostream &out) {
  out << "Usage: nghttpd [OPTION]... <PORT> [<PRIVATE_KEY> <CERT>]\n"
      << "HTTP/2 experimental server" << std::endl;
}
} // namespace

namespace {
void print_help(std::ostream &out) {
  print_usage(out);
  out << R"(
  <PORT>      Specify listening port number.
  <PRIVATE_KEY>
              Set  path  to  server's private  key.   Required  unless
              --no-tls is specified.
  <CERT>      Set  path  to  server's  certificate.   Required  unless
              --no-tls is specified.
Options:
  -D, --daemon
              Run in a background.  If -D is used, the current working
              directory is  changed to '/'.  Therefore  if this option
              is used, -d option must be specified.
  -V, --verify-client
              The server  sends a client certificate  request.  If the
              client did  not return  a certificate, the  handshake is
              terminated.   Currently,  this  option just  requests  a
              client certificate and does not verify it.
  -d, --htdocs=<PATH>
              Specify document root.  If this option is not specified,
              the document root is the current working directory.
  -v, --verbose
              Print debug information  such as reception/ transmission
              of frames and name/value pairs.
  --no-tls    Disable SSL/TLS.
  -c, --header-table-size=<SIZE>
              Specify decoder header table size.
  --color     Force colored log output.
  -p, --push=<PATH>=<PUSH_PATH,...>
              Push  resources <PUSH_PATH>s  when <PATH>  is requested.
              This option  can be used repeatedly  to specify multiple
              push  configurations.    <PATH>  and   <PUSH_PATH>s  are
              relative  to   document  root.   See   --htdocs  option.
              Example: -p/=/foo.png -p/doc=/bar.css
  -b, --padding=<N>
              Add at  most <N>  bytes to a  frame payload  as padding.
              Specify 0 to disable padding.
  -n, --workers=<N>
              Set the number of worker threads.
              Default: 1
  -e, --error-gzip
              Make error response gzipped.
  --dh-param-file=<PATH>
              Path to file that contains  DH parameters in PEM format.
              Without  this   option,  DHE   cipher  suites   are  not
              available.
  --early-response
              Start sending response when request HEADERS is received,
              rather than complete request is received.
  --version   Display version information and exit.
  -h, --help  Display this help and exit.

  The <SIZE> argument is an integer and an optional unit (e.g., 10K is
  10 * 1024).  Units are K, M and G (powers of 1024).)" << std::endl;
}
} // namespace

int main(int argc, char **argv) {
  Config config;
  bool color = false;
  while (1) {
    static int flag = 0;
    static option long_options[] = {
        {"daemon", no_argument, nullptr, 'D'},
        {"htdocs", required_argument, nullptr, 'd'},
        {"help", no_argument, nullptr, 'h'},
        {"verbose", no_argument, nullptr, 'v'},
        {"verify-client", no_argument, nullptr, 'V'},
        {"header-table-size", required_argument, nullptr, 'c'},
        {"push", required_argument, nullptr, 'p'},
        {"padding", required_argument, nullptr, 'b'},
        {"workers", required_argument, nullptr, 'n'},
        {"error-gzip", no_argument, nullptr, 'e'},
        {"no-tls", no_argument, &flag, 1},
        {"color", no_argument, &flag, 2},
        {"version", no_argument, &flag, 3},
        {"dh-param-file", required_argument, &flag, 4},
        {"early-response", no_argument, &flag, 5},
        {nullptr, 0, nullptr, 0}};
    int option_index = 0;
    int c =
        getopt_long(argc, argv, "DVb:c:d:ehn:p:v", long_options, &option_index);
    char *end;
    if (c == -1) {
      break;
    }
    switch (c) {
    case 'D':
      config.daemon = true;
      break;
    case 'V':
      config.verify_client = true;
      break;
    case 'b':
      config.padding = strtol(optarg, nullptr, 10);
      break;
    case 'd':
      config.htdocs = optarg;
      break;
    case 'e':
      config.error_gzip = true;
      break;
    case 'n':
#ifdef NOTHREADS
      std::cerr << "-n: WARNING: Threading disabled at build time, "
                << "no threads created." << std::endl;
#else
      errno = 0;
      config.num_worker = strtoul(optarg, &end, 10);
      if (errno == ERANGE || *end != '\0' || config.num_worker == 0) {
        std::cerr << "-n: Bad option value: " << optarg << std::endl;
        exit(EXIT_FAILURE);
      }
#endif // NOTHREADS
      break;
    case 'h':
      print_help(std::cout);
      exit(EXIT_SUCCESS);
    case 'v':
      config.verbose = true;
      break;
    case 'c':
      errno = 0;
      config.header_table_size = util::parse_uint_with_unit(optarg);
      if (config.header_table_size == -1) {
        std::cerr << "-c: Bad option value: " << optarg << std::endl;
        exit(EXIT_FAILURE);
      }
      break;
    case 'p':
      if (parse_push_config(config, optarg) != 0) {
        std::cerr << "-p: Bad option value: " << optarg << std::endl;
      }
      break;
    case '?':
      util::show_candidates(argv[optind - 1], long_options);
      exit(EXIT_FAILURE);
    case 0:
      switch (flag) {
      case 1:
        // no-tls option
        config.no_tls = true;
        break;
      case 2:
        // color option
        color = true;
        break;
      case 3:
        // version
        print_version(std::cout);
        exit(EXIT_SUCCESS);
      case 4:
        // dh-param-file
        config.dh_param_file = optarg;
        break;
      case 5:
        // early-response
        config.early_response = true;
        break;
      }
      break;
    default:
      break;
    }
  }
  if (argc - optind < (config.no_tls ? 1 : 3)) {
    print_usage(std::cerr);
    std::cerr << "Too few arguments" << std::endl;
    exit(EXIT_FAILURE);
  }

  config.port = strtol(argv[optind++], nullptr, 10);

  if (!config.no_tls) {
    config.private_key_file = argv[optind++];
    config.cert_file = argv[optind++];
  }

  if (config.daemon) {
    if (config.htdocs.empty()) {
      print_usage(std::cerr);
      std::cerr << "-d option must be specified when -D is used." << std::endl;
      exit(EXIT_FAILURE);
    }
    if (daemon(0, 0) == -1) {
      perror("daemon");
      exit(EXIT_FAILURE);
    }
  }
  if (config.htdocs.empty()) {
    config.htdocs = "./";
  }

  set_color_output(color || isatty(fileno(stdout)));

  struct sigaction act;
  memset(&act, 0, sizeof(struct sigaction));
  act.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &act, nullptr);
  OPENSSL_config(nullptr);
  OpenSSL_add_all_algorithms();
  SSL_load_error_strings();
  SSL_library_init();
#ifndef NOTHREADS
  ssl::LibsslGlobalLock lock;
#endif // NOTHREADS

  reset_timer();

  HttpServer server(&config);
  server.run();
  return 0;
}

} // namespace nghttp2

int main(int argc, char **argv) { return nghttp2::main(argc, argv); }
<commit_msg>nghttpd: Fix compile error on travis<commit_after>/*
 * nghttp2 - HTTP/2 C Library
 *
 * Copyright (c) 2012 Tatsuhiro Tsujikawa
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "nghttp2_config.h"

#include <unistd.h>
#include <signal.h>
#include <getopt.h>

#include <cstdlib>
#include <cstring>
#include <cassert>
#include <string>
#include <iostream>
#include <string>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#include <nghttp2/nghttp2.h>

#include "app_helper.h"
#include "HttpServer.h"
#include "util.h"
#include "ssl.h"

namespace nghttp2 {

namespace {
int parse_push_config(Config &config, const char *optarg) {
  auto eq = strchr(optarg, '=');
  if (eq == NULL) {
    return -1;
  }
  auto &paths = config.push[std::string(optarg, eq)];
  auto optarg_end = optarg + strlen(optarg);
  auto i = eq + 1;
  for (;;) {
    auto j = strchr(i, ',');
    if (j == NULL) {
      j = optarg_end;
    }
    paths.emplace_back(i, j);
    if (j == optarg_end) {
      break;
    }
    i = j;
    ++i;
  }

  return 0;
}
} // namespace

namespace {
void print_version(std::ostream &out) {
  out << "nghttpd nghttp2/" NGHTTP2_VERSION << std::endl;
}
} // namespace

namespace {
void print_usage(std::ostream &out) {
  out << "Usage: nghttpd [OPTION]... <PORT> [<PRIVATE_KEY> <CERT>]\n"
      << "HTTP/2 experimental server" << std::endl;
}
} // namespace

namespace {
void print_help(std::ostream &out) {
  print_usage(out);
  out << R"(
  <PORT>      Specify listening port number.
  <PRIVATE_KEY>
              Set  path  to  server's private  key.   Required  unless
              --no-tls is specified.
  <CERT>      Set  path  to  server's  certificate.   Required  unless
              --no-tls is specified.
Options:
  -D, --daemon
              Run in a background.  If -D is used, the current working
              directory is  changed to '/'.  Therefore  if this option
              is used, -d option must be specified.
  -V, --verify-client
              The server  sends a client certificate  request.  If the
              client did  not return  a certificate, the  handshake is
              terminated.   Currently,  this  option just  requests  a
              client certificate and does not verify it.
  -d, --htdocs=<PATH>
              Specify document root.  If this option is not specified,
              the document root is the current working directory.
  -v, --verbose
              Print debug information  such as reception/ transmission
              of frames and name/value pairs.
  --no-tls    Disable SSL/TLS.
  -c, --header-table-size=<SIZE>
              Specify decoder header table size.
  --color     Force colored log output.
  -p, --push=<PATH>=<PUSH_PATH,...>
              Push  resources <PUSH_PATH>s  when <PATH>  is requested.
              This option  can be used repeatedly  to specify multiple
              push  configurations.    <PATH>  and   <PUSH_PATH>s  are
              relative  to   document  root.   See   --htdocs  option.
              Example: -p/=/foo.png -p/doc=/bar.css
  -b, --padding=<N>
              Add at  most <N>  bytes to a  frame payload  as padding.
              Specify 0 to disable padding.
  -n, --workers=<N>
              Set the number of worker threads.
              Default: 1
  -e, --error-gzip
              Make error response gzipped.
  --dh-param-file=<PATH>
              Path to file that contains  DH parameters in PEM format.
              Without  this   option,  DHE   cipher  suites   are  not
              available.
  --early-response
              Start sending response when request HEADERS is received,
              rather than complete request is received.
  --version   Display version information and exit.
  -h, --help  Display this help and exit.

  The <SIZE> argument is an integer and an optional unit (e.g., 10K is
  10 * 1024).  Units are K, M and G (powers of 1024).)" << std::endl;
}
} // namespace

int main(int argc, char **argv) {
  Config config;
  bool color = false;
  while (1) {
    static int flag = 0;
    static option long_options[] = {
        {"daemon", no_argument, nullptr, 'D'},
        {"htdocs", required_argument, nullptr, 'd'},
        {"help", no_argument, nullptr, 'h'},
        {"verbose", no_argument, nullptr, 'v'},
        {"verify-client", no_argument, nullptr, 'V'},
        {"header-table-size", required_argument, nullptr, 'c'},
        {"push", required_argument, nullptr, 'p'},
        {"padding", required_argument, nullptr, 'b'},
        {"workers", required_argument, nullptr, 'n'},
        {"error-gzip", no_argument, nullptr, 'e'},
        {"no-tls", no_argument, &flag, 1},
        {"color", no_argument, &flag, 2},
        {"version", no_argument, &flag, 3},
        {"dh-param-file", required_argument, &flag, 4},
        {"early-response", no_argument, &flag, 5},
        {nullptr, 0, nullptr, 0}};
    int option_index = 0;
    int c =
        getopt_long(argc, argv, "DVb:c:d:ehn:p:v", long_options, &option_index);
    char *end;
    if (c == -1) {
      break;
    }
    switch (c) {
    case 'D':
      config.daemon = true;
      break;
    case 'V':
      config.verify_client = true;
      break;
    case 'b':
      config.padding = strtol(optarg, nullptr, 10);
      break;
    case 'd':
      config.htdocs = optarg;
      break;
    case 'e':
      config.error_gzip = true;
      break;
    case 'n':
#ifdef NOTHREADS
      std::cerr << "-n: WARNING: Threading disabled at build time, "
                << "no threads created." << std::endl;
#else
      errno = 0;
      config.num_worker = strtoul(optarg, &end, 10);
      if (errno == ERANGE || *end != '\0' || config.num_worker == 0) {
        std::cerr << "-n: Bad option value: " << optarg << std::endl;
        exit(EXIT_FAILURE);
      }
#endif // NOTHREADS
      break;
    case 'h':
      print_help(std::cout);
      exit(EXIT_SUCCESS);
    case 'v':
      config.verbose = true;
      break;
    case 'c':
      errno = 0;
      config.header_table_size = util::parse_uint_with_unit(optarg);
      if (config.header_table_size == -1) {
        std::cerr << "-c: Bad option value: " << optarg << std::endl;
        exit(EXIT_FAILURE);
      }
      break;
    case 'p':
      if (parse_push_config(config, optarg) != 0) {
        std::cerr << "-p: Bad option value: " << optarg << std::endl;
      }
      break;
    case '?':
      util::show_candidates(argv[optind - 1], long_options);
      exit(EXIT_FAILURE);
    case 0:
      switch (flag) {
      case 1:
        // no-tls option
        config.no_tls = true;
        break;
      case 2:
        // color option
        color = true;
        break;
      case 3:
        // version
        print_version(std::cout);
        exit(EXIT_SUCCESS);
      case 4:
        // dh-param-file
        config.dh_param_file = optarg;
        break;
      case 5:
        // early-response
        config.early_response = true;
        break;
      }
      break;
    default:
      break;
    }
  }
  if (argc - optind < (config.no_tls ? 1 : 3)) {
    print_usage(std::cerr);
    std::cerr << "Too few arguments" << std::endl;
    exit(EXIT_FAILURE);
  }

  config.port = strtol(argv[optind++], nullptr, 10);

  if (!config.no_tls) {
    config.private_key_file = argv[optind++];
    config.cert_file = argv[optind++];
  }

  if (config.daemon) {
    if (config.htdocs.empty()) {
      print_usage(std::cerr);
      std::cerr << "-d option must be specified when -D is used." << std::endl;
      exit(EXIT_FAILURE);
    }
    if (daemon(0, 0) == -1) {
      perror("daemon");
      exit(EXIT_FAILURE);
    }
  }
  if (config.htdocs.empty()) {
    config.htdocs = "./";
  }

  set_color_output(color || isatty(fileno(stdout)));

  struct sigaction act;
  memset(&act, 0, sizeof(struct sigaction));
  act.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &act, nullptr);
  OPENSSL_config(nullptr);
  OpenSSL_add_all_algorithms();
  SSL_load_error_strings();
  SSL_library_init();
#ifndef NOTHREADS
  ssl::LibsslGlobalLock lock;
#endif // NOTHREADS

  reset_timer();

  HttpServer server(&config);
  server.run();
  return 0;
}

} // namespace nghttp2

int main(int argc, char **argv) { return nghttp2::main(argc, argv); }
<|endoftext|>


<commit_before>#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <string>
#include <list>
#include <map>
#include <iostream>

#include "segment.h"
#include "message.h"
#include "register_success_message.h"
#include "register_failure_message.h"
#include "register_request_message.h"
#include "loc_success_message.h"
#include "loc_failure_message.h"
#include "loc_request_message.h"
#include "terminate_message.h"
#include "constants.h"
#include "network.h"
#include "helper_functions.h"

using namespace std;

// Global variables for binder
static map<procedure_signature, list<server_info *>, ps_compare> procLocDict;
static list<server_function_info *> roundRobinList;
static list<server_info *> serverList;
static bool isTerminated = false;

// Handles a registration request from the server
void handleRegistrationRequest(RegisterRequestMessage *message, int sock) {
  const char * name = message->getName().c_str();
  int * argTypes = message->getArgTypes();
  string server_identifier = message->getServerIdentifier();
  int port = message->getPort();

  procedure_signature key(name, argTypes);

  int status = 0;

  //if 'key' dosnt exist in map, add it to the map and round robin
	if (procLocDict.find(key) == procLocDict.end()) {

    //The purpose of this function is so we can have copy of the argTypes that not the original
    int *memArgTypes = copyArgTypes(argTypes);

    key = procedure_signature(name, memArgTypes);
    procLocDict[key] = list<server_info *>();

    //This is bad we shouldn't need a newKey and we should be able to use the key above
    //due to &* reasones I made a variable newKey for the 'info' object
    procedure_signature * newKey = new procedure_signature(name, memArgTypes);
    server_info * entry = new server_info(server_identifier, port, sock);
    server_function_info * info = new server_function_info(entry, newKey);

    // Adding to roundRobinList if server is not found
    roundRobinList.push_back(info);

    // Adding to serverList if server is not found
    bool serverExist = false;
    for (list<server_info *>::iterator it = serverList.begin(); it != serverList.end(); it++) {

      if( (*it)->server_identifier == entry->server_identifier && (*it)->port == entry->port &&  (*it)->socket == entry->socket){
        serverExist = true;
        break;
      }
    }

    if (!serverExist) {
      serverList.push_back(entry);
    }

  } else {
    bool sameLoc = false;
    list<server_info *> hostList = procLocDict[key];

    for (list<server_info *>::iterator it = hostList.begin(); it != hostList.end(); it++) {

      if((*it)->server_identifier == server_identifier && (*it)->port == port  && (*it)->socket == sock){
      //if((*it)->port == port  && (*it)->socket == sock){

        //If they have the same socket, then must be same server_address/port
        //The same procedure signature already exists on the same location
        //TODO: Move to end of round robin or something, maybe we should keep
        sameLoc = true;
      }
    }

  	if (!sameLoc) { //same procedure different socket

      server_info * new_msg_loc = new server_info(server_identifier, port, sock);
      hostList.push_back(new_msg_loc);

      int *newArgTypes = copyArgTypes(argTypes);

      procedure_signature * useFulKey = new procedure_signature(name, newArgTypes);
      server_function_info * info = new server_function_info(new_msg_loc, useFulKey);

      //Adding to roundRobinList if server is not found
      roundRobinList.push_back(info);

      //Adding to serverList if server is not found
      bool serverExist = false;
      for (list<server_info *>::iterator it = serverList.begin(); it != serverList.end(); it++) {

        if( (*it)->server_identifier == new_msg_loc->server_identifier && (*it)->port == new_msg_loc->port &&  (*it)->socket == new_msg_loc->socket){
          serverExist = true;
          break;
        }
      }

      if (!serverExist) {
        serverList.push_back(new_msg_loc);
      }
    }
  }

  RegisterSuccessMessage regSuccessMsg = RegisterSuccessMessage(status);
  Segment regSuccessSeg = Segment(regSuccessMsg.getLength(), MSG_TYPE_REGISTER_SUCCESS, &regSuccessMsg);
  regSuccessSeg.send(sock);

}

// Handles a location request from the client
void handleLocationRequest(LocRequestMessage *message, int sock) {
  bool exist = false;
  string serverIdToPushBack;
  int portToPushBack;
  int socketToPushBack;

	for (list<server_function_info *>::iterator it = roundRobinList.begin(); it != roundRobinList.end(); it++){
    //If the name are the same and argTypes

    if((*it)->ps->name == message->getName() && compareArr((*it)->ps->argTypes, message->getArgTypes() )){
      exist = true;

      serverIdToPushBack = (*it)->si->server_identifier;
      portToPushBack = (*it)->si->port;
      socketToPushBack = (*it)->si->socket;

      LocSuccessMessage locSuccessMsg = LocSuccessMessage((*it)->si->server_identifier.c_str(), (*it)->si->port);
      Segment locSuccessSeg = Segment(locSuccessMsg.getLength(), MSG_TYPE_LOC_SUCCESS, &locSuccessMsg);
      locSuccessSeg.send(sock);

      break;
 		}
	}

  if (exist) {

    list<server_function_info *>::iterator i = roundRobinList.begin();
    list<server_function_info *> tempList;

    while (i != roundRobinList.end()){
      if((*i)->si->server_identifier == serverIdToPushBack && (*i)->si->port == portToPushBack && (*i)->si->socket == socketToPushBack){
        tempList.push_back(*i);
        roundRobinList.erase(i++);  // alternatively, i = items.erase(i);
      }else{
        ++i;
      }
    }

    roundRobinList.splice(roundRobinList.end(), tempList);

  } else {
    LocFailureMessage locFailMsg =
      LocFailureMessage(ERROR_CODE_PROCEDURE_NOT_FOUND);
    Segment locFailSeg = Segment(locFailMsg.getLength(), MSG_TYPE_LOC_FAILURE, &locFailMsg);
    locFailSeg.send(sock);
  }
}

// Handles a termination request from the client
void handleTerminationRequest() {
  // Informs all the servers to terminate
  for (list<server_info *>::const_iterator it = serverList.begin(); it != serverList.end(); it++) {
    TerminateMessage messageToServer = TerminateMessage();
    Segment segmentToServer =
      Segment(messageToServer.getLength(), MSG_TYPE_TERMINATE,
        &messageToServer);
    segmentToServer.send((*it)->socket);
  }

  // Signals the binder to terminate
  isTerminated = true;
}

// Handles a request from the client/server
void handleRequest(Segment *segment, int socket) {
  switch (segment->getType()) {
    case MSG_TYPE_REGISTER_REQUEST: {
      RegisterRequestMessage *messageFromServer =
        dynamic_cast<RegisterRequestMessage *>(segment->getMessage());
      handleRegistrationRequest(messageFromServer, socket);
      break;
    }

    case MSG_TYPE_LOC_REQUEST: {
      LocRequestMessage *messageFromClient =
        dynamic_cast<LocRequestMessage *>(segment->getMessage());
      handleLocationRequest(messageFromClient, socket);
      break;
    }

    case MSG_TYPE_TERMINATE: {
      handleTerminationRequest();
      break;
    }
  }
}

int main() {
  fd_set allSockets;
  fd_set readSockets;

  /*
   * Clears all entries from the all sockets set and the read
   * sockets set
   */
  FD_ZERO(&allSockets);
  FD_ZERO(&readSockets);

  /*
   * Creates the welcome socket, adds it to the all sockets set and
   * sets it as the maximum socket so far
   */
  int welcomeSocket = createSocket();
  if (welcomeSocket < 0) {
    return welcomeSocket;
  }
  int result = setUpToListen(welcomeSocket);
  if (result < 0) {
    return result;
  }
  FD_SET(welcomeSocket, &allSockets);
  int maxSocket = welcomeSocket;

  /*
   * Prints the binder address and the binder port on the binder's
   * standard output
   */
  string binderIdentifier = getHostAddress();
  if (binderIdentifier == "") {
    return ERROR_CODE_HOST_ADDRESS_NOT_FOUND;
  }
  int port = getSocketPort(welcomeSocket);
  if (port < 0) {
    return port;
  }
  cout << "BINDER_ADDRESS " << binderIdentifier << endl;
  cout << "BINDER_PORT " << port << endl;

  while (!isTerminated) {
    readSockets = allSockets;

    // Checks if some of the sockets are ready to be read from
    int result = select(maxSocket + 1, &readSockets, 0, 0, 0);
    if (result < 0) {
      continue;
    }

    for (int i = 0; i <= maxSocket; i++) {
      if (!FD_ISSET(i, &readSockets)) {
        continue;
      }

      if (i == welcomeSocket) {

        /*
         * Creates the connection socket when a connection is made
         * to the welcome socket
         */
        int connectionSocket = acceptConnection(i);
        if (connectionSocket < 0) {
          continue;
        }

        // Adds the connection socket to the all sockets set
        FD_SET(connectionSocket, &allSockets);

        /*
         * Sets the connection socket as the maximum socket so far
         * if necessary
         */
        if (connectionSocket > maxSocket) {
          maxSocket = connectionSocket;
        }

      } else {

        /*
         * Creates a segment to receive data from the client/server and
         * reads into it from the connection socket
         */
        Segment *segment = 0;
        result = 0;
        result = Segment::receive(i, segment);
        if (result < 0) {
          /*
           * Closes the connection socket and removes it from the
           * all sockets set
           */
          destroySocket(i);
          FD_CLR(i, &allSockets);
          continue;
        }

        // Handles a request from the client/server
        handleRequest(segment, i);
      }
    }
  }

  // Destroys the welcome socket
  destroySocket(welcomeSocket);

  return SUCCESS_CODE;
}
<commit_msg>Trying out register failure<commit_after>#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <string>
#include <list>
#include <map>
#include <iostream>

#include "segment.h"
#include "message.h"
#include "register_success_message.h"
#include "register_failure_message.h"
#include "register_request_message.h"
#include "loc_success_message.h"
#include "loc_failure_message.h"
#include "loc_request_message.h"
#include "terminate_message.h"
#include "constants.h"
#include "network.h"
#include "helper_functions.h"

using namespace std;

// Global variables for binder
static map<procedure_signature, list<server_info *>, ps_compare> procLocDict;
static list<server_function_info *> roundRobinList;
static list<server_info *> serverList;
static bool isTerminated = false;

// Handles a registration request from the server
void handleRegistrationRequest(RegisterRequestMessage *message, int sock) {
  const char * name = message->getName().c_str();
  int * argTypes = message->getArgTypes();
  string server_identifier = message->getServerIdentifier();
  int port = message->getPort();
  bool failFlag = false;
  procedure_signature key(name, argTypes);

  int status = 0;
  try {

    //if 'key' dosnt exist in map, add it to the map and round robin
	  if (procLocDict.find(key) == procLocDict.end()) {

    //The purpose of this function is so we can have copy of the argTypes that not the original
    int *memArgTypes = copyArgTypes(argTypes);

    key = procedure_signature(name, memArgTypes);
    procLocDict[key] = list<server_info *>();

    //This is bad we shouldn't need a newKey and we should be able to use the key above
    //due to &* reasones I made a variable newKey for the 'info' object
    procedure_signature * newKey = new procedure_signature(name, memArgTypes);
    server_info * entry = new server_info(server_identifier, port, sock);
    server_function_info * info = new server_function_info(entry, newKey);

    // Adding to roundRobinList if server is not found
    roundRobinList.push_back(info);

    // Adding to serverList if server is not found
    bool serverExist = false;
    for (list<server_info *>::iterator it = serverList.begin(); it != serverList.end(); it++) {

      if( (*it)->server_identifier == entry->server_identifier && (*it)->port == entry->port &&  (*it)->socket == entry->socket){
        serverExist = true;
        break;
      }
    }

    if (!serverExist) {
      serverList.push_back(entry);
    }

    } else {
    bool sameLoc = false;
    list<server_info *> hostList = procLocDict[key];

    for (list<server_info *>::iterator it = hostList.begin(); it != hostList.end(); it++) {

      if((*it)->server_identifier == server_identifier && (*it)->port == port  && (*it)->socket == sock){
      //if((*it)->port == port  && (*it)->socket == sock){

        //If they have the same socket, then must be same server_address/port
        //The same procedure signature already exists on the same location
        //TODO: Move to end of round robin or something, maybe we should keep
        sameLoc = true;
      }
    }

  	if (!sameLoc) { //same procedure different socket

      server_info * new_msg_loc = new server_info(server_identifier, port, sock);
      hostList.push_back(new_msg_loc);

      int *newArgTypes = copyArgTypes(argTypes);

      procedure_signature * useFulKey = new procedure_signature(name, newArgTypes);
      server_function_info * info = new server_function_info(new_msg_loc, useFulKey);

      //Adding to roundRobinList if server is not found
      roundRobinList.push_back(info);

      //Adding to serverList if server is not found
      bool serverExist = false;
      for (list<server_info *>::iterator it = serverList.begin(); it != serverList.end(); it++) {

        if( (*it)->server_identifier == new_msg_loc->server_identifier && (*it)->port == new_msg_loc->port &&  (*it)->socket == new_msg_loc->socket){
          serverExist = true;
          break;
        }
      }

      if (!serverExist) {
        serverList.push_back(new_msg_loc);
      }
    }
    }

  } catch (int errorOccur) {
      failFlag = true;
  }

  if(failFlag){
    RegisterFailureMessage regFailureMsg = RegisterFailureMessage(status);
    Segment regFailureSeg = Segment(regFailureMsg.getLength(), MSG_TYPE_REGISTER_FAILURE, &regFailureMsg);
    regFailureSeg.send(sock);
  } else {
    RegisterSuccessMessage regSuccessMsg = RegisterSuccessMessage(status);
    Segment regSuccessSeg = Segment(regSuccessMsg.getLength(), MSG_TYPE_REGISTER_SUCCESS, &regSuccessMsg);
    regSuccessSeg.send(sock);
  }

}

// Handles a location request from the client
void handleLocationRequest(LocRequestMessage *message, int sock) {
  bool exist = false;
  string serverIdToPushBack;
  int portToPushBack;
  int socketToPushBack;

	for (list<server_function_info *>::iterator it = roundRobinList.begin(); it != roundRobinList.end(); it++){
    //If the name are the same and argTypes

    if((*it)->ps->name == message->getName() && compareArr((*it)->ps->argTypes, message->getArgTypes() )){
      exist = true;

      serverIdToPushBack = (*it)->si->server_identifier;
      portToPushBack = (*it)->si->port;
      socketToPushBack = (*it)->si->socket;

      LocSuccessMessage locSuccessMsg = LocSuccessMessage((*it)->si->server_identifier.c_str(), (*it)->si->port);
      Segment locSuccessSeg = Segment(locSuccessMsg.getLength(), MSG_TYPE_LOC_SUCCESS, &locSuccessMsg);
      locSuccessSeg.send(sock);

      break;
 		}
	}

  if (exist) {

    list<server_function_info *>::iterator i = roundRobinList.begin();
    list<server_function_info *> tempList;

    while (i != roundRobinList.end()){
      if((*i)->si->server_identifier == serverIdToPushBack && (*i)->si->port == portToPushBack && (*i)->si->socket == socketToPushBack){
        tempList.push_back(*i);
        roundRobinList.erase(i++);  // alternatively, i = items.erase(i);
      }else{
        ++i;
      }
    }

    roundRobinList.splice(roundRobinList.end(), tempList);

  } else {
    LocFailureMessage locFailMsg =
      LocFailureMessage(ERROR_CODE_PROCEDURE_NOT_FOUND);
    Segment locFailSeg = Segment(locFailMsg.getLength(), MSG_TYPE_LOC_FAILURE, &locFailMsg);
    locFailSeg.send(sock);
  }
}

// Handles a termination request from the client
void handleTerminationRequest() {
  // Informs all the servers to terminate
  for (list<server_info *>::const_iterator it = serverList.begin(); it != serverList.end(); it++) {
    TerminateMessage messageToServer = TerminateMessage();
    Segment segmentToServer =
      Segment(messageToServer.getLength(), MSG_TYPE_TERMINATE,
        &messageToServer);
    segmentToServer.send((*it)->socket);
  }

  // Signals the binder to terminate
  isTerminated = true;
}

// Handles a request from the client/server
void handleRequest(Segment *segment, int socket) {
  switch (segment->getType()) {
    case MSG_TYPE_REGISTER_REQUEST: {
      RegisterRequestMessage *messageFromServer =
        dynamic_cast<RegisterRequestMessage *>(segment->getMessage());
      handleRegistrationRequest(messageFromServer, socket);
      break;
    }

    case MSG_TYPE_LOC_REQUEST: {
      LocRequestMessage *messageFromClient =
        dynamic_cast<LocRequestMessage *>(segment->getMessage());
      handleLocationRequest(messageFromClient, socket);
      break;
    }

    case MSG_TYPE_TERMINATE: {
      handleTerminationRequest();
      break;
    }
  }
}

int main() {
  fd_set allSockets;
  fd_set readSockets;

  /*
   * Clears all entries from the all sockets set and the read
   * sockets set
   */
  FD_ZERO(&allSockets);
  FD_ZERO(&readSockets);

  /*
   * Creates the welcome socket, adds it to the all sockets set and
   * sets it as the maximum socket so far
   */
  int welcomeSocket = createSocket();
  if (welcomeSocket < 0) {
    return welcomeSocket;
  }
  int result = setUpToListen(welcomeSocket);
  if (result < 0) {
    return result;
  }
  FD_SET(welcomeSocket, &allSockets);
  int maxSocket = welcomeSocket;

  /*
   * Prints the binder address and the binder port on the binder's
   * standard output
   */
  string binderIdentifier = getHostAddress();
  if (binderIdentifier == "") {
    return ERROR_CODE_HOST_ADDRESS_NOT_FOUND;
  }
  int port = getSocketPort(welcomeSocket);
  if (port < 0) {
    return port;
  }
  cout << "BINDER_ADDRESS " << binderIdentifier << endl;
  cout << "BINDER_PORT " << port << endl;

  while (!isTerminated) {
    readSockets = allSockets;

    // Checks if some of the sockets are ready to be read from
    int result = select(maxSocket + 1, &readSockets, 0, 0, 0);
    if (result < 0) {
      continue;
    }

    for (int i = 0; i <= maxSocket; i++) {
      if (!FD_ISSET(i, &readSockets)) {
        continue;
      }

      if (i == welcomeSocket) {

        /*
         * Creates the connection socket when a connection is made
         * to the welcome socket
         */
        int connectionSocket = acceptConnection(i);
        if (connectionSocket < 0) {
          continue;
        }

        // Adds the connection socket to the all sockets set
        FD_SET(connectionSocket, &allSockets);

        /*
         * Sets the connection socket as the maximum socket so far
         * if necessary
         */
        if (connectionSocket > maxSocket) {
          maxSocket = connectionSocket;
        }

      } else {

        /*
         * Creates a segment to receive data from the client/server and
         * reads into it from the connection socket
         */
        Segment *segment = 0;
        result = 0;
        result = Segment::receive(i, segment);
        if (result < 0) {
          /*
           * Closes the connection socket and removes it from the
           * all sockets set
           */
          destroySocket(i);
          FD_CLR(i, &allSockets);
          continue;
        }

        // Handles a request from the client/server
        handleRequest(segment, i);
      }
    }
  }

  // Destroys the welcome socket
  destroySocket(welcomeSocket);

  return SUCCESS_CODE;
}
<|endoftext|>


<commit_before>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2015 Intel Corporation. All Rights Reserved.

#include "option.h"
#include "sensor.h"
#include "error-handling.h"

bool librealsense::option_base::is_valid(float value) const
{
    if (!std::isnormal(_opt_range.step) && _opt_range.step != 0)
        throw invalid_value_exception(to_string() << "is_valid(...) failed! step is not properly defined. (" << _opt_range.step << ")");

    if ((value < _opt_range.min) || (value > _opt_range.max))
        return false;

    if (_opt_range.step == 0)
        return true;

    auto n = (value - _opt_range.min) / _opt_range.step;
    return (fabs(fmod(n, 1)) < std::numeric_limits<float>::min());
}

librealsense::option_range librealsense::option_base::get_range() const
{
    return _opt_range;
}
void librealsense::option_base::enable_recording(std::function<void(const option&)> recording_action)
{
    _recording_function = recording_action;
}

void librealsense::option::create_snapshot(std::shared_ptr<option>& snapshot) const
{
    snapshot = std::make_shared<const_value_option>(get_description(), query());
}

void librealsense::float_option::set(float value)
{
    if (!is_valid(value))
        throw invalid_value_exception(to_string() << "set(...) failed! " << value << " is not a valid value");
    _value = value;
}

void librealsense::uvc_pu_option::set(float value)
{
    _ep.invoke_powered(
        [this, value](platform::uvc_device& dev)
        {
            if (!dev.set_pu(_id, static_cast<int32_t>(value)))
                throw invalid_value_exception(to_string() << "set_pu(id=" << std::to_string(_id) << ") failed!" << " Last Error: " << strerror(errno));
            _record(*this);
        });
}

float librealsense::uvc_pu_option::query() const
{
    return static_cast<float>(_ep.invoke_powered(
        [this](platform::uvc_device& dev)
        {
            int32_t value = 0;
            if (!dev.get_pu(_id, value))
                throw invalid_value_exception(to_string() << "get_pu(id=" << std::to_string(_id) << ") failed!" << " Last Error: " << strerror(errno));

            return static_cast<float>(value);
        }));
}

librealsense::option_range librealsense::uvc_pu_option::get_range() const
{
    auto uvc_range = _ep.invoke_powered(
        [this](platform::uvc_device& dev)
        {
            return dev.get_pu_range(_id);
        });

    if (uvc_range.min.size() < sizeof(int32_t)) return option_range{0,0,1,0};

    auto min = *(reinterpret_cast<int32_t*>(uvc_range.min.data()));
    auto max = *(reinterpret_cast<int32_t*>(uvc_range.max.data()));
    auto step = *(reinterpret_cast<int32_t*>(uvc_range.step.data()));
    auto def = *(reinterpret_cast<int32_t*>(uvc_range.def.data()));
    return option_range{static_cast<float>(min),
                        static_cast<float>(max),
                        static_cast<float>(step),
                        static_cast<float>(def)};
}

const char* librealsense::uvc_pu_option::get_description() const
{
    switch(_id)
    {
    case RS2_OPTION_BACKLIGHT_COMPENSATION: return "Enable / disable backlight compensation";
    case RS2_OPTION_BRIGHTNESS: return "UVC image brightness";
    case RS2_OPTION_CONTRAST: return "UVC image contrast";
    case RS2_OPTION_EXPOSURE: return "Controls exposure time of color camera. Setting any value will disable auto exposure";
    case RS2_OPTION_GAIN: return "UVC image gain";
    case RS2_OPTION_GAMMA: return "UVC image gamma setting";
    case RS2_OPTION_HUE: return "UVC image hue";
    case RS2_OPTION_SATURATION: return "UVC image saturation setting";
    case RS2_OPTION_SHARPNESS: return "UVC image sharpness setting";
    case RS2_OPTION_WHITE_BALANCE: return "Controls white balance of color image. Setting any value will disable auto white balance";
    case RS2_OPTION_ENABLE_AUTO_EXPOSURE: return "Enable / disable auto-exposure";
    case RS2_OPTION_ENABLE_AUTO_WHITE_BALANCE: return "Enable / disable auto-white-balance";
    case RS2_OPTION_POWER_LINE_FREQUENCY: return "Power Line Frequency";
    case RS2_OPTION_AUTO_EXPOSURE_PRIORITY: return "Limit exposure time when auto-exposure is ON to preserve constant fps rate";
    default: return _ep.get_option_name(_id);
    }
}

std::vector<uint8_t> librealsense::command_transfer_over_xu::send_receive(const std::vector<uint8_t>& data, int, bool require_response)
{
    return _uvc.invoke_powered([this, &data, require_response]
        (platform::uvc_device& dev)
        {
            std::vector<uint8_t> result;
            std::lock_guard<platform::uvc_device> lock(dev);

            if (data.size() > HW_MONITOR_BUFFER_SIZE)
            {
                LOG_ERROR("XU command size is invalid");
                throw invalid_value_exception(to_string() << "Requested XU command size " <<
                    std::dec << data.size() << " exceeds permitted limit " << HW_MONITOR_BUFFER_SIZE);
            }

            std::vector<uint8_t> transmit_buf(HW_MONITOR_BUFFER_SIZE, 0);
            std::copy(data.begin(), data.end(), transmit_buf.begin());

            if (!dev.set_xu(_xu, _ctrl, transmit_buf.data(), static_cast<int>(transmit_buf.size())))
                throw invalid_value_exception(to_string() << "set_xu(ctrl=" << unsigned(_ctrl) << ") failed!" << " Last Error: " << strerror(errno));

            if (require_response)
            {
                result.resize(HW_MONITOR_BUFFER_SIZE);
                if (!dev.get_xu(_xu, _ctrl, result.data(), static_cast<int>(result.size())))
                    throw invalid_value_exception(to_string() << "get_xu(ctrl=" << unsigned(_ctrl) << ") failed!" << " Last Error: " << strerror(errno));

                // Returned data size located in the last 4 bytes
                auto data_size = *(reinterpret_cast<uint32_t*>(result.data() + HW_MONITOR_DATA_SIZE_OFFSET)) + SIZE_OF_HW_MONITOR_HEADER;
                result.resize(data_size);
            }
            return result;
        });
}

void librealsense::polling_errors_disable::set(float value)
{
    if (value < 0)
        throw invalid_value_exception("Invalid polling errors disable request " + std::to_string(value));

    if (value == 0)
    {
        _polling_error_handler->stop();
        _value = 0;
    }
    else
    {
        _polling_error_handler->start();
        _value = 1;
    }
    _recording_function(*this);
}

float librealsense::polling_errors_disable::query() const
{
    return _value;
}

librealsense::option_range librealsense::polling_errors_disable::get_range() const
{
    return option_range{0, 1, 1, 0};
}

bool librealsense::polling_errors_disable::is_enabled() const
{
    return true;
}

const char * librealsense::polling_errors_disable::get_description() const
{
    return "Enable / disable polling of camera internal errors";
}

const char * librealsense::polling_errors_disable::get_value_description(float value) const
{
    if (value == 0)
    {
        return "Disable error polling";
    }
    else
    {
        return "Enable error polling";
    }
}

std::vector<rs2_option> librealsense::options_container::get_supported_options() const
{
    std::vector<rs2_option> options;
    for (auto option : _options)
        options.push_back(option.first);

    return options;
}<commit_msg>tooltip text corrected<commit_after>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2015 Intel Corporation. All Rights Reserved.

#include "option.h"
#include "sensor.h"
#include "error-handling.h"

bool librealsense::option_base::is_valid(float value) const
{
    if (!std::isnormal(_opt_range.step) && _opt_range.step != 0)
        throw invalid_value_exception(to_string() << "is_valid(...) failed! step is not properly defined. (" << _opt_range.step << ")");

    if ((value < _opt_range.min) || (value > _opt_range.max))
        return false;

    if (_opt_range.step == 0)
        return true;

    auto n = (value - _opt_range.min) / _opt_range.step;
    return (fabs(fmod(n, 1)) < std::numeric_limits<float>::min());
}

librealsense::option_range librealsense::option_base::get_range() const
{
    return _opt_range;
}
void librealsense::option_base::enable_recording(std::function<void(const option&)> recording_action)
{
    _recording_function = recording_action;
}

void librealsense::option::create_snapshot(std::shared_ptr<option>& snapshot) const
{
    snapshot = std::make_shared<const_value_option>(get_description(), query());
}

void librealsense::float_option::set(float value)
{
    if (!is_valid(value))
        throw invalid_value_exception(to_string() << "set(...) failed! " << value << " is not a valid value");
    _value = value;
}

void librealsense::uvc_pu_option::set(float value)
{
    _ep.invoke_powered(
        [this, value](platform::uvc_device& dev)
        {
            if (!dev.set_pu(_id, static_cast<int32_t>(value)))
                throw invalid_value_exception(to_string() << "set_pu(id=" << std::to_string(_id) << ") failed!" << " Last Error: " << strerror(errno));
            _record(*this);
        });
}

float librealsense::uvc_pu_option::query() const
{
    return static_cast<float>(_ep.invoke_powered(
        [this](platform::uvc_device& dev)
        {
            int32_t value = 0;
            if (!dev.get_pu(_id, value))
                throw invalid_value_exception(to_string() << "get_pu(id=" << std::to_string(_id) << ") failed!" << " Last Error: " << strerror(errno));

            return static_cast<float>(value);
        }));
}

librealsense::option_range librealsense::uvc_pu_option::get_range() const
{
    auto uvc_range = _ep.invoke_powered(
        [this](platform::uvc_device& dev)
        {
            return dev.get_pu_range(_id);
        });

    if (uvc_range.min.size() < sizeof(int32_t)) return option_range{0,0,1,0};

    auto min = *(reinterpret_cast<int32_t*>(uvc_range.min.data()));
    auto max = *(reinterpret_cast<int32_t*>(uvc_range.max.data()));
    auto step = *(reinterpret_cast<int32_t*>(uvc_range.step.data()));
    auto def = *(reinterpret_cast<int32_t*>(uvc_range.def.data()));
    return option_range{static_cast<float>(min),
                        static_cast<float>(max),
                        static_cast<float>(step),
                        static_cast<float>(def)};
}

const char* librealsense::uvc_pu_option::get_description() const
{
    switch(_id)
    {
    case RS2_OPTION_BACKLIGHT_COMPENSATION: return "Enable / disable backlight compensation";
    case RS2_OPTION_BRIGHTNESS: return "UVC image brightness";
    case RS2_OPTION_CONTRAST: return "UVC image contrast";
    case RS2_OPTION_EXPOSURE: return "Controls exposure time of color camera. Setting any value will disable auto exposure";
    case RS2_OPTION_GAIN: return "UVC image gain";
    case RS2_OPTION_GAMMA: return "UVC image gamma setting";
    case RS2_OPTION_HUE: return "UVC image hue";
    case RS2_OPTION_SATURATION: return "UVC image saturation setting";
    case RS2_OPTION_SHARPNESS: return "UVC image sharpness setting";
    case RS2_OPTION_WHITE_BALANCE: return "Controls white balance of color image. Setting any value will disable auto white balance";
    case RS2_OPTION_ENABLE_AUTO_EXPOSURE: return "Enable / disable auto-exposure";
    case RS2_OPTION_ENABLE_AUTO_WHITE_BALANCE: return "Enable / disable auto-white-balance";
    case RS2_OPTION_POWER_LINE_FREQUENCY: return "Power Line Frequency";
    case RS2_OPTION_AUTO_EXPOSURE_PRIORITY: return "Restrict Auto-Exposure to enforce constant FPS rate. Turn ON to remove the restrictions (may result in FPS drop)";
    default: return _ep.get_option_name(_id);
    }
}

std::vector<uint8_t> librealsense::command_transfer_over_xu::send_receive(const std::vector<uint8_t>& data, int, bool require_response)
{
    return _uvc.invoke_powered([this, &data, require_response]
        (platform::uvc_device& dev)
        {
            std::vector<uint8_t> result;
            std::lock_guard<platform::uvc_device> lock(dev);

            if (data.size() > HW_MONITOR_BUFFER_SIZE)
            {
                LOG_ERROR("XU command size is invalid");
                throw invalid_value_exception(to_string() << "Requested XU command size " <<
                    std::dec << data.size() << " exceeds permitted limit " << HW_MONITOR_BUFFER_SIZE);
            }

            std::vector<uint8_t> transmit_buf(HW_MONITOR_BUFFER_SIZE, 0);
            std::copy(data.begin(), data.end(), transmit_buf.begin());

            if (!dev.set_xu(_xu, _ctrl, transmit_buf.data(), static_cast<int>(transmit_buf.size())))
                throw invalid_value_exception(to_string() << "set_xu(ctrl=" << unsigned(_ctrl) << ") failed!" << " Last Error: " << strerror(errno));

            if (require_response)
            {
                result.resize(HW_MONITOR_BUFFER_SIZE);
                if (!dev.get_xu(_xu, _ctrl, result.data(), static_cast<int>(result.size())))
                    throw invalid_value_exception(to_string() << "get_xu(ctrl=" << unsigned(_ctrl) << ") failed!" << " Last Error: " << strerror(errno));

                // Returned data size located in the last 4 bytes
                auto data_size = *(reinterpret_cast<uint32_t*>(result.data() + HW_MONITOR_DATA_SIZE_OFFSET)) + SIZE_OF_HW_MONITOR_HEADER;
                result.resize(data_size);
            }
            return result;
        });
}

void librealsense::polling_errors_disable::set(float value)
{
    if (value < 0)
        throw invalid_value_exception("Invalid polling errors disable request " + std::to_string(value));

    if (value == 0)
    {
        _polling_error_handler->stop();
        _value = 0;
    }
    else
    {
        _polling_error_handler->start();
        _value = 1;
    }
    _recording_function(*this);
}

float librealsense::polling_errors_disable::query() const
{
    return _value;
}

librealsense::option_range librealsense::polling_errors_disable::get_range() const
{
    return option_range{0, 1, 1, 0};
}

bool librealsense::polling_errors_disable::is_enabled() const
{
    return true;
}

const char * librealsense::polling_errors_disable::get_description() const
{
    return "Enable / disable polling of camera internal errors";
}

const char * librealsense::polling_errors_disable::get_value_description(float value) const
{
    if (value == 0)
    {
        return "Disable error polling";
    }
    else
    {
        return "Enable error polling";
    }
}

std::vector<rs2_option> librealsense::options_container::get_supported_options() const
{
    std::vector<rs2_option> options;
    for (auto option : _options)
        options.push_back(option.first);

    return options;
}<|endoftext|>


<commit_before>/*
  +----------------------------------------------------------------------+
  | Swoole                                                               |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.0 of the Apache license,    |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.apache.org/licenses/LICENSE-2.0.html                      |
  | If you did not receive a copy of the Apache2.0 license and are unable|
  | to obtain it through the world-wide-web, please send a note to       |
  | license@swoole.com so we can mail you a copy immediately.            |
  +----------------------------------------------------------------------+
  | Author: Tianfeng Han  <mikan.tenny@gmail.com>                        |
  +----------------------------------------------------------------------+
*/
#include "swoole.h"
#include "coroutine.h"

#include <queue>
#include <unordered_map>

using namespace std;
using namespace swoole;

struct wait_task
{
    Coroutine *co;
    pid_t pid;
    int status;
};

static unordered_map<int, wait_task *> waitpid_map;
static unordered_map<int, int> child_processes;
static queue<wait_task *> wait_list;

bool signal_init = false;

static void signal_handler(int signo)
{
    if (signo == SIGCHLD)
    {
        int __stat_loc;

        while(true)
        {
            pid_t __pid = waitpid(-1, &__stat_loc, WNOHANG);
            if (__pid < 0)
            {
                break;
            }
            wait_task *task = nullptr;
            if (waitpid_map.find(__pid) != waitpid_map.end())
            {
                task = waitpid_map[__pid];
                waitpid_map.erase(__pid);
            }
            else if (wait_list.size() > 0)
            {
                task = wait_list.front();
                wait_list.pop();
            }
            else
            {
                child_processes[__pid] = __stat_loc;
            }
            if (task)
            {
                task->status = __stat_loc;
                task->pid = __pid;
                task->co->resume();
            }
        }
    }
}

extern "C"
{

void swoole_coroutine_signal_init()
{
    if (!signal_init)
    {
        signal_init = true;
        swSignal_add(SIGCHLD, signal_handler);
#ifdef HAVE_SIGNALFD
        if (SwooleG.use_signalfd && !swReactor_handle_isset(SwooleG.main_reactor, SW_FD_SIGNAL))
        {
            swSignalfd_setup(SwooleG.main_reactor);
        }
#endif
    }
}

pid_t swoole_coroutine_waitpid(pid_t __pid, int *__stat_loc, int __options)
{
    if (SwooleG.main_reactor == nullptr || coroutine_get_current_cid() == -1 || (__options & WNOHANG))
    {
        return waitpid(__pid, __stat_loc, __options);
    }

    if (child_processes.find(__pid) != child_processes.end())
    {
        *__stat_loc = child_processes[__pid];
        return __pid;
    }

    wait_task task;
    task.co = coroutine_get_current();;
    waitpid_map[__pid] = &task;
    task.co->yield();
    *__stat_loc = task.status;

    return task.pid;
}

pid_t swoole_coroutine_wait(int *__stat_loc)
{
    if (SwooleG.main_reactor == nullptr || coroutine_get_current_cid() == -1)
    {
        return wait( __stat_loc);
    }

    pid_t __pid;
    if (child_processes.size() > 0)
    {
        unordered_map<int, int>::iterator i = child_processes.begin();
        __pid = i->first;
        *__stat_loc = i->second;
        child_processes.erase(__pid);
        return __pid;
    }

    wait_task task;
    task.co = coroutine_get_current();;
    waitpid_map[__pid] = &task;
    task.co->yield();
    *__stat_loc = task.status;

    return task.pid;
}

}
<commit_msg>fix wait.cc bugs.<commit_after>/*
  +----------------------------------------------------------------------+
  | Swoole                                                               |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.0 of the Apache license,    |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.apache.org/licenses/LICENSE-2.0.html                      |
  | If you did not receive a copy of the Apache2.0 license and are unable|
  | to obtain it through the world-wide-web, please send a note to       |
  | license@swoole.com so we can mail you a copy immediately.            |
  +----------------------------------------------------------------------+
  | Author: Tianfeng Han  <mikan.tenny@gmail.com>                        |
  +----------------------------------------------------------------------+
*/
#include "swoole.h"
#include "coroutine.h"

#include <queue>
#include <unordered_map>

using namespace std;
using namespace swoole;

struct wait_task
{
    Coroutine *co;
    pid_t pid;
    int status;
};

static unordered_map<int, wait_task *> waitpid_map;
static unordered_map<int, int> child_processes;
static queue<wait_task *> wait_list;

bool signal_init = false;

static void signal_handler(int signo)
{
    if (signo == SIGCHLD)
    {
        int __stat_loc;

        while(true)
        {
            pid_t __pid = waitpid(-1, &__stat_loc, WNOHANG);
            if (__pid <= 0)
            {
                break;
            }
            wait_task *task = nullptr;
            if (waitpid_map.find(__pid) != waitpid_map.end())
            {
                task = waitpid_map[__pid];
                waitpid_map.erase(__pid);
            }
            else if (wait_list.size() > 0)
            {
                task = wait_list.front();
                wait_list.pop();
            }
            else
            {
                child_processes[__pid] = __stat_loc;
            }
            if (task)
            {
                task->status = __stat_loc;
                task->pid = __pid;
                task->co->resume();
            }
        }
    }
}

extern "C"
{

void swoole_coroutine_signal_init()
{
    if (!signal_init)
    {
        signal_init = true;
        swSignal_add(SIGCHLD, signal_handler);
#ifdef HAVE_SIGNALFD
        if (SwooleG.use_signalfd && !swReactor_handle_isset(SwooleG.main_reactor, SW_FD_SIGNAL))
        {
            swSignalfd_setup(SwooleG.main_reactor);
        }
#endif
    }
}

pid_t swoole_coroutine_waitpid(pid_t __pid, int *__stat_loc, int __options)
{
    if (SwooleG.main_reactor == nullptr || coroutine_get_current_cid() == -1 || (__options & WNOHANG))
    {
        return waitpid(__pid, __stat_loc, __options);
    }

    if (child_processes.find(__pid) != child_processes.end())
    {
        *__stat_loc = child_processes[__pid];
        return __pid;
    }

    wait_task task;
    task.co = coroutine_get_current();;
    waitpid_map[__pid] = &task;
    task.co->yield();
    *__stat_loc = task.status;

    return task.pid;
}

pid_t swoole_coroutine_wait(int *__stat_loc)
{
    if (SwooleG.main_reactor == nullptr || coroutine_get_current_cid() == -1)
    {
        return wait( __stat_loc);
    }

    pid_t __pid;
    if (child_processes.size() > 0)
    {
        unordered_map<int, int>::iterator i = child_processes.begin();
        __pid = i->first;
        *__stat_loc = i->second;
        child_processes.erase(__pid);
        return __pid;
    }

    wait_task task;
    task.co = coroutine_get_current();;
    waitpid_map[__pid] = &task;
    task.co->yield();
    *__stat_loc = task.status;

    return task.pid;
}

}
<|endoftext|>


<commit_before>#include "OrientationSensorsWrapper.h"
#include "SDLogDriver.h"
#include "DualEncoderDriver.h"
#include "MotorDriver.h"
#include "PlanarAccelerationModule.h"
#include "TireContactModule.h"
#include "FrontLiftedDetection.h"

#include "constants.h"

#include <Wire.h>
#include <SD.h>

enum {
	WAITING_FOR_COMMAND,
	PREPARE_TO_FIGHT,
	IN_COMBAT,
	RECALIBRATE,
	BRAINDEAD,
	TEST_MODE
} robot_state = WAITING_FOR_COMMAND;

uint32_t prepare_micros;

void log_info()
{
	log_data_pack.timestamp = millis();

	log_data_pack.acc_x = position.getAccX();
	log_data_pack.acc_y = position.getAccY();
	log_data_pack.acc_z = position.getAccZ();

	log_data_pack.gyro_x = position.getGyroX();
	log_data_pack.gyro_y = position.getGyroY();
	log_data_pack.gyro_z = position.getGyroZ();

	log_data_pack.ahrs_x = position.getRoll();
	log_data_pack.ahrs_y = position.getPitch();
	log_data_pack.ahrs_z = position.getYaw();

	log_data_pack.leftSpeed = leftEncoder.getSpeed();
	log_data_pack.rightSpeed = rightEncoder.getSpeed();

	logDataPack();
}

void setup()
{
	Serial.begin(115200);

	SD.begin(4);

	initLogger();

	initDualEncoders();
	initMotors();

	pinMode(LEFT_SENSOR_PIN, INPUT);
	pinMode(RIGHT_SENSOR_PIN, INPUT);

	Wire.begin();
	Wire.setClock(400000);

	position.init();

	tiresContactInit(TIRE_LOST_OF_CONTACT_DEGREES);

	initFrontLifted(FRONT_LIFTED_THRESHOLD);
}

void serialCommand()
{
	static int left = 0;
	static int right = 0;

	if(Serial.available() == 0) return;

	char cmd = Serial.read();
	if(cmd == 'l')
	{
		left = 0;
		if(Serial.available() > 0)
		{
			int dir = 1;
			if(Serial.peek() == '-')
			{
				dir = -1;
				Serial.read();
			}
			while(Serial.available() > 0)
			{
				char digit = Serial.read();
				left = left * 10 + (digit - '0');
			}
			left *= dir;
		}

		setMotors(left, right);
	}
	else if(cmd == 'r')
	{
		right = 0;
		if(Serial.available() > 0)
		{
			int dir = 1;
			if(Serial.peek() == '-')
			{
				dir = -1;
				Serial.read();
			}
			while(Serial.available() > 0)
			{
				char digit = Serial.read();
				right = right * 10 + (digit - '0');
			}
			right *= dir;
		}

		setMotors(left, right);
	}
	else if(cmd == 'd')
	{
		dumpLog();
	}
}

void readProximitySensors(int& left, int& right)
{
	left = digitalRead(LEFT_SENSOR_PIN) ^ 1;
	right = digitalRead(RIGHT_SENSOR_PIN) ^ 1;
}

void getCommand()
{
	static int left = 0;
	static int right = 0;

	static int last_left = 0;
	static int last_right = 0;

	static int command_counter = 0;

	readProximitySensors(left, right);

	if(robot_state == WAITING_FOR_COMMAND)
	{
		if(right)
		{
			if(left < last_left)
			{
				++command_counter;
				Serial.print("Command counter: ");
				Serial.println(command_counter);
			}
		}
		else if(right < last_right)
		{
			if(left) command_counter = 42;

			switch(command_counter)
			{
				case 0:
					robot_state = PREPARE_TO_FIGHT;
					prepare_micros = micros();
					break;
				case 1:
					robot_state = RECALIBRATE;
					position.calibrate();
					plannarAcceleration.calibrate();
					robot_state = WAITING_FOR_COMMAND;
					break;
				case 2:
					robot_state = TEST;
					setMotors(80, 80);
					break;
			}

			command_counter = 0;
		}
	}
	else if(left && right)
	{
		if(robot_state == PREPARE_TO_FIGHT)
		{
			robot_state = WAITING_FOR_COMMAND;
			command_counter = 42;
		}
		else
		{
			robot_state = BRAINDEAD;
			setMotors(0, 0);
		}
	}

	last_left = left;
	last_right = right;
}

void loop()
{
	static uint32_t last_sample_micros = 0;
	static uint32_t last_log_micros = 0;
	static uint32_t last_blink_micros = 0;

	uint32_t current_micros = micros();

	{ // blink control
		uint32_t full_cycle;
		uint32_t high_cycle;

		if(robot_state == BRAINDEAD)
		{
			full_cycle = MICROS_PER_SECOND * 2;
			high_cycle = MICROS_PER_SECOND;
		}
		else if(robot_state == PREPARE_TO_FIGHT)
		{
			full_cycle = MICROS_PER_SECOND / 10;
			high_cycle = MICROS_PER_SECOND / 20;
		}
		else
		{
			full_cycle = MICROS_PER_SECOND / 2;
			high_cycle = MICROS_PER_SECOND / 3;
		}

		if(current_micros - last_blink_micros >= full_cycle)
		{
			digitalWrite(LED_PIN, HIGH);
			last_blink_micros = current_micros;
		}
		else if(current_micros - last_blink_micros >= high_cycle)
		{
			digitalWrite(LED_PIN, LOW);
		}
	}

	if(robot_state == BRAINDEAD)
	{
		setMotors(0, 0);
		return;
	}

	if(robot_state == PREPARE_TO_FIGHT)
	{
		if(current_micros - prepare_micros >= MICROS_PER_SECOND * 5)
		{
			robot_state = IN_COMBAT;
		}
	}

	// Read sensors
	if(current_micros - last_sample_micros >= MICROS_PER_SECOND / SAMPLE_FREQUENCY)
	{
		position.read_sensors();

		getCommand();

		last_sample_micros = current_micros;
	}

	// Log data
	if(current_micros - last_log_micros >= MICROS_PER_SECOND / LOG_FREQUENCY)
	{
		log_info();
		last_log_micros = current_micros;

		if(robot_state == TEST_MODE)
		{
			Serial.print(getLeftTireContactState()); Serial.print(" ");
			Serial.print(getRightTireContactState()); Serial.print(" ");
			Serial.print(getFrontLiftedState()); Serial.println("");
		}
	}

	serialCommand();
}
<commit_msg>Fix compile error<commit_after>#include "OrientationSensorsWrapper.h"
#include "SDLogDriver.h"
#include "DualEncoderDriver.h"
#include "MotorDriver.h"
#include "PlanarAccelerationModule.h"
#include "TireContactModule.h"
#include "FrontLiftedDetection.h"

#include "constants.h"

#include <Wire.h>
#include <SD.h>

enum {
	WAITING_FOR_COMMAND,
	PREPARE_TO_FIGHT,
	IN_COMBAT,
	RECALIBRATE,
	BRAINDEAD,
	TEST_MODE
} robot_state = WAITING_FOR_COMMAND;

uint32_t prepare_micros;

void log_info()
{
	log_data_pack.timestamp = millis();

	log_data_pack.acc_x = position.getAccX();
	log_data_pack.acc_y = position.getAccY();
	log_data_pack.acc_z = position.getAccZ();

	log_data_pack.gyro_x = position.getGyroX();
	log_data_pack.gyro_y = position.getGyroY();
	log_data_pack.gyro_z = position.getGyroZ();

	log_data_pack.ahrs_x = position.getRoll();
	log_data_pack.ahrs_y = position.getPitch();
	log_data_pack.ahrs_z = position.getYaw();

	log_data_pack.leftSpeed = leftEncoder.getSpeed();
	log_data_pack.rightSpeed = rightEncoder.getSpeed();

	logDataPack();
}

void setup()
{
	Serial.begin(115200);

	SD.begin(4);

	initLogger();

	initDualEncoders();
	initMotors();

	pinMode(LEFT_SENSOR_PIN, INPUT);
	pinMode(RIGHT_SENSOR_PIN, INPUT);

	Wire.begin();
	Wire.setClock(400000);

	position.init();

	tiresContactInit(TIRE_LOST_OF_CONTACT_DEGREES);

	initFrontLifted(FRONT_LIFTED_THRESHOLD);
}

void serialCommand()
{
	static int left = 0;
	static int right = 0;

	if(Serial.available() == 0) return;

	char cmd = Serial.read();
	if(cmd == 'l')
	{
		left = 0;
		if(Serial.available() > 0)
		{
			int dir = 1;
			if(Serial.peek() == '-')
			{
				dir = -1;
				Serial.read();
			}
			while(Serial.available() > 0)
			{
				char digit = Serial.read();
				left = left * 10 + (digit - '0');
			}
			left *= dir;
		}

		setMotors(left, right);
	}
	else if(cmd == 'r')
	{
		right = 0;
		if(Serial.available() > 0)
		{
			int dir = 1;
			if(Serial.peek() == '-')
			{
				dir = -1;
				Serial.read();
			}
			while(Serial.available() > 0)
			{
				char digit = Serial.read();
				right = right * 10 + (digit - '0');
			}
			right *= dir;
		}

		setMotors(left, right);
	}
	else if(cmd == 'd')
	{
		dumpLog();
	}
}

void readProximitySensors(int& left, int& right)
{
	left = digitalRead(LEFT_SENSOR_PIN) ^ 1;
	right = digitalRead(RIGHT_SENSOR_PIN) ^ 1;
}

void getCommand()
{
	static int left = 0;
	static int right = 0;

	static int last_left = 0;
	static int last_right = 0;

	static int command_counter = 0;

	readProximitySensors(left, right);

	if(robot_state == WAITING_FOR_COMMAND)
	{
		if(right)
		{
			if(left < last_left)
			{
				++command_counter;
				Serial.print("Command counter: ");
				Serial.println(command_counter);
			}
		}
		else if(right < last_right)
		{
			if(left) command_counter = 42;

			switch(command_counter)
			{
				case 0:
					robot_state = PREPARE_TO_FIGHT;
					prepare_micros = micros();
					break;
				case 1:
					robot_state = RECALIBRATE;
					position.calibrate();
					plannarAcceleration.calibrate();
					robot_state = WAITING_FOR_COMMAND;
					break;
				case 2:
					robot_state = TEST_MODE;
					setMotors(80, 80);
					break;
			}

			command_counter = 0;
		}
	}
	else if(left && right)
	{
		if(robot_state == PREPARE_TO_FIGHT)
		{
			robot_state = WAITING_FOR_COMMAND;
			command_counter = 42;
		}
		else
		{
			robot_state = BRAINDEAD;
			setMotors(0, 0);
		}
	}

	last_left = left;
	last_right = right;
}

void loop()
{
	static uint32_t last_sample_micros = 0;
	static uint32_t last_log_micros = 0;
	static uint32_t last_blink_micros = 0;

	uint32_t current_micros = micros();

	{ // blink control
		uint32_t full_cycle;
		uint32_t high_cycle;

		if(robot_state == BRAINDEAD)
		{
			full_cycle = MICROS_PER_SECOND * 2;
			high_cycle = MICROS_PER_SECOND;
		}
		else if(robot_state == PREPARE_TO_FIGHT)
		{
			full_cycle = MICROS_PER_SECOND / 10;
			high_cycle = MICROS_PER_SECOND / 20;
		}
		else
		{
			full_cycle = MICROS_PER_SECOND / 2;
			high_cycle = MICROS_PER_SECOND / 3;
		}

		if(current_micros - last_blink_micros >= full_cycle)
		{
			digitalWrite(LED_PIN, HIGH);
			last_blink_micros = current_micros;
		}
		else if(current_micros - last_blink_micros >= high_cycle)
		{
			digitalWrite(LED_PIN, LOW);
		}
	}

	if(robot_state == BRAINDEAD)
	{
		setMotors(0, 0);
		return;
	}

	if(robot_state == PREPARE_TO_FIGHT)
	{
		if(current_micros - prepare_micros >= MICROS_PER_SECOND * 5)
		{
			robot_state = IN_COMBAT;
		}
	}

	// Read sensors
	if(current_micros - last_sample_micros >= MICROS_PER_SECOND / SAMPLE_FREQUENCY)
	{
		position.read_sensors();

		getCommand();

		last_sample_micros = current_micros;
	}

	// Log data
	if(current_micros - last_log_micros >= MICROS_PER_SECOND / LOG_FREQUENCY)
	{
		log_info();
		last_log_micros = current_micros;

		if(robot_state == TEST_MODE)
		{
			Serial.print(getLeftTireContactState()); Serial.print(" ");
			Serial.print(getRightTireContactState()); Serial.print(" ");
			Serial.print(getFrontLiftedState()); Serial.println("");
		}
	}

	serialCommand();
}
<|endoftext|>


<commit_before>// SA:MP Profiler plugin
//
// Copyright (c) 2011 Zeex
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iterator>
#include <list>
#include <map>
#include <string>

#include "amxnamefinder.h"
#include "amxprofiler.h"
#include "jump.h"
#include "plugin.h"

extern void *pAMXFunctions;

// Symbolic info, used for getting function names
static std::map<AMX*, AMX_DBG> debugInfo;

// Both x86 and x86-64 are Little Endian...
static void *AMXAPI DummyAmxAlign(void *v) { return v; }

static uint32_t amx_Exec_addr;
static unsigned char amx_Exec_code[5];

static int AMXAPI Exec(AMX *amx, cell *retval, int index) {
    memcpy(reinterpret_cast<void*>(::amx_Exec_addr), ::amx_Exec_code, 5);

    int error = AMX_ERR_NONE;

    // Check if this script has a profiler attached to it
    AmxProfiler *prof = AmxProfiler::Get(amx);
    if (prof != 0) {
        error =  prof->Exec(retval, index);
    } else {
        error = amx_Exec(amx, retval, index);
    }

    SetJump(reinterpret_cast<void*>(::amx_Exec_addr), (void*)::Exec, ::amx_Exec_code);

    return error;
}

// Returns true if the .amx should be profiled
static bool WantsProfiler(const std::string &amxName) {
    std::ifstream config("plugins/profiler.cfg");

	std::istream_iterator<std::string> begin(config);
	std::istream_iterator<std::string> end;

	if (std::find(begin, end, amxName) != end) {
		return true;
	}

	return false;
}

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() {
    return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) {
	pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];

    // The server does not export amx_Align* for some reason.
    // They are used in amxdbg.c and amxaux.c, so they must be callable.
    ((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align16] = (void*)DummyAmxAlign; // amx_Align16
    ((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align32] = (void*)DummyAmxAlign; // amx_Align32
    ((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align64] = (void*)DummyAmxAlign; // amx_Align64

    // Hook amx_Exec
    ::amx_Exec_addr = reinterpret_cast<uint32_t>(((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Exec]);
    SetJump(reinterpret_cast<void*>(::amx_Exec_addr), (void*)::Exec, ::amx_Exec_code);

    // Add SA:MP default directories to the .amx finder sarch path
    AmxNameFinder *nameFinder = AmxNameFinder::GetInstance();
    nameFinder->AddSearchDir("gamemodes");
    nameFinder->AddSearchDir("filterscripts");
    nameFinder->UpdateCache();

    return true;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload() {
    return;
}

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx) {
	// Get the path to the loaded .amx
    AmxNameFinder *nameFinder = AmxNameFinder::GetInstance();
    nameFinder->UpdateCache();

    // If the name is established, load symbolic info
    std::string filename = nameFinder->GetAmxName(amx);
    if (!filename.empty()) {
        std::replace(filename.begin(), filename.end(), '\\', '/');
        if (WantsProfiler(filename)) {
            FILE *fp = fopen(filename.c_str(), "rb");
            if (fp != 0) {
                AMX_DBG amxdbg;
                int error = dbg_LoadInfo(&amxdbg, fp);
                if (error == AMX_ERR_NONE) {
                    AmxProfiler::Attach(amx, amxdbg);
                    ::debugInfo[amx] = amxdbg;
                    fclose(fp);
                    return AMX_ERR_NONE;
                }
                fclose(fp);
            }
        }
    }

    // No symbolic info loaded
    AmxProfiler::Attach(amx);
    return AMX_ERR_NONE;
}

PLUGIN_EXPORT int PLUGIN_CALL AmxUnload(AMX *amx) {
    // Get an instance of AmxProfiler attached to the unloading AMX
    AmxProfiler *prof = AmxProfiler::Get(amx);

    // Detach profiler
    if (prof != 0) {
        // Before doing that, print stats to <amx_file_path>.prof
        std::string name = AmxNameFinder::GetInstance()->GetAmxName(amx);
        if (!name.empty()) {
            prof->PrintStats(name + std::string(".prof"));
        }
        AmxProfiler::Detach(amx);
    }

    // Free debug info
    std::map<AMX*, AMX_DBG>::iterator it = ::debugInfo.find(amx);
    if (it != ::debugInfo.end()) {
        dbg_FreeInfo(&it->second);
        ::debugInfo.erase(it);
    }

    return AMX_ERR_NONE;
}
<commit_msg>Print plugin version on startup<commit_after>// SA:MP Profiler plugin
//
// Copyright (c) 2011 Zeex
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iterator>
#include <list>
#include <map>
#include <string>

#include "amxnamefinder.h"
#include "amxprofiler.h"
#include "jump.h"
#include "plugin.h"
#include "version.h"

typedef void (*logprintf_t)(const char *format, ...);
static logprintf_t logprintf;

extern void *pAMXFunctions;

// Symbolic info, used for getting function names
static std::map<AMX*, AMX_DBG> debugInfo;

// Both x86 and x86-64 are Little Endian...
static void *AMXAPI DummyAmxAlign(void *v) { return v; }

static uint32_t amx_Exec_addr;
static unsigned char amx_Exec_code[5];

static int AMXAPI Exec(AMX *amx, cell *retval, int index) {
    memcpy(reinterpret_cast<void*>(::amx_Exec_addr), ::amx_Exec_code, 5);

    int error = AMX_ERR_NONE;

    // Check if this script has a profiler attached to it
    AmxProfiler *prof = AmxProfiler::Get(amx);
    if (prof != 0) {
        error =  prof->Exec(retval, index);
    } else {
        error = amx_Exec(amx, retval, index);
    }

    SetJump(reinterpret_cast<void*>(::amx_Exec_addr), (void*)::Exec, ::amx_Exec_code);

    return error;
}

// Returns true if the .amx should be profiled
static bool WantsProfiler(const std::string &amxName) {
    std::ifstream config("plugins/profiler.cfg");

	std::istream_iterator<std::string> begin(config);
	std::istream_iterator<std::string> end;

	if (std::find(begin, end, amxName) != end) {
		return true;
	}

	return false;
}

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() {
    return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) {
	pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];
	logprintf = (logprintf_t)ppData[PLUGIN_DATA_LOGPRINTF];

    // The server does not export amx_Align* for some reason.
    // They are used in amxdbg.c and amxaux.c, so they must be callable.
    ((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align16] = (void*)DummyAmxAlign; // amx_Align16
    ((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align32] = (void*)DummyAmxAlign; // amx_Align32
    ((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Align64] = (void*)DummyAmxAlign; // amx_Align64

    // Hook amx_Exec
    ::amx_Exec_addr = reinterpret_cast<uint32_t>(((void**)pAMXFunctions)[PLUGIN_AMX_EXPORT_Exec]);
    SetJump(reinterpret_cast<void*>(::amx_Exec_addr), (void*)::Exec, ::amx_Exec_code);

    // Add SA:MP default directories to the .amx finder sarch path
    AmxNameFinder *nameFinder = AmxNameFinder::GetInstance();
    nameFinder->AddSearchDir("gamemodes");
    nameFinder->AddSearchDir("filterscripts");
    nameFinder->UpdateCache();

	logprintf("  Profiler plugin v" VERSION " is OK.");

    return true;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload() {
    return;
}

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx) {
	// Get the path to the loaded .amx
    AmxNameFinder *nameFinder = AmxNameFinder::GetInstance();
    nameFinder->UpdateCache();

    // If the name is established, load symbolic info
    std::string filename = nameFinder->GetAmxName(amx);
    if (!filename.empty()) {
        std::replace(filename.begin(), filename.end(), '\\', '/');
        if (WantsProfiler(filename)) {
            FILE *fp = fopen(filename.c_str(), "rb");
            if (fp != 0) {
                AMX_DBG amxdbg;
                int error = dbg_LoadInfo(&amxdbg, fp);
                if (error == AMX_ERR_NONE) {
                    AmxProfiler::Attach(amx, amxdbg);
                    ::debugInfo[amx] = amxdbg;
                    fclose(fp);
                    return AMX_ERR_NONE;
                }
                fclose(fp);
            }
        }
    }

    // No symbolic info loaded
    AmxProfiler::Attach(amx);
    return AMX_ERR_NONE;
}

PLUGIN_EXPORT int PLUGIN_CALL AmxUnload(AMX *amx) {
    // Get an instance of AmxProfiler attached to the unloading AMX
    AmxProfiler *prof = AmxProfiler::Get(amx);

    // Detach profiler
    if (prof != 0) {
        // Before doing that, print stats to <amx_file_path>.prof
        std::string name = AmxNameFinder::GetInstance()->GetAmxName(amx);
        if (!name.empty()) {
            prof->PrintStats(name + std::string(".prof"));
        }
        AmxProfiler::Detach(amx);
    }

    // Free debug info
    std::map<AMX*, AMX_DBG>::iterator it = ::debugInfo.find(amx);
    if (it != ::debugInfo.end()) {
        dbg_FreeInfo(&it->second);
        ::debugInfo.erase(it);
    }

    return AMX_ERR_NONE;
}
<|endoftext|>