v2.6 +multi-threading

This commit is contained in:
alex
2015-06-09 19:54:38 +01:00
parent 2364bbf6b9
commit 523cb1e736
10 changed files with 309 additions and 230 deletions

View File

@@ -1,5 +1,11 @@
SIGNAL SERVER CHANGELOG
2.6 - 9 June 2015
Multithreading support added by Michael Ramnarine
PlotPropagation() and PlotLOSMap() use four threads by default
Feature can be disabled with -nothreads flag
Static and global variables have been made threadsafe
2.5 - 27 May 2015
Code refactored by Andrew Clayton / ac000 with header files
New Makefile with c / c++ multi mode compilation

View File

@@ -4,7 +4,7 @@ CC = gcc
CXX = g++
CFLAGS = -Wall -O3 -s -ffast-amth
CXXFLAGS = -Wall -O3 -s -ffast-math
LIBS = -lm
LIBS = -lm -lpthread
VPATH = models
objects = main.o cost.o ecc33.o ericsson.o fspl.o hata.o itwom3.0.o \

View File

@@ -20,7 +20,7 @@
* *
\****************************************************************************/
-- Signal Server 2.5 --
-- Signal Server 2.6 --
Compiled for 64 tiles at 1200 pixels/degree
-d Directory containing .sdf tiles
@@ -52,4 +52,6 @@
-ked Knife edge diffraction (Default for ITM)
-ng Normalise Path Profile graph
-haf Halve 1 or 2 (optional)
-nothreads Turn off threaded processing (optional)

View File

@@ -98,7 +98,7 @@ extern double clutter;
extern double dBm;
extern double loss;
extern double field_strength;
extern double *elev;
extern __thread double *elev;
extern char string[];
extern char sdf_path[];
@@ -110,7 +110,7 @@ extern unsigned char metric;
extern unsigned char dbm;
extern struct dem *dem;
extern struct path path;
extern __thread struct path path;
extern struct LR LR;
extern struct region region;

37
main.cc
View File

@@ -1,4 +1,4 @@
double version = 2.5;
double version = 2.6;
/****************************************************************************\
* Signal Server: Server optimised SPLAT! by Alex Farrant *
******************************************************************************
@@ -53,11 +53,11 @@ int min_north = 90, max_north = -90, min_west = 360, max_west = -1, ippd, mpi,
unsigned char got_elevation_pattern, got_azimuth_pattern, metric = 0, dbm = 0;
double *elev;
__thread double *elev;
__thread struct path path;
struct site tx_site[2];
struct dem *dem;
struct path path;
struct LR LR;
struct region region;
@@ -939,7 +939,11 @@ static void free_dem(void)
delete [] dem;
}
static void free_path(void)
void free_elev(void) {
delete [] elev;
}
void free_path(void)
{
delete [] path.lat;
delete [] path.lon;
@@ -947,6 +951,11 @@ static void free_path(void)
delete [] path.distance;
}
void alloc_elev(void)
{
elev = new double[ARRAYSIZE + 10];
}
static void alloc_dem(void)
{
int i;
@@ -965,7 +974,7 @@ static void alloc_dem(void)
}
}
static void alloc_path(void)
void alloc_path(void)
{
path.lat = new double[ARRAYSIZE];
path.lon = new double[ARRAYSIZE];
@@ -980,6 +989,8 @@ int main(int argc, char *argv[])
nortRxHin, nortRxHax, propmodel, winfiles, knifeedge = 0, ppa =
0, normalise = 0, haf = 0, pmenv = 1;
bool use_threads = true;
unsigned char LRmap = 0, txsites = 0, topomap = 0, geo = 0, kml =
0, area_mode = 0, max_txsites, ngs = 0;
@@ -1047,6 +1058,7 @@ int main(int argc, char *argv[])
" -ked Knife edge diffraction (Default for ITM)\n");
fprintf(stdout, " -ng Normalise Path Profile graph\n");
fprintf(stdout, " -haf Halve 1 or 2 (optional)\n");
fprintf(stdout, " -nothreads Turn off threaded processing (optional)\n");
fflush(stdout);
@@ -1057,7 +1069,7 @@ int main(int argc, char *argv[])
* Now we know what mode we are running in, we can allocate various
* data structures.
*/
elev = new double[ARRAYSIZE + 10];
alloc_elev();
alloc_dem();
alloc_path();
@@ -1422,6 +1434,11 @@ int main(int argc, char *argv[])
}
}
//Disable threads
if (strcmp(argv[x], "-nothreads") == 0) {
z = x + 1;
use_threads = false;
}
}
/* ERROR DETECTION */
@@ -1639,12 +1656,12 @@ int main(int argc, char *argv[])
if (ppa == 0) {
if (propmodel == 2) {
PlotLOSMap(tx_site[0], altitudeLR, ano_filename);
PlotLOSMap(tx_site[0], altitudeLR, ano_filename, use_threads);
DoLOS(mapfile, geo, kml, ngs, tx_site, txsites);
} else {
// 90% of effort here
PlotPropagation(tx_site[0], altitudeLR, ano_filename,
propmodel, knifeedge, haf, pmenv);
propmodel, knifeedge, haf, pmenv, use_threads);
// Near field bugfix
PutSignal(tx_site[0].lat, tx_site[0].lon, hottest);
@@ -1683,7 +1700,7 @@ int main(int argc, char *argv[])
}
fflush(stdout);
delete [] elev;
free_elev();
free_dem();
free_path();

View File

@@ -23,4 +23,9 @@ double ReadBearing(char *input);
void ObstructionAnalysis(struct site xmtr, struct site rcvr, double f,
FILE *outfile);
void free_elev(void);
void free_path(void);
void alloc_elev(void);
void alloc_path(void);
#endif /* _MAIN_HH_ */

View File

@@ -451,7 +451,7 @@ double saalos(double d, prop_type & prop, propa_type & propa)
double adiff(double d, prop_type & prop, propa_type & propa)
{
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
static double wd1, xd1, afo, qk, aht, xht;
static __thread double wd1, xd1, afo, qk, aht, xht;
double a, q, pk, ds, th, wa, ar, wd, adiffv;
if (d == 0) {
@@ -513,7 +513,7 @@ double adiff(double d, prop_type & prop, propa_type & propa)
double adiff2(double d, prop_type & prop, propa_type & propa)
{
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
static double wd1, xd1, qk, aht, xht, toh, toho, roh, roho, dto, dto1,
static __thread double wd1, xd1, qk, aht, xht, toh, toho, roh, roho, dto, dto1,
dtro, dro, dro2, drto, dtr, dhh1, dhh2, /* dhec, */ dtof, dto1f,
drof, dro2f;
double a, q, pk, rd, ds, dsl, /* dfdh, */ th, wa, /* ar, wd, sf1, */
@@ -829,7 +829,7 @@ double adiff2(double d, prop_type & prop, propa_type & propa)
double ascat(double d, prop_type & prop, propa_type & propa)
{
static double ad, rr, etq, h0s;
static __thread double ad, rr, etq, h0s;
double h0, r1, r2, z0, ss, et, ett, th, q;
double ascatv, temp;
@@ -954,7 +954,7 @@ void qlrps(double fmhz, double zsys, double en0, int ipol, double eps,
double alos(double d, prop_type & prop, propa_type & propa)
{
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
static double wls;
static __thread double wls;
complex < double >r;
double s, sps, q;
double alosv;
@@ -1146,8 +1146,8 @@ void qlra(int kst[], int klimx, int mdvarx, prop_type & prop,
void lrprop(double d, prop_type & prop, propa_type & propa)
{
/* PaulM_lrprop used for ITM */
static bool wlos, wscat;
static double dmin, xae;
static __thread bool wlos, wscat;
static __thread double dmin, xae;
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
double a0, a1, a2, a3, a4, a5, a6;
double d0, d1, d2, d3, d4, d5, d6;
@@ -1337,8 +1337,8 @@ void lrprop(double d, prop_type & prop, propa_type & propa)
void lrprop2(double d, prop_type & prop, propa_type & propa)
{
/* ITWOM_lrprop2 */
static bool wlos, wscat;
static double dmin, xae;
static __thread bool wlos, wscat;
static __thread double dmin, xae;
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
double pd1;
double a0, a1, a2, a3, a4, a5, a6, iw;
@@ -1612,8 +1612,8 @@ double curve(double const &c1, double const &c2, double const &x1,
double avar(double zzt, double zzl, double zzc, prop_type & prop,
propv_type & propv)
{
static int kdv;
static double dexa, de, vmd, vs0, sgl, sgtm, sgtp, sgtd, tgtd,
static __thread int kdv;
static __thread double dexa, de, vmd, vs0, sgl, sgtm, sgtp, sgtd, tgtd,
gm, gp, cv1, cv2, yv1, yv2, yv3, csm1, csm2, ysm1, ysm2,
ysm3, csp1, csp2, ysp1, ysp2, ysp3, csd1, zd, cfm1, cfm2,
cfm3, cfp1, cfp2, cfp3;
@@ -1650,7 +1650,7 @@ double avar(double zzt, double zzl, double zzc, prop_type & prop,
double bfp1[7] = { 1.0, 0.93, 1.0, 0.93, 0.93, 1.0, 1.0 };
double bfp2[7] = { 0.0, 0.31, 0.0, 0.19, 0.31, 0.0, 0.0 };
double bfp3[7] = { 0.0, 2.00, 0.0, 1.79, 2.00, 0.0, 0.0 };
static bool ws, w1;
static __thread bool ws, w1;
double rt = 7.8, rl = 24.0, avarv, q, vs, zt, zl, zc;
double sgt, yr, temp1, temp2;
int temp_klim = propv.klim - 1;
@@ -1974,6 +1974,7 @@ void z1sq1(double z[], const double &x1, const double &x2, double &z0,
xa = xb - xa;
x = -0.5 * xa;
xb += x;
a = 0.5 * (z[ja + 2] + z[jb + 2]);
b = 0.5 * (z[ja + 2] - z[jb + 2]) * x;

View File

@@ -1,8 +1,8 @@
#include <stdio.h>
#include <math.h>
#include "../common.h"
#include "../main.hh"
#include "los.hh"
#include "cost.hh"
#include "ecc33.hh"
#include "ericsson.hh"
@@ -10,6 +10,154 @@
#include "hata.hh"
#include "itwom3.0.hh"
#include "sui.hh"
#include <pthread.h>
#define MAXPAGES 64
#define IPPD 3600
#define NUM_SECTIONS 4
namespace {
pthread_t threads[NUM_SECTIONS];
unsigned int thread_count = 0;
pthread_mutex_t maskMutex;
bool processed[MAXPAGES][IPPD][IPPD];
bool has_init_processed = false;
struct propagationRange {
int min_west, max_west, min_north, max_north;
double altitude;
bool eastwest, los, use_threads;
site source;
unsigned char mask_value;
FILE *fd;
int propmodel, knifeedge, pmenv;
};
void* rangePropagation(void *parameters)
{
propagationRange *v = (propagationRange*)parameters;
if(v->use_threads) {
alloc_elev();
alloc_path();
}
double minwest = dpp + (double)v->min_west;
double lon = v->eastwest ? minwest : v->min_west;
double lat = v->min_north;
int y = 0;
do {
if (lon >= 360.0)
lon -= 360.0;
site edge;
edge.lat = lat;
edge.lon = lon;
edge.alt = v->altitude;
if(v->los)
PlotLOSPath(v->source, edge, v->mask_value, v->fd);
else
PlotPropPath(v->source, edge, v->mask_value, v->fd, v->propmodel,
v->knifeedge, v->pmenv);
++y;
if(v->eastwest)
lon = minwest + (dpp * (double)y);
else
lat = (double)v->min_north + (dpp * (double)y);
} while ( v->eastwest
? (LonDiff(lon, (double)v->max_west) <= 0.0)
: (lat < (double)v->max_north) );
if(v->use_threads) {
free_elev();
free_path();
}
return NULL;
}
void init_processed()
{
for(int i = 0; i < MAXPAGES; i++) {
for (int x = 0; x < ippd; x++) {
for (int y = 0; y < ippd; y++) {
processed[i][x][y] = false;
}
}
}
}
bool can_process(double lat, double lon)
{
/* Lines, text, markings, and coverage areas are stored in a
mask that is combined with topology data when topographic
maps are generated by ss. This function sets bits in
the mask based on the latitude and longitude of the area
pointed to. */
int x, y, indx;
char found;
bool rtn = false;
for (indx = 0, found = 0; indx < MAXPAGES && found == 0;) {
x = (int)rint(ppd * (lat - dem[indx].min_north));
y = mpi - (int)rint(ppd * (LonDiff(dem[indx].max_west, lon)));
if (x >= 0 && x <= mpi && y >= 0 && y <= mpi)
found = 1;
else
indx++;
}
if (found) {
/* As long as we only set this without resetting it we can
check outside a mutex first without worrying about race
conditions. But we must lock the mutex before updating the
value. */
if(!processed[indx][x][y]) {
pthread_mutex_lock(&maskMutex);
if(!processed[indx][x][y]) {
rtn = true;
processed[indx][x][y] = true;
}
pthread_mutex_unlock (&maskMutex);
}
}
return rtn;
}
void beginThread(void *arg)
{
if(!has_init_processed)
init_processed();
int rc = pthread_create(&threads[thread_count], NULL, rangePropagation, arg);
if (rc)
printf("ERROR; return code from pthread_create() is %d\n", rc);
else
++thread_count;
}
void finishThreads()
{
void* status;
for(unsigned int i=0; i<thread_count; i++) {
int rc = pthread_join(threads[i], &status);
if (rc)
printf("ERROR; return code from pthread_join() is %d\n", rc);
}
thread_count = 0;
}
}
/*
* Acute Angle from Rx point to an obstacle of height (opp) and
@@ -89,7 +237,9 @@ void PlotLOSPath(struct site source, struct site destination, char mask_value,
/* Test this point only if it hasn't been already
tested and found to be free of obstructions. */
if ((GetMask(path.lat[y], path.lon[y]) & mask_value) == 0) {
if ((GetMask(path.lat[y], path.lon[y]) & mask_value) == 0
&& can_process(path.lat[y], path.lon[y])) {
distance = 5280.0 * path.distance[y];
tx_alt = earthradius + source.alt + path.elevation[0];
rx_alt =
@@ -183,8 +333,12 @@ void PlotPropPath(struct site source, struct site destination,
/* Process this point only if it
has not already been processed. */
if ((GetMask(path.lat[y], path.lon[y]) & 248) !=
(mask_value << 3)) {
if ( (GetMask(path.lat[y], path.lon[y]) & 248) !=
(mask_value << 3) && can_process(path.lat[y], path.lon[y])) {
char fd_buffer[64];
int buffer_offset = 0;
distance = 5280.0 * path.distance[y];
xmtr_alt =
four_thirds_earth + source.alt + path.elevation[0];
@@ -337,6 +491,7 @@ void PlotPropPath(struct site source, struct site destination,
destination.alt *
METERS_PER_FOOT, LR.eps_dielect,
LR.sgm_conductivity,
LR.eno_ns_surfref, LR.frq_mhz,
LR.radio_climate, LR.pol,
LR.conf, LR.rel, loss, strmode,
@@ -379,7 +534,8 @@ void PlotPropPath(struct site source, struct site destination,
azimuth = (Azimuth(source, temp));
if (fd != NULL)
fprintf(fd, "%.7f, %.7f, %.3f, %.3f, ",
buffer_offset += sprintf(fd_buffer+buffer_offset,
"%.7f, %.7f, %.3f, %.3f, ",
path.lat[y], path.lon[y], azimuth,
elevation);
@@ -388,7 +544,8 @@ void PlotPropPath(struct site source, struct site destination,
or received power level (below), as appropriate. */
if (fd != NULL && LR.erp == 0.0)
fprintf(fd, "%.2f", loss);
buffer_offset += sprintf(fd_buffer+buffer_offset,
"%.2f", loss);
/* Integrate the antenna's radiation
pattern into the overall path loss. */
@@ -418,7 +575,8 @@ void PlotPropPath(struct site source, struct site destination,
dBm = 10.0 * (log10(rxp * 1000.0));
if (fd != NULL)
fprintf(fd, "%.3f", dBm);
buffer_offset += sprintf(fd_buffer+buffer_offset,
"%.3f", dBm);
/* Scale roughly between 0 and 255 */
@@ -466,7 +624,8 @@ void PlotPropPath(struct site source, struct site destination,
(unsigned char)ifs);
if (fd != NULL)
fprintf(fd, "%.3f",
buffer_offset += sprintf(fd_buffer+buffer_offset,
"%.3f",
field_strength);
}
}
@@ -488,9 +647,9 @@ void PlotPropPath(struct site source, struct site destination,
if (fd != NULL) {
if (block)
fprintf(fd, " *");
fprintf(fd, "\n");
buffer_offset += sprintf(fd_buffer+buffer_offset,
" *");
fprintf(fd, "%s\n", fd_buffer);
}
/* Mark this point as having been analyzed */
@@ -503,7 +662,8 @@ void PlotPropPath(struct site source, struct site destination,
}
void PlotLOSMap(struct site source, double altitude, char *plo_filename)
void PlotLOSMap(struct site source, double altitude, char *plo_filename,
bool use_threads)
{
/* This function performs a 360 degree sweep around the
transmitter site (source location), and plots the
@@ -514,10 +674,7 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
of a topographic map when the WritePPM() function
is later invoked. */
int x, y, z;
struct site edge;
double lat, lon, minwest, maxnorth, th;
static unsigned char mask_value = 1;
static __thread unsigned char mask_value = 1;
FILE *fd = NULL;
if (plo_filename[0] != 0)
@@ -529,64 +686,44 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
max_west, min_west, max_north, min_north);
}
th = ppd / loops;
// Four sections start here
// Process north edge east/west, east edge north/south,
// south edge east/west, west edge north/south
int range_min_west[] = {min_west, min_west, min_west, max_west};
int range_min_north[] = {max_north, min_north, min_north, min_north};
int range_max_west[] = {max_west, min_west, max_west, max_west};
int range_max_north[] = {max_north, max_north, min_north, max_north};
propagationRange* r[NUM_SECTIONS];
z = (int)(th * ReduceAngle(max_west - min_west));
for(int i = 0; i < NUM_SECTIONS; ++i) {
propagationRange *range = new propagationRange;
r[i] = range;
range->los = true;
minwest = dpp + (double)min_west;
maxnorth = (double)max_north - dpp;
range->eastwest = (range_min_west[i] == range_max_west[i] ? false : true);
range->min_west = range_min_west[i];
range->max_west = range_max_west[i];
range->min_north = range_min_north[i];
range->max_north = range_max_north[i];
for (lon = minwest, x = 0, y = 0;
(LonDiff(lon, (double)max_west) <= 0.0);
y++, lon = minwest + (dpp * (double)y)) {
if (lon >= 360.0)
lon -= 360.0;
range->use_threads = use_threads;
range->altitude = altitude;
range->source = source;
range->mask_value = mask_value;
range->fd = fd;
edge.lat = max_north;
edge.lon = lon;
edge.alt = altitude;
PlotLOSPath(source, edge, mask_value, fd);
}
z = (int)(th * (double)(max_north - min_north));
for (lat = maxnorth, x = 0, y = 0; lat >= (double)min_north;
y++, lat = maxnorth - (dpp * (double)y)) {
edge.lat = lat;
edge.lon = min_west;
edge.alt = altitude;
PlotLOSPath(source, edge, mask_value, fd);
if(use_threads)
beginThread(range);
else
rangePropagation(range);
}
z = (int)(th * ReduceAngle(max_west - min_west));
for (lon = minwest, x = 0, y = 0;
(LonDiff(lon, (double)max_west) <= 0.0);
y++, lon = minwest + (dpp * (double)y)) {
if (lon >= 360.0)
lon -= 360.0;
edge.lat = min_north;
edge.lon = lon;
edge.alt = altitude;
PlotLOSPath(source, edge, mask_value, fd);
}
z = (int)(th * (double)(max_north - min_north));
for (lat = (double)min_north, x = 0, y = 0; lat < (double)max_north;
y++, lat = (double)min_north + (dpp * (double)y)) {
edge.lat = lat;
edge.lon = max_west;
edge.alt = altitude;
PlotLOSPath(source, edge, mask_value, fd);
if(use_threads)
finishThreads();
for(int i = 0; i < NUM_SECTIONS; ++i){
delete r[i];
}
switch (mask_value) {
@@ -603,21 +740,14 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
}
}
void PlotPropagation(struct site source, double altitude, char *plo_filename,
int propmodel, int knifeedge, int haf, int pmenv)
int propmodel, int knifeedge, int haf, int pmenv, bool
use_threads)
{
int y, z, count;
struct site edge;
double lat, lon, minwest, maxnorth, th;
unsigned char x;
static unsigned char mask_value = 1;
static __thread unsigned char mask_value = 1;
FILE *fd = NULL;
minwest = dpp + (double)min_west;
maxnorth = (double)max_north - dpp;
count = 0;
if (LR.erp == 0.0 && debug)
fprintf(stdout, "path loss");
else {
@@ -657,137 +787,55 @@ void PlotPropagation(struct site source, double altitude, char *plo_filename,
max_west, min_west, max_north, min_north);
}
th = ppd / loops;
// Four sections start here
// Process north edge east/west, east edge north/south,
// south edge east/west, west edge north/south
int range_min_west[] = {min_west, min_west, min_west, max_west};
int range_min_north[] = {max_north, min_north, min_north, min_north};
int range_max_west[] = {max_west, min_west, max_west, max_west};
int range_max_north[] = {max_north, max_north, min_north, max_north};
propagationRange* r[NUM_SECTIONS];
//S1
if (haf == 0 || haf == 1) {
z = (int)(th * ReduceAngle(max_west - min_west));
for(int i = 0; i < NUM_SECTIONS; ++i) {
propagationRange *range = new propagationRange;
r[i] = range;
range->los = false;
for (lon = minwest, x = 0, y = 0;
(LonDiff(lon, (double)max_west) <= 0.0);
y++, lon = minwest + (dpp * (double)y)) {
if (lon >= 360.0)
lon -= 360.0;
// Only process correct half
if((NUM_SECTIONS - i) <= (NUM_SECTIONS / 2) && haf == 1)
continue;
if((NUM_SECTIONS - i) > (NUM_SECTIONS / 2) && haf == 2)
continue;
edge.lat = max_north;
edge.lon = lon;
edge.alt = altitude;
PlotPropPath(source, edge, mask_value, fd, propmodel,
knifeedge, pmenv);
count++;
range->eastwest = (range_min_west[i] == range_max_west[i] ? false : true);
range->min_west = range_min_west[i];
range->max_west = range_max_west[i];
range->min_north = range_min_north[i];
range->max_north = range_max_north[i];
if (count == z) {
count = 0;
range->use_threads = use_threads;
range->altitude = altitude;
range->source = source;
range->mask_value = mask_value;
range->fd = fd;
range->propmodel = propmodel;
range->knifeedge = knifeedge;
range->pmenv = pmenv;
if (x == 3)
x = 0;
if(use_threads)
beginThread(range);
else
x++;
}
}
}
//S2
if (haf == 0 || haf == 1) {
count = 0;
if (debug) {
fprintf(stdout, "\n25%c to 50%c ", 37, 37);
fflush(stdout);
}
z = (int)(th * (double)(max_north - min_north));
for (lat = maxnorth, x = 0, y = 0; lat >= (double)min_north;
y++, lat = maxnorth - (dpp * (double)y)) {
edge.lat = lat;
edge.lon = min_west;
edge.alt = altitude;
PlotPropPath(source, edge, mask_value, fd, propmodel,
knifeedge, pmenv);
count++;
if (count == z) {
count = 0;
if (x == 3)
x = 0;
else
x++;
}
}
}
//S3
if (haf == 0 || haf == 2) {
count = 0;
if (debug) {
fprintf(stdout, "\n50%c to 75%c ", 37, 37);
fflush(stdout);
}
z = (int)(th * ReduceAngle(max_west - min_west));
for (lon = minwest, x = 0, y = 0;
(LonDiff(lon, (double)max_west) <= 0.0);
y++, lon = minwest + (dpp * (double)y)) {
if (lon >= 360.0)
lon -= 360.0;
edge.lat = min_north;
edge.lon = lon;
edge.alt = altitude;
PlotPropPath(source, edge, mask_value, fd, propmodel,
knifeedge, pmenv);
count++;
if (count == z) {
count = 0;
if (x == 3)
x = 0;
else
x++;
}
rangePropagation(range);
}
if(use_threads)
finishThreads();
for(int i = 0; i < NUM_SECTIONS; ++i){
delete r[i];
}
//S4
if (haf == 0 || haf == 2) {
count = 0;
if (debug) {
fprintf(stdout, "\n75%c to 100%c ", 37, 37);
fflush(stdout);
}
z = (int)(th * (double)(max_north - min_north));
for (lat = (double)min_north, x = 0, y = 0;
lat < (double)max_north;
y++, lat = (double)min_north + (dpp * (double)y)) {
edge.lat = lat;
edge.lon = max_west;
edge.alt = altitude;
PlotPropPath(source, edge, mask_value, fd, propmodel,
knifeedge, pmenv);
count++;
if (count == z) {
count = 0;
if (x == 3)
x = 0;
else
x++;
}
}
} //S4
if (fd != NULL)
fclose(fd);

View File

@@ -10,9 +10,9 @@ void PlotLOSPath(struct site source, struct site destination, char mask_value,
void PlotPropPath(struct site source, struct site destination,
unsigned char mask_value, FILE * fd, int propmodel,
int knifeedge, int pmenv);
void PlotLOSMap(struct site source, double altitude, char *plo_filename);
void PlotLOSMap(struct site source, double altitude, char *plo_filename, bool use_threads);
void PlotPropagation(struct site source, double altitude, char *plo_filename,
int propmodel, int knifeedge, int haf, int pmenv);
int propmodel, int knifeedge, int haf, int pmenv, bool use_threads);
void PlotPath(struct site source, struct site destination, char mask_value);
#endif /* _LOS_HH_ */

View File

@@ -1,6 +1,6 @@
#!/bin/bash
œ#!/bin/bash
mkdir test
RAD=5
RAD=10
MAXRAD=30
FRQ=800
ERP=20
@@ -17,7 +17,7 @@ while [ $RAD -lt $MAXRAD ]; do
convert test/$RAD.hd.ppm test/$RAD.hd.png
rm test/$RAD.hd.ppm
rm test/$RAD.*cf
let RAD=RAD+5
let RAD=RAD+10
done