From 2e68afd84ce1a282b5c14247e1fed3902f2a93b4 Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 18 Feb 2020 15:37:41 -0800 Subject: [PATCH] removed threading holdovers from dump1090. started working on android build (not working yet). map drawing now resumes next frame if frame times out Former-commit-id: 8c281d95e55d2b260a70c9a9232d68ae5917d96b [formerly 9c5d89f2af4f235ccb5cd7b983443d63907ba6ad] [formerly 4271671e19b70a7333649bb93bff920d1fa1acd0] Former-commit-id: 77f53ebfdb727dd7cbc2550443e08504e4aa624b Former-commit-id: a2daaa44daa2d42eb36f4e93f92e2f4db4000bbf --- Android.mk | 39 ++ Application.mk | 3 + Makefile | 6 +- draw.c | 42 +- draw.o.REMOVED.git-id | 2 +- dump1090.c | 904 ------------------------ font.o | Bin 37800 -> 37856 bytes init.c | 2 + init.o | Bin 48344 -> 48464 bytes input.o.REMOVED.git-id | 2 +- interactive.c | 103 ++- interactive.o | Bin 46136 -> 44376 bytes list.o | Bin 48296 -> 48344 bytes monokai.o | Bin 27792 -> 27848 bytes planeObj.o | Bin 44336 -> 44392 bytes pthreads/pthread.h | 1368 ------------------------------------- pthreads/sched.h | 183 ----- pthreads/semaphore.h | 169 ----- status.o.REMOVED.git-id | 2 +- structs.h | 1 + view1090.REMOVED.git-id | 2 +- view1090.c | 6 +- view1090.o.REMOVED.git-id | 2 +- 23 files changed, 161 insertions(+), 2675 deletions(-) create mode 100644 Android.mk create mode 100644 Application.mk delete mode 100644 dump1090.c delete mode 100644 pthreads/pthread.h delete mode 100644 pthreads/sched.h delete mode 100644 pthreads/semaphore.h diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..3987d7c --- /dev/null +++ b/Android.mk @@ -0,0 +1,39 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := main.out + +SDL_PATH := ~/Downloads/SDL + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/$(SDL_PATH)/include \ + $(LOCAL_PATH)/$(SDL_PATH) + +#LOCALCFLAGS= + +LOCAL_SRC_FILES := \ + $(SDL_PATH)/src/main/android/SDL_android_main.cpp \ + allstates.c \ + input.c \ + mapdata.c \ + monokai.c \ + planeObj.c \ + anet.c \ + font.c \ + interactive.c \ + mode_ac.c \ + net_io.c \ + status.c \ + draw.c \ + init.c \ + list.c \ + mode_s.c \ + parula.c \ + view1090.c + +LOCAL_SHARED_LIBRARIES := SDL2 SDL2_gfx SDL2_ttf + +LOCAL_LDLIBS := -lGLESv1_CM #-lstdc++ + +include $(BUILD_EXECUTABLE) \ No newline at end of file diff --git a/Application.mk b/Application.mk new file mode 100644 index 0000000..0f73767 --- /dev/null +++ b/Application.mk @@ -0,0 +1,3 @@ +APP_ABI := arm64-v8a +APP_PLATFORM := android-29 +APP_BUILD_SCRIPT := Android.mk \ No newline at end of file diff --git a/Makefile b/Makefile index 21e5a7e..cb47954 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # When building a package or installing otherwise in the system, make # sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local # -PROGNAME=dump1090 +PROGNAME=view1090 ifdef PREFIX BINDIR=$(PREFIX)/bin @@ -10,8 +10,8 @@ SHAREDIR=$(PREFIX)/share/$(PROGNAME) EXTRACFLAGS=-DHTMLPATH=\"$(SHAREDIR)\" endif -CFLAGS=-O2 -g -Wall -W `pkg-config --cflags librtlsdr` -LIBS=`pkg-config --libs librtlsdr` -lpthread -lm -lSDL2 -lSDL2_ttf -lSDL2_gfx +CFLAGS=-O2 -g -Wall -W +LIBS=-lm -lSDL2 -lSDL2_ttf -lSDL2_gfx CC=gcc all: view1090 diff --git a/draw.c b/draw.c index c7e6803..5c4f38f 100644 --- a/draw.c +++ b/draw.c @@ -343,6 +343,9 @@ void drawTrail(double *oldDx, double *oldDy, double *oldHeading, time_t * oldSee //tick marks + age = 1.0 - (double) 4.0 * (now - oldSeen[currentIdx]) / TRAIL_TTL; + colorVal = (uint8_t)floor(255.0 * age); + double vec[3]; vec[0] = sin(oldHeading[currentIdx] * M_PI / 180); vec[1] = -cos(oldHeading[currentIdx] * M_PI / 180); @@ -427,6 +430,19 @@ void drawPolys(QuadTree *tree, double screen_lat_min, double screen_lat_max, dou return; } + if(appData.mapContinue && appData.mapContinue != tree) { + return; + } + + if(appData.mapContinue && appData.mapContinue == tree) { + appData.mapContinue = NULL; + } + + if(mstime() - appData.lastFrameTime > FRAMETIME) { + appData.mapContinue = tree; + return; + } + if (tree->lat_min > screen_lat_max || screen_lat_min > tree->lat_max) { return; } @@ -438,8 +454,14 @@ void drawPolys(QuadTree *tree, double screen_lat_min, double screen_lat_max, dou drawPolys(tree->nw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); drawPolys(tree->sw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); drawPolys(tree->ne, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); + + //if we didn't make it to the last child then need to set mapContinue to this node to make sure all children get drawn next time + if(appData.mapContinue) { + appData.mapContinue = tree; + } + drawPolys(tree->se, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); - + double dx, dy; // if(!(tree->lat_min > screen_lat_min && // tree->lat_max < screen_lat_max && @@ -581,7 +603,11 @@ void drawGeography() { latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, 0, appData.screen_height * -0.2); latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, appData.screen_width, appData.screen_height * 1.2); - drawPolys(&root, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); + if(appData.mapContinue) { + drawPolys(appData.mapContinue, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); + } else { + drawPolys(&root, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); + } } void drawSignalMarks(struct planeObj *p, int x, int y) { @@ -935,7 +961,7 @@ void drawPlanes() { drawTrail(p->oldLon, p->oldLat, p->oldHeading, p->oldSeen, p->oldIdx); } - if(selectedPlane == NULL) { + if(selectedPlane == NULL && appData.touchx && appData.touchy) { if((p->cx - appData.touchx) * (p->cx - appData.touchx) + (p->cy - appData.touchy) * (p->cy - appData.touchy) < 900) { if(selection) { if((p->cx - appData.touchx) * (p->cx - appData.touchx) + (p->cy - appData.touchy) * (p->cy - appData.touchy) < @@ -1089,12 +1115,16 @@ void draw() { updateStatus(); - if(appData.mapMoved) { + if(appData.mapMoved || appData.mapContinue) { SDL_SetRenderTarget(appData.renderer, appData.mapTexture); - SDL_SetRenderDrawColor(appData.renderer, 0, 0, 0, 0); - SDL_RenderClear(appData.renderer); + + if(appData.mapContinue == NULL) { + SDL_SetRenderDrawColor(appData.renderer, 0, 0, 0, 0); + SDL_RenderClear(appData.renderer); + } drawGeography(); + drawScaleBars(); SDL_SetRenderTarget(appData.renderer, NULL ); diff --git a/draw.o.REMOVED.git-id b/draw.o.REMOVED.git-id index fd64bce..d5e9144 100644 --- a/draw.o.REMOVED.git-id +++ b/draw.o.REMOVED.git-id @@ -1 +1 @@ -f1227086156bca68b563a45527bb1442279dc1f5 \ No newline at end of file +4019e6c1da59af5e54909b8625f116916ed7b2de \ No newline at end of file diff --git a/dump1090.c b/dump1090.c deleted file mode 100644 index 60882fc..0000000 --- a/dump1090.c +++ /dev/null @@ -1,904 +0,0 @@ -// dump1090, a Mode S messages decoder for RTLSDR devices. -// -// Copyright (C) 2012 by Salvatore Sanfilippo -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -#include "coaa.h" -#include "dump1090.h" -// -// ============================= Utility functions ========================== -// -void sigintHandler(int dummy) { - MODES_NOTUSED(dummy); - signal(SIGINT, SIG_DFL); // reset signal handler - bit extra safety - Modes.exit = 1; // Signal to threads that we are done -} -// -// =============================== Terminal handling ======================== -// -#ifndef _WIN32 -// Get the number of rows after the terminal changes size. -int getTermRows() { - struct winsize w; - ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); - return (w.ws_row); -} - -// Handle resizing terminal -void sigWinchCallback() { - signal(SIGWINCH, SIG_IGN); - Modes.interactive_rows = getTermRows(); - interactiveShowData(); - signal(SIGWINCH, sigWinchCallback); -} -#else -int getTermRows() { return MODES_INTERACTIVE_ROWS;} -#endif -// -// =============================== Initialization =========================== -// -void modesInitConfig(void) { - // Default everything to zero/NULL - memset(&Modes, 0, sizeof(Modes)); - - // Now initialise things that should not be 0/NULL to their defaults - Modes.gain = MODES_MAX_GAIN; - Modes.freq = MODES_DEFAULT_FREQ; - Modes.ppm_error = MODES_DEFAULT_PPM; - Modes.check_crc = 1; - Modes.net_heartbeat_rate = MODES_NET_HEARTBEAT_RATE; - Modes.net_output_sbs_port = MODES_NET_OUTPUT_SBS_PORT; - Modes.net_output_raw_port = MODES_NET_OUTPUT_RAW_PORT; - Modes.net_input_raw_port = MODES_NET_INPUT_RAW_PORT; - Modes.net_output_beast_port = MODES_NET_OUTPUT_BEAST_PORT; - Modes.net_input_beast_port = MODES_NET_INPUT_BEAST_PORT; - Modes.net_http_port = MODES_NET_HTTP_PORT; - Modes.interactive_rows = getTermRows(); - Modes.interactive_delete_ttl = MODES_INTERACTIVE_DELETE_TTL; - Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL; - Modes.fUserLat = MODES_USER_LATITUDE_DFLT; - Modes.fUserLon = MODES_USER_LONGITUDE_DFLT; -} -// -//========================================================================= -// -void modesInit(void) { - int i, q; - - pthread_mutex_init(&Modes.pDF_mutex,NULL); - pthread_mutex_init(&Modes.data_mutex,NULL); - pthread_cond_init(&Modes.data_cond,NULL); - - // Allocate the various buffers used by Modes - if ( ((Modes.icao_cache = (uint32_t *) malloc(sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2) ) == NULL) || - ((Modes.pFileData = (uint16_t *) malloc(MODES_ASYNC_BUF_SIZE) ) == NULL) || - ((Modes.magnitude = (uint16_t *) malloc(MODES_ASYNC_BUF_SIZE+MODES_PREAMBLE_SIZE+MODES_LONG_MSG_SIZE) ) == NULL) || - ((Modes.maglut = (uint16_t *) malloc(sizeof(uint16_t) * 256 * 256) ) == NULL) || - ((Modes.beastOut = (char *) malloc(MODES_RAWOUT_BUF_SIZE) ) == NULL) || - ((Modes.rawOut = (char *) malloc(MODES_RAWOUT_BUF_SIZE) ) == NULL) ) - { - fprintf(stderr, "Out of memory allocating data buffer.\n"); - exit(1); - } - - // Clear the buffers that have just been allocated, just in-case - memset(Modes.icao_cache, 0, sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2); - memset(Modes.pFileData,127, MODES_ASYNC_BUF_SIZE); - memset(Modes.magnitude, 0, MODES_ASYNC_BUF_SIZE+MODES_PREAMBLE_SIZE+MODES_LONG_MSG_SIZE); - - // Validate the users Lat/Lon home location inputs - if ( (Modes.fUserLat > 90.0) // Latitude must be -90 to +90 - || (Modes.fUserLat < -90.0) // and - || (Modes.fUserLon > 360.0) // Longitude must be -180 to +360 - || (Modes.fUserLon < -180.0) ) { - Modes.fUserLat = Modes.fUserLon = 0.0; - } else if (Modes.fUserLon > 180.0) { // If Longitude is +180 to +360, make it -180 to 0 - Modes.fUserLon -= 360.0; - } - // If both Lat and Lon are 0.0 then the users location is either invalid/not-set, or (s)he's in the - // Atlantic ocean off the west coast of Africa. This is unlikely to be correct. - // Set the user LatLon valid flag only if either Lat or Lon are non zero. Note the Greenwich meridian - // is at 0.0 Lon,so we must check for either fLat or fLon being non zero not both. - // Testing the flag at runtime will be much quicker than ((fLon != 0.0) || (fLat != 0.0)) - Modes.bUserFlags &= ~MODES_USER_LATLON_VALID; - if ((Modes.fUserLat != 0.0) || (Modes.fUserLon != 0.0)) { - Modes.bUserFlags |= MODES_USER_LATLON_VALID; - } - - // Limit the maximum requested raw output size to less than one Ethernet Block - if (Modes.net_output_raw_size > (MODES_RAWOUT_BUF_FLUSH)) - {Modes.net_output_raw_size = MODES_RAWOUT_BUF_FLUSH;} - if (Modes.net_output_raw_rate > (MODES_RAWOUT_BUF_RATE)) - {Modes.net_output_raw_rate = MODES_RAWOUT_BUF_RATE;} - if (Modes.net_sndbuf_size > (MODES_NET_SNDBUF_MAX)) - {Modes.net_sndbuf_size = MODES_NET_SNDBUF_MAX;} - - // Initialise the Block Timers to something half sensible - ftime(&Modes.stSystemTimeBlk); - for (i = 0; i < MODES_ASYNC_BUF_NUMBER; i++) - {Modes.stSystemTimeRTL[i] = Modes.stSystemTimeBlk;} - - // Each I and Q value varies from 0 to 255, which represents a range from -1 to +1. To get from the - // unsigned (0-255) range you therefore subtract 127 (or 128 or 127.5) from each I and Q, giving you - // a range from -127 to +128 (or -128 to +127, or -127.5 to +127.5).. - // - // To decode the AM signal, you need the magnitude of the waveform, which is given by sqrt((I^2)+(Q^2)) - // The most this could be is if I&Q are both 128 (or 127 or 127.5), so you could end up with a magnitude - // of 181.019 (or 179.605, or 180.312) - // - // However, in reality the magnitude of the signal should never exceed the range -1 to +1, because the - // values are I = rCos(w) and Q = rSin(w). Therefore the integer computed magnitude should (can?) never - // exceed 128 (or 127, or 127.5 or whatever) - // - // If we scale up the results so that they range from 0 to 65535 (16 bits) then we need to multiply - // by 511.99, (or 516.02 or 514). antirez's original code multiplies by 360, presumably because he's - // assuming the maximim calculated amplitude is 181.019, and (181.019 * 360) = 65166. - // - // So lets see if we can improve things by subtracting 127.5, Well in integer arithmatic we can't - // subtract half, so, we'll double everything up and subtract one, and then compensate for the doubling - // in the multiplier at the end. - // - // If we do this we can never have I or Q equal to 0 - they can only be as small as +/- 1. - // This gives us a minimum magnitude of root 2 (0.707), so the dynamic range becomes (1.414-255). This - // also affects our scaling value, which is now 65535/(255 - 1.414), or 258.433254 - // - // The sums then become mag = 258.433254 * (sqrt((I*2-255)^2 + (Q*2-255)^2) - 1.414) - // or mag = (258.433254 * sqrt((I*2-255)^2 + (Q*2-255)^2)) - 365.4798 - // - // We also need to clip mag just incaes any rogue I/Q values somehow do have a magnitude greater than 255. - // - - for (i = 0; i <= 255; i++) { - for (q = 0; q <= 255; q++) { - int mag, mag_i, mag_q; - - mag_i = (i * 2) - 255; - mag_q = (q * 2) - 255; - - mag = (int) round((sqrt((mag_i*mag_i)+(mag_q*mag_q)) * 258.433254) - 365.4798); - - Modes.maglut[(i*256)+q] = (uint16_t) ((mag < 65535) ? mag : 65535); - } - } - - // Prepare error correction tables - modesInitErrorInfo(); -} -// -// =============================== RTLSDR handling ========================== -// -void modesInitRTLSDR(void) { - int j; - int device_count; - char vendor[256], product[256], serial[256]; - - device_count = rtlsdr_get_device_count(); - if (!device_count) { - fprintf(stderr, "No supported RTLSDR devices found.\n"); - exit(1); - } - - fprintf(stderr, "Found %d device(s):\n", device_count); - for (j = 0; j < device_count; j++) { - rtlsdr_get_device_usb_strings(j, vendor, product, serial); - fprintf(stderr, "%d: %s, %s, SN: %s %s\n", j, vendor, product, serial, - (j == Modes.dev_index) ? "(currently selected)" : ""); - } - - if (rtlsdr_open(&Modes.dev, Modes.dev_index) < 0) { - fprintf(stderr, "Error opening the RTLSDR device: %s\n", - strerror(errno)); - exit(1); - } - - // Set gain, frequency, sample rate, and reset the device - rtlsdr_set_tuner_gain_mode(Modes.dev, - (Modes.gain == MODES_AUTO_GAIN) ? 0 : 1); - if (Modes.gain != MODES_AUTO_GAIN) { - if (Modes.gain == MODES_MAX_GAIN) { - // Find the maximum gain available - int numgains; - int gains[100]; - - numgains = rtlsdr_get_tuner_gains(Modes.dev, gains); - Modes.gain = gains[numgains-1]; - fprintf(stderr, "Max available gain is: %.2f\n", Modes.gain/10.0); - } - rtlsdr_set_tuner_gain(Modes.dev, Modes.gain); - fprintf(stderr, "Setting gain to: %.2f\n", Modes.gain/10.0); - } else { - fprintf(stderr, "Using automatic gain control.\n"); - } - rtlsdr_set_freq_correction(Modes.dev, Modes.ppm_error); - if (Modes.enable_agc) rtlsdr_set_agc_mode(Modes.dev, 1); - rtlsdr_set_center_freq(Modes.dev, Modes.freq); - rtlsdr_set_sample_rate(Modes.dev, MODES_DEFAULT_RATE); - rtlsdr_reset_buffer(Modes.dev); - fprintf(stderr, "Gain reported by device: %.2f\n", - rtlsdr_get_tuner_gain(Modes.dev)/10.0); -} -// -//========================================================================= -// -// We use a thread reading data in background, while the main thread -// handles decoding and visualization of data to the user. -// -// The reading thread calls the RTLSDR API to read data asynchronously, and -// uses a callback to populate the data buffer. -// -// A Mutex is used to avoid races with the decoding thread. -// -void rtlsdrCallback(unsigned char *buf, uint32_t len, void *ctx) { - - MODES_NOTUSED(ctx); - - // Lock the data buffer variables before accessing them - pthread_mutex_lock(&Modes.data_mutex); - - Modes.iDataIn &= (MODES_ASYNC_BUF_NUMBER-1); // Just incase!!! - - // Get the system time for this block - ftime(&Modes.stSystemTimeRTL[Modes.iDataIn]); - - if (len > MODES_ASYNC_BUF_SIZE) {len = MODES_ASYNC_BUF_SIZE;} - - // Queue the new data - Modes.pData[Modes.iDataIn] = (uint16_t *) buf; - Modes.iDataIn = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn + 1); - Modes.iDataReady = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn - Modes.iDataOut); - - if (Modes.iDataReady == 0) { - // Ooooops. We've just received the MODES_ASYNC_BUF_NUMBER'th outstanding buffer - // This means that RTLSDR is currently overwriting the MODES_ASYNC_BUF_NUMBER+1 - // buffer, but we havent yet processed it, so we're going to lose it. There - // isn't much we can do to recover the lost data, but we can correct things to - // avoid any additional problems. - Modes.iDataOut = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataOut+1); - Modes.iDataReady = (MODES_ASYNC_BUF_NUMBER-1); - Modes.iDataLost++; - } - - // Signal to the other thread that new data is ready, and unlock - pthread_cond_signal(&Modes.data_cond); - pthread_mutex_unlock(&Modes.data_mutex); -} -// -//========================================================================= -// -// This is used when --ifile is specified in order to read data from file -// instead of using an RTLSDR device -// -void readDataFromFile(void) { - pthread_mutex_lock(&Modes.data_mutex); - while(Modes.exit == 0) { - ssize_t nread, toread; - unsigned char *p; - - if (Modes.iDataReady) { - pthread_cond_wait(&Modes.data_cond, &Modes.data_mutex); - continue; - } - - if (Modes.interactive) { - // When --ifile and --interactive are used together, slow down - // playing at the natural rate of the RTLSDR received. - pthread_mutex_unlock(&Modes.data_mutex); - usleep(64000); - pthread_mutex_lock(&Modes.data_mutex); - } - - toread = MODES_ASYNC_BUF_SIZE; - p = (unsigned char *) Modes.pFileData; - while(toread) { - nread = read(Modes.fd, p, toread); - if (nread <= 0) { - Modes.exit = 1; // Signal the other threads to exit. - break; - } - p += nread; - toread -= nread; - } - if (toread) { - // Not enough data on file to fill the buffer? Pad with no signal. - memset(p,127,toread); - } - - Modes.iDataIn &= (MODES_ASYNC_BUF_NUMBER-1); // Just incase!!! - - // Get the system time for this block - ftime(&Modes.stSystemTimeRTL[Modes.iDataIn]); - - // Queue the new data - Modes.pData[Modes.iDataIn] = Modes.pFileData; - Modes.iDataIn = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn + 1); - Modes.iDataReady = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn - Modes.iDataOut); - - // Signal to the other thread that new data is ready - pthread_cond_signal(&Modes.data_cond); - } -} -// -//========================================================================= -// -// We read data using a thread, so the main thread only handles decoding -// without caring about data acquisition -// -void *readerThreadEntryPoint(void *arg) { - MODES_NOTUSED(arg); - - if (Modes.filename == NULL) { - rtlsdr_read_async(Modes.dev, rtlsdrCallback, NULL, - MODES_ASYNC_BUF_NUMBER, - MODES_ASYNC_BUF_SIZE); - } else { - readDataFromFile(); - } - // Signal to the other thread that new data is ready - dummy really so threads don't mutually lock - pthread_cond_signal(&Modes.data_cond); - pthread_mutex_unlock(&Modes.data_mutex); -#ifndef _WIN32 - pthread_exit(NULL); -#else - return NULL; -#endif -} -// -// ============================== Snip mode ================================= -// -// Get raw IQ samples and filter everything is < than the specified level -// for more than 256 samples in order to reduce example file size -// -void snipMode(int level) { - int i, q; - uint64_t c = 0; - - while ((i = getchar()) != EOF && (q = getchar()) != EOF) { - if (abs(i-127) < level && abs(q-127) < level) { - c++; - if (c > MODES_PREAMBLE_SIZE) continue; - } else { - c = 0; - } - putchar(i); - putchar(q); - } -} -// -// ================================ Main ==================================== -// -void showHelp(void) { - printf( -"-----------------------------------------------------------------------------\n" -"| dump1090 ModeS Receiver Ver : " MODES_DUMP1090_VERSION " |\n" -"-----------------------------------------------------------------------------\n" -"--device-index Select RTL device (default: 0)\n" -"--gain Set gain (default: max gain. Use -10 for auto-gain)\n" -"--enable-agc Enable the Automatic Gain Control (default: off)\n" -"--freq Set frequency (default: 1090 Mhz)\n" -"--ifile Read data from file (use '-' for stdin)\n" -"--interactive Interactive mode refreshing data on screen\n" -"--interactive-rows Max number of rows in interactive mode (default: 15)\n" -"--interactive-ttl Remove from list if idle for (default: 60)\n" -"--interactive-rtl1090 Display flight table in RTL1090 format\n" -"--raw Show only messages hex values\n" -"--net Enable networking\n" -"--modeac Enable decoding of SSR Modes 3/A & 3/C\n" -"--net-beast TCP raw output in Beast binary format\n" -"--net-only Enable just networking, no RTL device or file used\n" -"--net-bind-address IP address to bind to (default: Any; Use 127.0.0.1 for private)\n" -"--net-http-port HTTP server port (default: 8080)\n" -"--net-ri-port TCP raw input listen port (default: 30001)\n" -"--net-ro-port TCP raw output listen port (default: 30002)\n" -"--net-sbs-port TCP BaseStation output listen port (default: 30003)\n" -"--net-bi-port TCP Beast input listen port (default: 30004)\n" -"--net-bo-port TCP Beast output listen port (default: 30005)\n" -"--net-ro-size TCP raw output minimum size (default: 0)\n" -"--net-ro-rate TCP raw output memory flush rate (default: 0)\n" -"--net-heartbeat TCP heartbeat rate in seconds (default: 60 sec; 0 to disable)\n" -"--net-buffer TCP buffer size 64Kb * (2^n) (default: n=0, 64Kb)\n" -"--lat Reference/receiver latitude for surface posn (opt)\n" -"--lon Reference/receiver longitude for surface posn (opt)\n" -"--fix Enable single-bits error correction using CRC\n" -"--no-fix Disable single-bits error correction using CRC\n" -"--no-crc-check Disable messages with broken CRC (discouraged)\n" -"--phase-enhance Enable phase enhancement\n" -"--aggressive More CPU for more messages (two bits fixes, ...)\n" -"--mlat display raw messages in Beast ascii mode\n" -"--stats With --ifile print stats at exit. No other output\n" -"--stats-every Show and reset stats every seconds\n" -"--onlyaddr Show only ICAO addresses (testing purposes)\n" -"--metric Use metric units (meters, km/h, ...)\n" -"--snip Strip IQ file removing samples < level\n" -"--debug Debug mode (verbose), see README for details\n" -"--quiet Disable output to stdout. Use for daemon applications\n" -"--ppm Set receiver error in parts per million (default 0)\n" -"--help Show this help\n" -"\n" -"Debug mode flags: d = Log frames decoded with errors\n" -" D = Log frames decoded with zero errors\n" -" c = Log frames with bad CRC\n" -" C = Log frames with good CRC\n" -" p = Log frames with bad preamble\n" -" n = Log network debugging info\n" -" j = Log frames to frames.js, loadable by debug.html\n" - ); -} - -#ifdef _WIN32 -void showCopyright(void) { - uint64_t llTime = time(NULL) + 1; - - printf( -"-----------------------------------------------------------------------------\n" -"| dump1090 ModeS Receiver Ver : " MODES_DUMP1090_VERSION " |\n" -"-----------------------------------------------------------------------------\n" -"\n" -" Copyright (C) 2012 by Salvatore Sanfilippo \n" -" Copyright (C) 2014 by Malcolm Robb \n" -"\n" -" All rights reserved.\n" -"\n" -" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" -" ""AS IS"" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" -" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" -" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" -" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" -" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" -" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" -" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" -" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" -" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" -" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" -"\n" -" For further details refer to \n" -"\n" - ); - - // delay for 1 second to give the user a chance to read the copyright - while (llTime >= time(NULL)) {} -} -#endif - - -static void display_stats(void) { - int j; - time_t now = time(NULL); - - printf("\n\n"); - if (Modes.interactive) - interactiveShowData(); - - printf("Statistics as at %s", ctime(&now)); - - printf("%d sample blocks processed\n", Modes.stat_blocks_processed); - printf("%d sample blocks dropped\n", Modes.stat_blocks_dropped); - - printf("%d ModeA/C detected\n", Modes.stat_ModeAC); - printf("%d valid Mode-S preambles\n", Modes.stat_valid_preamble); - printf("%d DF-?? fields corrected for length\n", Modes.stat_DF_Len_Corrected); - printf("%d DF-?? fields corrected for type\n", Modes.stat_DF_Type_Corrected); - printf("%d demodulated with 0 errors\n", Modes.stat_demodulated0); - printf("%d demodulated with 1 error\n", Modes.stat_demodulated1); - printf("%d demodulated with 2 errors\n", Modes.stat_demodulated2); - printf("%d demodulated with > 2 errors\n", Modes.stat_demodulated3); - printf("%d with good crc\n", Modes.stat_goodcrc); - printf("%d with bad crc\n", Modes.stat_badcrc); - printf("%d errors corrected\n", Modes.stat_fixed); - - for (j = 0; j < MODES_MAX_BITERRORS; j++) { - printf(" %d with %d bit %s\n", Modes.stat_bit_fix[j], j+1, (j==0)?"error":"errors"); - } - - if (Modes.phase_enhance) { - printf("%d phase enhancement attempts\n", Modes.stat_out_of_phase); - printf("%d phase enhanced demodulated with 0 errors\n", Modes.stat_ph_demodulated0); - printf("%d phase enhanced demodulated with 1 error\n", Modes.stat_ph_demodulated1); - printf("%d phase enhanced demodulated with 2 errors\n", Modes.stat_ph_demodulated2); - printf("%d phase enhanced demodulated with > 2 errors\n", Modes.stat_ph_demodulated3); - printf("%d phase enhanced with good crc\n", Modes.stat_ph_goodcrc); - printf("%d phase enhanced with bad crc\n", Modes.stat_ph_badcrc); - printf("%d phase enhanced errors corrected\n", Modes.stat_ph_fixed); - - for (j = 0; j < MODES_MAX_BITERRORS; j++) { - printf(" %d with %d bit %s\n", Modes.stat_ph_bit_fix[j], j+1, (j==0)?"error":"errors"); - } - } - - printf("%d total usable messages\n", Modes.stat_goodcrc + Modes.stat_ph_goodcrc + Modes.stat_fixed + Modes.stat_ph_fixed); - fflush(stdout); - - Modes.stat_blocks_processed = - Modes.stat_blocks_dropped = 0; - - Modes.stat_ModeAC = - Modes.stat_valid_preamble = - Modes.stat_DF_Len_Corrected = - Modes.stat_DF_Type_Corrected = - Modes.stat_demodulated0 = - Modes.stat_demodulated1 = - Modes.stat_demodulated2 = - Modes.stat_demodulated3 = - Modes.stat_goodcrc = - Modes.stat_badcrc = - Modes.stat_fixed = 0; - - Modes.stat_out_of_phase = - Modes.stat_ph_demodulated0 = - Modes.stat_ph_demodulated1 = - Modes.stat_ph_demodulated2 = - Modes.stat_ph_demodulated3 = - Modes.stat_ph_goodcrc = - Modes.stat_ph_badcrc = - Modes.stat_ph_fixed = 0; - - for (j = 0; j < MODES_MAX_BITERRORS; j++) { - Modes.stat_ph_bit_fix[j] = 0; - Modes.stat_bit_fix[j] = 0; - } -} - - -// -//========================================================================= -// -// This function is called a few times every second by main in order to -// perform tasks we need to do continuously, like accepting new clients -// from the net, refreshing the screen in interactive mode, and so forth -// -void backgroundTasks(void) { - static time_t next_stats; - - if (Modes.net) { - modesReadFromClients(); - } - - // If Modes.aircrafts is not NULL, remove any stale aircraft - if (Modes.aircrafts) { - interactiveRemoveStaleAircrafts(); - } - - // Refresh screen when in interactive mode - if (Modes.interactive) { - interactiveShowData(); - } - - if (Modes.stats > 0) { - time_t now = time(NULL); - if (now > next_stats) { - if (next_stats != 0) - display_stats(); - next_stats = now + Modes.stats; - } - } -} -// -//========================================================================= -// -int verbose_device_search(char *s) -{ - int i, device_count, device, offset; - char *s2; - char vendor[256], product[256], serial[256]; - device_count = rtlsdr_get_device_count(); - if (!device_count) { - fprintf(stderr, "No supported devices found.\n"); - return -1; - } - fprintf(stderr, "Found %d device(s):\n", device_count); - for (i = 0; i < device_count; i++) { - rtlsdr_get_device_usb_strings(i, vendor, product, serial); - fprintf(stderr, " %d: %s, %s, SN: %s\n", i, vendor, product, serial); - } - fprintf(stderr, "\n"); - /* does string look like raw id number */ - device = (int)strtol(s, &s2, 0); - if (s2[0] == '\0' && device >= 0 && device < device_count) { - fprintf(stderr, "Using device %d: %s\n", - device, rtlsdr_get_device_name((uint32_t)device)); - return device; - } - /* does string exact match a serial */ - for (i = 0; i < device_count; i++) { - rtlsdr_get_device_usb_strings(i, vendor, product, serial); - if (strcmp(s, serial) != 0) { - continue;} - device = i; - fprintf(stderr, "Using device %d: %s\n", - device, rtlsdr_get_device_name((uint32_t)device)); - return device; - } - /* does string prefix match a serial */ - for (i = 0; i < device_count; i++) { - rtlsdr_get_device_usb_strings(i, vendor, product, serial); - if (strncmp(s, serial, strlen(s)) != 0) { - continue;} - device = i; - fprintf(stderr, "Using device %d: %s\n", - device, rtlsdr_get_device_name((uint32_t)device)); - return device; - } - /* does string suffix match a serial */ - for (i = 0; i < device_count; i++) { - rtlsdr_get_device_usb_strings(i, vendor, product, serial); - offset = strlen(serial) - strlen(s); - if (offset < 0) { - continue;} - if (strncmp(s, serial+offset, strlen(s)) != 0) { - continue;} - device = i; - fprintf(stderr, "Using device %d: %s\n", - device, rtlsdr_get_device_name((uint32_t)device)); - return device; - } - fprintf(stderr, "No matching devices found.\n"); - return -1; -} -// -//========================================================================= -// -int main(int argc, char **argv) { - int j; - - // Set sane defaults - modesInitConfig(); - signal(SIGINT, sigintHandler); // Define Ctrl/C handler (exit program) - - // Parse the command line options - for (j = 1; j < argc; j++) { - int more = j+1 < argc; // There are more arguments - - if (!strcmp(argv[j],"--device-index") && more) { - Modes.dev_index = verbose_device_search(argv[++j]); - } else if (!strcmp(argv[j],"--gain") && more) { - Modes.gain = (int) (atof(argv[++j])*10); // Gain is in tens of DBs - } else if (!strcmp(argv[j],"--enable-agc")) { - Modes.enable_agc++; - } else if (!strcmp(argv[j],"--freq") && more) { - Modes.freq = (int) strtoll(argv[++j],NULL,10); - } else if (!strcmp(argv[j],"--ifile") && more) { - Modes.filename = strdup(argv[++j]); - } else if (!strcmp(argv[j],"--fix")) { - Modes.nfix_crc = 1; - } else if (!strcmp(argv[j],"--no-fix")) { - Modes.nfix_crc = 0; - } else if (!strcmp(argv[j],"--no-crc-check")) { - Modes.check_crc = 0; - } else if (!strcmp(argv[j],"--phase-enhance")) { - Modes.phase_enhance = 1; - } else if (!strcmp(argv[j],"--raw")) { - Modes.raw = 1; - } else if (!strcmp(argv[j],"--net")) { - Modes.net = 1; - } else if (!strcmp(argv[j],"--modeac")) { - Modes.mode_ac = 1; - } else if (!strcmp(argv[j],"--net-beast")) { - Modes.beast = 1; - } else if (!strcmp(argv[j],"--net-only")) { - Modes.net = 1; - Modes.net_only = 1; - } else if (!strcmp(argv[j],"--net-heartbeat") && more) { - Modes.net_heartbeat_rate = atoi(argv[++j]) * 15; - } else if (!strcmp(argv[j],"--net-ro-size") && more) { - Modes.net_output_raw_size = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--net-ro-rate") && more) { - Modes.net_output_raw_rate = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--net-ro-port") && more) { - if (Modes.beast) // Required for legacy backward compatibility - {Modes.net_output_beast_port = atoi(argv[++j]);;} - else - {Modes.net_output_raw_port = atoi(argv[++j]);} - } else if (!strcmp(argv[j],"--net-ri-port") && more) { - Modes.net_input_raw_port = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--net-bo-port") && more) { - Modes.net_output_beast_port = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--net-bi-port") && more) { - Modes.net_input_beast_port = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--net-bind-address") && more) { - Modes.net_bind_address = strdup(argv[++j]); - } else if (!strcmp(argv[j],"--net-http-port") && more) { - Modes.net_http_port = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--net-sbs-port") && more) { - Modes.net_output_sbs_port = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--net-buffer") && more) { - Modes.net_sndbuf_size = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--onlyaddr")) { - Modes.onlyaddr = 1; - } else if (!strcmp(argv[j],"--metric")) { - Modes.metric = 1; - } else if (!strcmp(argv[j],"--aggressive")) { - Modes.nfix_crc = MODES_MAX_BITERRORS; - } else if (!strcmp(argv[j],"--interactive")) { - Modes.interactive = 1; - } else if (!strcmp(argv[j],"--interactive-rows") && more) { - Modes.interactive_rows = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--interactive-ttl") && more) { - Modes.interactive_display_ttl = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--lat") && more) { - Modes.fUserLat = atof(argv[++j]); - } else if (!strcmp(argv[j],"--lon") && more) { - Modes.fUserLon = atof(argv[++j]); - } else if (!strcmp(argv[j],"--debug") && more) { - char *f = argv[++j]; - while(*f) { - switch(*f) { - case 'D': Modes.debug |= MODES_DEBUG_DEMOD; break; - case 'd': Modes.debug |= MODES_DEBUG_DEMODERR; break; - case 'C': Modes.debug |= MODES_DEBUG_GOODCRC; break; - case 'c': Modes.debug |= MODES_DEBUG_BADCRC; break; - case 'p': Modes.debug |= MODES_DEBUG_NOPREAMBLE; break; - case 'n': Modes.debug |= MODES_DEBUG_NET; break; - case 'j': Modes.debug |= MODES_DEBUG_JS; break; - default: - fprintf(stderr, "Unknown debugging flag: %c\n", *f); - exit(1); - break; - } - f++; - } - } else if (!strcmp(argv[j],"--stats")) { - Modes.stats = -1; - } else if (!strcmp(argv[j],"--stats-every") && more) { - Modes.stats = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--snip") && more) { - snipMode(atoi(argv[++j])); - exit(0); - } else if (!strcmp(argv[j],"--help")) { - showHelp(); - exit(0); - } else if (!strcmp(argv[j],"--ppm") && more) { - Modes.ppm_error = atoi(argv[++j]); - } else if (!strcmp(argv[j],"--quiet")) { - Modes.quiet = 1; - } else if (!strcmp(argv[j],"--mlat")) { - Modes.mlat = 1; - } else if (!strcmp(argv[j],"--interactive-rtl1090")) { - Modes.interactive = 1; - Modes.interactive_rtl1090 = 1; - } else { - fprintf(stderr, - "Unknown or not enough arguments for option '%s'.\n\n", - argv[j]); - showHelp(); - exit(1); - } - } - -#ifdef _WIN32 - // Try to comply with the Copyright license conditions for binary distribution - if (!Modes.quiet) {showCopyright();} -#endif - -#ifndef _WIN32 - // Setup for SIGWINCH for handling lines - if (Modes.interactive) {signal(SIGWINCH, sigWinchCallback);} -#endif - - // Initialization - modesInit(); - - if (Modes.net_only) { - fprintf(stderr,"Net-only mode, no RTL device or file open.\n"); - } else if (Modes.filename == NULL) { - modesInitRTLSDR(); - } else { - if (Modes.filename[0] == '-' && Modes.filename[1] == '\0') { - Modes.fd = STDIN_FILENO; - } else if ((Modes.fd = open(Modes.filename, -#ifdef _WIN32 - (O_RDONLY | O_BINARY) -#else - (O_RDONLY) -#endif - )) == -1) { - perror("Opening data file"); - exit(1); - } - } - if (Modes.net) modesInitNet(); - - // If the user specifies --net-only, just run in order to serve network - // clients without reading data from the RTL device - while (Modes.net_only) { - if (Modes.exit) exit(0); // If we exit net_only nothing further in main() - backgroundTasks(); - usleep(100000); - } - - // Create the thread that will read the data from the device. - pthread_create(&Modes.reader_thread, NULL, readerThreadEntryPoint, NULL); - pthread_mutex_lock(&Modes.data_mutex); - - while (Modes.exit == 0) { - - if (Modes.iDataReady == 0) { - pthread_cond_wait(&Modes.data_cond,&Modes.data_mutex); // This unlocks Modes.data_mutex, and waits for Modes.data_cond - continue; // Once (Modes.data_cond) occurs, it locks Modes.data_mutex - } - - // Modes.data_mutex is Locked, and (Modes.iDataReady != 0) - if (Modes.iDataReady) { // Check we have new data, just in case!! - - Modes.iDataOut &= (MODES_ASYNC_BUF_NUMBER-1); // Just incase - - // Translate the next lot of I/Q samples into Modes.magnitude - computeMagnitudeVector(Modes.pData[Modes.iDataOut]); - - Modes.stSystemTimeBlk = Modes.stSystemTimeRTL[Modes.iDataOut]; - - // Update the input buffer pointer queue - Modes.iDataOut = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataOut + 1); - Modes.iDataReady = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn - Modes.iDataOut); - - // If we lost some blocks, correct the timestamp - if (Modes.iDataLost) { - Modes.timestampBlk += (MODES_ASYNC_BUF_SAMPLES * 6 * Modes.iDataLost); - Modes.stat_blocks_dropped += Modes.iDataLost; - Modes.iDataLost = 0; - } - - // It's safe to release the lock now - pthread_cond_signal (&Modes.data_cond); - pthread_mutex_unlock(&Modes.data_mutex); - - // Process data after releasing the lock, so that the capturing - // thread can read data while we perform computationally expensive - // stuff at the same time. - detectModeS(Modes.magnitude, MODES_ASYNC_BUF_SAMPLES); - - // Update the timestamp ready for the next block - Modes.timestampBlk += (MODES_ASYNC_BUF_SAMPLES*6); - Modes.stat_blocks_processed++; - } else { - pthread_cond_signal (&Modes.data_cond); - pthread_mutex_unlock(&Modes.data_mutex); - } - - backgroundTasks(); - pthread_mutex_lock(&Modes.data_mutex); - } - - // If --stats were given, print statistics - if (Modes.stats) { - display_stats(); - } - - if (Modes.filename == NULL) { - rtlsdr_cancel_async(Modes.dev); // Cancel rtlsdr_read_async will cause data input thread to terminate cleanly - rtlsdr_close(Modes.dev); - } - pthread_cond_destroy(&Modes.data_cond); // Thread cleanup - pthread_mutex_destroy(&Modes.data_mutex); - pthread_join(Modes.reader_thread,NULL); // Wait on reader thread exit -#ifndef _WIN32 - pthread_exit(0); -#else - return (0); -#endif -} -// -//========================================================================= -// diff --git a/font.o b/font.o index 85b9bb72588953b123507690b920fa7da94c9384..801bef849bc4d5a670a3606163e7b25a806805dc 100644 GIT binary patch delta 4860 zcmZ`+4Nz3q6@F(yWEDXWxID}v7=Iu!Zq_)8nt*7g>l#x*0U?Sk{!mOo{*;A`@@I_V zAFQVpnc7664U$@suC;1910*%0?W7G!jia_1m`U4-Z8fxsQ(I$u?!NQvdK>QyXV3Y* zbI(2Z-1F{xoanL)by?byVW>By-eL*TechIiB7)C}kW6fdigjg1YFemOqanuRl0M$h z!`6@kJCtohfA5@ zmpu`hX7MjN>$jxF`_=Sw))z!$hlk2dsY&yo*k_gopd zb9QM`pJDikKlF|Ajw6F`5nmnU%sicsdPCv3LetWbQ zCQB*{La5qUXp~B9E@Rr1rLJ>$)Yea+H4iK49{&-Bz11^ zb+TgI;OnK%Ewn-UaIvfy$6sZUNE;*L!0GA7dzlDyt3E>w>OEG7Dh%4eAhb34OC)0g9&PM58inIA2a_KW= zJ>HIs5yxU5nO?{>iuZ0T_6yx6^Se&2-<03ixLr?3lj+3>>GA*RJ;gZf>_L7?ve$H* za}T*C%G_XryjtXV!uZj&&nP^F4*Cb=Xxft!g<#W3TB%adfFtYix%lKUCP&*WkB%QtV?w0Y}BU)w@= zsPER2svtP$D_Z6Zfm-Zd;e?$yvO>Uqw644gRX9v?9iGp&!*cvQ+X-HDId8tqD=b*cSjo@a`!&tQ14)f8wTEOer zz1r?r#EG6)JdN8;)A|&=0Ih5K^g9!cxIv>Hj{h?pUgLqIm|tMmulS!aP1~XPHn+fK^)#_hZ`7K?1Ufs@{4-_zCde9D_p^jl0t~| z-7RSVX!6y)+z!xzk)}9jZ}{Y$o1XbLONOr{M{kXjn)zCd9eUB~ zaY80$c?2EUCep*Pm*ns9uE!2P!IauUNXC}hE@(hUoq#NK)j6RQy>+e7ib=0{UJ-axzFwB-6miXc5k!mzvOmxD?X=jWSg*rCg7OuHBgUD+l4+M z(FoJ8xIT%!+glw$T&ZZj%FM+o7*AAi4_4OOtwsDaK9Amdp>I-rUXC(W+=2tdHZm*k z4L(6X-GU?a!gWZQJBd%=O$Fc0Q%@;)0bfTKFsnf{ysxnJoXJNDzKfsaPZd0vUZir| zRPc3N?mG(ZqL;oL7Gs?!9`xjk94MRA=hm=_7a;P5TCDZ|J-66Cbn8- zd2TI6?htyj!fs`D7iR1bF0aDgWcE-1E;rfEJ##bwmzgB;yZJ}hNzr-~Hka8m0l19j z6Wk<<+M$@;s9QUwk zr*K*68&nRHoz9;e;Q_d;=L)|UebooxGTIULx8X3YHC!mnC$u6d6v#tdRJ6*iUUZoo=nw=iqod;Q$uP1xBY=&PTkW1r%)jbC+bkHFgz z_6Ycal#XMHkDcdsJp%8+BAV;-%XiRAdY@muj{~Gr#Yhg~2+1o_I<6~mrkbzqN8t2q z?iKL4Uw(m2q<`s`|HfX@|0AVuXs_D>$-ayOPOyyDaZl?U>!mECYMFSsbuOGjXiJB0 zVMbfJC2k)!x23^%aeyEv-8a7lsfHrdz^XI4~s^^A09k j#=EfjU>cmjfrIJrAp)jDKW1RMHFUqR;3wE}VA6j94hY#L delta 4737 zcmaKv3s98T6@dSd&5F@P6z~;!_+X^UOB7gNi1@5l zSdOVRqf<$2gic%7u4C1jBBpI*($+RS(!~M@W z-?`_Wd++)GyWBiuYd>RaNr84>>Q0+&FwWm$dp|O`ON7qFhN#$_xpqwp3)iTLk@HC& zW6Gl!ksN2r5mHVv<#}-%OEzm_j+|go+{VfZmY116 zFBDP|#p5WLCfrg^3MPf-7xSccbA*XsdS<>8PYA z`JFUXJIUm2$Ulp8tQ`hjQnAQc&cSdyAE;bnrJys2)_*xt8-0;-lZO}2S~f5koxi*T}-meLs` zoiuHN>|nNigr)^~yBeM})I9kv$u=<;K_448ZzOq7Dv2|Vlg$Th0#4T_hj_@GihUwJ zaSut^BpcQ=-=P=%UIl#y^MtEZ%o9y%NP`obUQy@R+OIR#34NOC>;HrWDcLjH` zSx+<;5G0HMkBpQHNMQT_S-@T0;jSmQB$+Qn%WsfuQ_Y8_y-#7x-10T;Tha=_mXp-d zWk(H8m~)!`39%Vwc*>ksP8*Q-aC7BO51;I3tqHME;TH*q zC;2;P6@~f7!h5!kcT39E3B`gbsSnH!u~wyYaYVd`=>MER?irvbcy9V@!^vmA7Puo>J6dKep5 zI^o;sTPdIwdsjML&pJ$x3yS9hPH)d1+GFBHgLo7nE&|{O#=ni^CWwTas2VKPi zGBKyP89u`6#YJ$(pHb2u1SM!+*RTJWmlR`s@gEM`hfwN-Yv?LVOQ2v1eluOvB`IH_XDaa;N@eqUiyn z%%_!WCi=>SzJh6lLThoL+zD@@y+Y_$*k_XBa|5$0gzcL|Tv71_oWYz*H#~*jN+ccR*x<7sjS75R%J8D)!_jP<~Qz68lcT*Agad4AcZ`4hf zGQ~9(b87_jU|EeUxZ~8{#NHYzS>Bc7ivM)Kee(!_`F?#1Jyv3JtpLP~+B!IdzFIdG z^H8l5euAlWZkUVJb%GA;AjvlDqy9bA>z&YsIrT*_4m;}4Kn>=41bi3EJZ>mPpQjm` zFnenqB;kdvZfNquwqu~j^0v(wV=ls4XEpk^3y8+v?N0qXmus=&a~kbCgzdfqr|zhQ zP1v?W=p&NMFqakA@z}Sc+4VKQS7Z6>Wlgr0cQ8q@Z$R%(XZUWqj$~Vk13QJjTJgyX zHE9Lf8-!k`&>wQ`@4;-MEehSvhkOF7iMA{B7~P4ooy9hymle8=-_Ji_AJIQ6w1Btl z7Q!yka8IENIr4qQevWH5DaxGL+Mj-Tvs0U<*w1k#WhnLu{LOg5v`-zb-X>n~5@o;} zoDjX3yM$h@(7%p1r{9W$ME5Hc_^6L!a-+}%AC{Fm2i7KHZllO?DOCPil5MYIzs;NL zWxKovhVK}XUqc_w^=1H_B*Sp~6%No`Z!0kqWJ=VoDfYLx_&!$bU-7E{f!Vu7&X)?E z!!NJK3$)gIibsu7>{)z232fUf^dyB2@_|jpKB6-f+QDC`*Og<6~qtHj*Q|Z^9Y;t<(_(#rTHVzP7r_j%t z?m+uqp}(ro5T5CE%qDt{sdbhQ_|tL;tBHP~Q0r7a!M433=S~1MR>-gH*NS}#{~)*@ zU=KW}P=tL#AI0ZlWn!IE47!NME7UrPiC983RiV~Nq@$PU>;NkBY~jj#5qpT1D)jeE zH{jqt5z;8BaT2YVykF=(_O?#qZ-iy*#ayDFD>Rr-A{ZNqj-%hQvRPvtOjFTEG>xgX z{>^+6GjU+QfIRFwAfOQK2ZX*xi8J2}t9dZ{fCy=l6x&*(;Wex#@6!QsIVhXkBA`fki7`EA*|t}1bK>-v0*{R3>HvHeDW1N%t+)aY*`92W3TKOC;J zL73lj#0?Su<`~A7Vq0@G-fWHwZ_hP!EghjH4NhQ2OBOtXo|Y`z%|m#xB@>q85Sdai z!<$8$;GupQUhrmx&*1+*TM=5*;0k86X4$@&hkZG**wUI}yEhLnwq`;V4z*@M7iM4< U{R`p2tnl{^n-hMBJx9j>7a397ZU6uP diff --git a/init.c b/init.c index d740e1d..bb78170 100644 --- a/init.c +++ b/init.c @@ -43,6 +43,8 @@ void init(char *title) { appData.screen_width, appData.screen_height); appData.mapMoved = 1; + selectedPlane = NULL; + appData.mapContinue = NULL; if(appData.fullscreen) { //\SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); // make the scaled rendering look smoother. diff --git a/init.o b/init.o index f25681451b739f5af961c6b38463e5a7110db08c..332a5abe4e4e2c6e00638e81706d797d2c0c2683 100644 GIT binary patch delta 6532 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 F{|6c%pD+Lb diff --git a/input.o.REMOVED.git-id b/input.o.REMOVED.git-id index 82d3329..0b023a1 100644 --- a/input.o.REMOVED.git-id +++ b/input.o.REMOVED.git-id @@ -1 +1 @@ -d4947b5d39abcf0073465f4b5683173294132874 \ No newline at end of file +e65446c295519dac23cf6b702c274d4cfb873e7f \ No newline at end of file diff --git a/interactive.c b/interactive.c index 4f7e029..ae89d8b 100644 --- a/interactive.c +++ b/interactive.c @@ -60,15 +60,20 @@ void interactiveCreateDF(struct aircraft *a, struct modesMessage *mm) { pDF->pAircraft = a; memcpy(pDF->msg, mm->msg, MODES_LONG_MSG_BYTES); - if (!pthread_mutex_lock(&Modes.pDF_mutex)) { - if ((pDF->pNext = Modes.pDF)) { - Modes.pDF->pPrev = pDF; - } - Modes.pDF = pDF; - pthread_mutex_unlock(&Modes.pDF_mutex); - } else { - free(pDF); + // if (!pthread_mutex_lock(&Modes.pDF_mutex)) { + // if ((pDF->pNext = Modes.pDF)) { + // Modes.pDF->pPrev = pDF; + // } + // Modes.pDF = pDF; + // pthread_mutex_unlock(&Modes.pDF_mutex); + // } else { + // free(pDF); + // } + if ((pDF->pNext = Modes.pDF)) { + Modes.pDF->pPrev = pDF; } + Modes.pDF = pDF; + } } // @@ -81,45 +86,75 @@ void interactiveRemoveStaleDF(time_t now) { // Only fiddle with the DF list if we gain possession of the mutex // If we fail to get the mutex we'll get another chance to tidy the // DF list in a second or so. - if (!pthread_mutex_trylock(&Modes.pDF_mutex)) { - pDF = Modes.pDF; - while(pDF) { - if ((now - pDF->seen) > Modes.interactive_delete_ttl) { - if (Modes.pDF == pDF) { - Modes.pDF = NULL; - } else { - prev->pNext = NULL; - } + // if (!pthread_mutex_trylock(&Modes.pDF_mutex)) { + // pDF = Modes.pDF; + // while(pDF) { + // if ((now - pDF->seen) > Modes.interactive_delete_ttl) { + // if (Modes.pDF == pDF) { + // Modes.pDF = NULL; + // } else { + // prev->pNext = NULL; + // } - // All DF's in the list from here onwards will be time - // expired, so delete them all - while (pDF) { - prev = pDF; pDF = pDF->pNext; - free(prev); - } + // // All DF's in the list from here onwards will be time + // // expired, so delete them all + // while (pDF) { + // prev = pDF; pDF = pDF->pNext; + // free(prev); + // } + // } else { + // prev = pDF; pDF = pDF->pNext; + // } + // } + // pthread_mutex_unlock (&Modes.pDF_mutex); + // } + pDF = Modes.pDF; + while(pDF) { + if ((now - pDF->seen) > Modes.interactive_delete_ttl) { + if (Modes.pDF == pDF) { + Modes.pDF = NULL; } else { - prev = pDF; pDF = pDF->pNext; + prev->pNext = NULL; } + + // All DF's in the list from here onwards will be time + // expired, so delete them all + while (pDF) { + prev = pDF; pDF = pDF->pNext; + free(prev); + } + + } else { + prev = pDF; pDF = pDF->pNext; } - pthread_mutex_unlock (&Modes.pDF_mutex); } } struct stDF *interactiveFindDF(uint32_t addr) { struct stDF *pDF = NULL; - if (!pthread_mutex_lock(&Modes.pDF_mutex)) { - pDF = Modes.pDF; - while(pDF) { - if (pDF->addr == addr) { - pthread_mutex_unlock (&Modes.pDF_mutex); - return (pDF); - } - pDF = pDF->pNext; + // if (!pthread_mutex_lock(&Modes.pDF_mutex)) { + // pDF = Modes.pDF; + // while(pDF) { + // if (pDF->addr == addr) { + // pthread_mutex_unlock (&Modes.pDF_mutex); + // return (pDF); + // } + // pDF = pDF->pNext; + // } + // pthread_mutex_unlock (&Modes.pDF_mutex); + // } + + pDF = Modes.pDF; + while(pDF) { + if (pDF->addr == addr) { + return (pDF); } - pthread_mutex_unlock (&Modes.pDF_mutex); + pDF = pDF->pNext; } + + return (NULL); } // diff --git a/interactive.o b/interactive.o index 77997b23096b9626b7aaba8b7657aa551c5de545..b2a72dbf2f3c662398d9f99bb7ea3c176794293f 100644 GIT binary patch literal 44376 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 G{{H}F4C#pg literal 46136 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 diff --git a/list.o b/list.o index ed2a71d5e6b81655b042285ff3977292f5fe6f57..43b9463726a7cc20354876e40d21ea896c140d33 100644 GIT binary patch delta 6181 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�iD3*<3o{G}2JvF=B->y!w(=?J z1orVI!5cW*my-Sg>0GuQOo9PFn@Vv9x~PC|@kJ61$7)~y5nmEzv~QqknpBk!SghiU z9KMy}WzqQz+co#tEiop7-qe7YJIqP8-RSFNVo@}hdbMwK@x(=KW$QJJ=%>?4V&HJJ za7IOIcpaN(7r?8SKPLof*f1v-CZqYV1&1*3@Oj9><-+F}oF~ko zGGQ9^pzgALCeT%b)$;^w!@79|(1>P{WqwAFo*Zc&b$2ws!NMZpxtxegi}uh%kv#tt zlwsq13+kiZ1-}D0i-kb}6R;#`!64ilw9E~3GUS+QzjaizkTEAZ=zzh;1iXSzJyrv2(Z9@s`>=3X8N7r| z%PjLpuI$+MEsd*j@bVC}#>nzqxE-5m9*a3)Vb0|G#dK(?@5f-c1|CK8am)M@`+Pyu z8H$CEpQ7l=rDgCXMoNWgBq=Y;I=1w712z)chtWz6ZHL|!0(N5BiZbYobt^3Dy`Qfr zfI-o~6PZAbrS!>D@C4?p6i|oxD=l-%t;+qxPA$V^WA#d5#&P|oYv^;>KjyVWxEf|UZwYe}oTC(;W?V+goJl(os@>T)+aPZa;%)!XkTzC$fw_4Px z(q71gp%{EYzmBZQYSs2+N;0rvn!!k>`8Woz(BJ}PQupHBNhUiJJ z-YLuv?XMiexT0x(jtx5tJePapz+L_6*c9#(<|;1S{q(`)4!jP_cUkeb*PH@931aN%x7*dt7zh92&wwA0bQM}+U!(1o!IovF$D@P;kWq!ukG=gyEL7@@^(hBiSqx8hOXoe@g^qM2y+~LamwKwAZCpzm{%jh4{7L* z8t%7?(# znTxPj1d3g#{q4>6r7U-{>cFP!T>3s&tj$=sSC~6oC@zXMWkGFMj|z<0nl&ou99Eyq_}LevUHTyDB-Z z-scS@xperEwl&jO?o@AMl5%jnOW*$Cqr}F&*tk!a6Ev$WoLN44_X~5W3vI`C^0pdt z2;Hoq^uyC0&tq`E2<+C-*BRaClFRSGPRzfg$;b0s=QK7@tT$aKf9%-)-bXkf!XLR% zndes=>)$T9jFrmA=aNe<^@qrU)A-IMmr;gGA&o08x%A`oSWp{)6$iX#9B+nGf2ZGe z!ukWkyg@_zCfkmUp4fCi1kyFs!~JW7ChyB1P892Dj{4Q$sEpU^)r zDtA`KYG$8*#6m(BXttBsb1{|^x>~ax8A}dmY`}U#E0b)-eiKR0$mlj~BJ@>8WioMe zag#RQ$K=Bz@C~C*R{vt#tD3wczipj2yrVym<#AYgSeUo*d30j&HX3(ggwVSfm9}y( zF485(1Z*U9stc8?ILMx7p*JGTIWEt3X}Egjm_ullhIV4~1O^HHo920pECY?Vu{t6G zf7fgWv2C+U&IYzsY!CZp0NrFJS-evN5RM3QtcEUSZwt{+XoZFzWAr2z9ua|y8tS|o zu4wWsm4MMPrDY~lS)PLR6e~wV8#z`On+V;_sN4(Li$*ef1e2q}d|5*q_*9&fD7=ZK zG@rHSa~L7|Lwjz-Mxy^C=bOILJp9DF`E3ezJ~|9eNAr#rczV#o<4h4aFEdnT>~!w}ETe{PL~; E19l*aO#lD@ diff --git a/monokai.o b/monokai.o index f3c046fa29f82566bcd3bfe93a0d161adac0fe6e..6f670082aa843be3934aac4417aacb39a254467f 100644 GIT binary patch delta 8600 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 delta 8308 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 delta 7902 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 ybSjM4(= 199309 -#undef PTW32_LEVEL -#define PTW32_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_LEVEL -#define PTW32_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_LEVEL_MAX 3 - -#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL) -#define PTW32_LEVEL PTW32_LEVEL_MAX -/* Include everything */ -#endif - -#if defined(_UWIN) -# define HAVE_STRUCT_TIMESPEC 1 -# define HAVE_SIGNAL_H 1 -# undef HAVE_PTW32_CONFIG_H -# pragma comment(lib, "pthread") -#endif - -/* - * ------------------------------------------------------------- - * - * - * Module: pthread.h - * - * Purpose: - * Provides an implementation of PThreads based upon the - * standard: - * - * POSIX 1003.1-2001 - * and - * The Single Unix Specification version 3 - * - * (these two are equivalent) - * - * in order to enhance code portability between Windows, - * various commercial Unix implementations, and Linux. - * - * See the ANNOUNCE file for a full list of conforming - * routines and defined constants, and a list of missing - * routines and constants not defined in this implementation. - * - * Authors: - * There have been many contributors to this library. - * The initial implementation was contributed by - * John Bossom, and several others have provided major - * sections or revisions of parts of the implementation. - * Often significant effort has been contributed to - * find and fix important bugs and other problems to - * improve the reliability of the library, which sometimes - * is not reflected in the amount of code which changed as - * result. - * As much as possible, the contributors are acknowledged - * in the ChangeLog file in the source code distribution - * where their changes are noted in detail. - * - * Contributors are listed in the CONTRIBUTORS file. - * - * As usual, all bouquets go to the contributors, and all - * brickbats go to the project maintainer. - * - * Maintainer: - * The code base for this project is coordinated and - * eventually pre-tested, packaged, and made available by - * - * Ross Johnson - * - * QA Testers: - * Ultimately, the library is tested in the real world by - * a host of competent and demanding scientists and - * engineers who report bugs and/or provide solutions - * which are then fixed or incorporated into subsequent - * versions of the library. Each time a bug is fixed, a - * test case is written to prove the fix and ensure - * that later changes to the code don't reintroduce the - * same error. The number of test cases is slowly growing - * and therefore so is the code reliability. - * - * Compliance: - * See the file ANNOUNCE for the list of implemented - * and not-implemented routines and defined options. - * Of course, these are all defined is this file as well. - * - * Web site: - * The source code and other information about this library - * are available from - * - * http://sources.redhat.com/pthreads-win32/ - * - * ------------------------------------------------------------- - */ - -/* Try to avoid including windows.h */ -#if (defined(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus) -#define PTW32_INCLUDE_WINDOWS_H -#endif - -#if defined(PTW32_INCLUDE_WINDOWS_H) -#include -#endif - -#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) -/* - * VC++6.0 or early compiler's header has no DWORD_PTR type. - */ -typedef unsigned long DWORD_PTR; -typedef unsigned long ULONG_PTR; -#endif -/* - * ----------------- - * autoconf switches - * ----------------- - */ - -#if defined(HAVE_PTW32_CONFIG_H) -#include "config.h" -#endif /* HAVE_PTW32_CONFIG_H */ - -#if !defined(NEED_FTIME) -#include -#else /* NEED_FTIME */ -/* use native WIN32 time API */ -#endif /* NEED_FTIME */ - -#if defined(HAVE_SIGNAL_H) -#include -#endif /* HAVE_SIGNAL_H */ - -#include - -/* - * Boolean values to make us independent of system includes. - */ -enum { - PTW32_FALSE = 0, - PTW32_TRUE = (! PTW32_FALSE) -}; - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include -#endif -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Several systems don't define some error numbers. - */ -#if !defined(ENOTSUP) -# define ENOTSUP 48 /* This is the value in Solaris. */ -#endif - -#if !defined(ETIMEDOUT) -# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */ -#endif - -#if !defined(ENOSYS) -# define ENOSYS 140 /* Semi-arbitrary value */ -#endif - -#if !defined(EDEADLK) -# if defined(EDEADLOCK) -# define EDEADLK EDEADLOCK -# else -# define EDEADLK 36 /* This is the value in MSVC. */ -# endif -#endif - -/* POSIX 2008 - related to robust mutexes */ -#if !defined(EOWNERDEAD) -# define EOWNERDEAD 43 -#endif -#if !defined(ENOTRECOVERABLE) -# define ENOTRECOVERABLE 44 -#endif - -#include - -/* - * To avoid including windows.h we define only those things that we - * actually need from it. - */ -#if !defined(PTW32_INCLUDE_WINDOWS_H) -#if !defined(HANDLE) -# define PTW32__HANDLE_DEF -# define HANDLE void * -#endif -#if !defined(DWORD) -# define PTW32__DWORD_DEF -# define DWORD unsigned long -#endif -#endif - -#if !defined(HAVE_STRUCT_TIMESPEC) -#define HAVE_STRUCT_TIMESPEC -#if !defined(_TIMESPEC_DEFINED) -#define _TIMESPEC_DEFINED -struct timespec { - time_t tv_sec; - long tv_nsec; -}; -#endif /* _TIMESPEC_DEFINED */ -#endif /* HAVE_STRUCT_TIMESPEC */ - -#if !defined(SIG_BLOCK) -#define SIG_BLOCK 0 -#endif /* SIG_BLOCK */ - -#if !defined(SIG_UNBLOCK) -#define SIG_UNBLOCK 1 -#endif /* SIG_UNBLOCK */ - -#if !defined(SIG_SETMASK) -#define SIG_SETMASK 2 -#endif /* SIG_SETMASK */ - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -/* - * ------------------------------------------------------------- - * - * POSIX 1003.1-2001 Options - * ========================= - * - * Options are normally set in , which is not provided - * with pthreads-win32. - * - * For conformance with the Single Unix Specification (version 3), all of the - * options below are defined, and have a value of either -1 (not supported) - * or 200112L (supported). - * - * These options can neither be left undefined nor have a value of 0, because - * either indicates that sysconf(), which is not implemented, may be used at - * runtime to check the status of the option. - * - * _POSIX_THREADS (== 200112L) - * If == 200112L, you can use threads - * - * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) - * If == 200112L, you can control the size of a thread's - * stack - * pthread_attr_getstacksize - * pthread_attr_setstacksize - * - * _POSIX_THREAD_ATTR_STACKADDR (== -1) - * If == 200112L, you can allocate and control a thread's - * stack. If not supported, the following functions - * will return ENOSYS, indicating they are not - * supported: - * pthread_attr_getstackaddr - * pthread_attr_setstackaddr - * - * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) - * If == 200112L, you can use realtime scheduling. - * This option indicates that the behaviour of some - * implemented functions conforms to the additional TPS - * requirements in the standard. E.g. rwlocks favour - * writers over readers when threads have equal priority. - * - * _POSIX_THREAD_PRIO_INHERIT (== -1) - * If == 200112L, you can create priority inheritance - * mutexes. - * pthread_mutexattr_getprotocol + - * pthread_mutexattr_setprotocol + - * - * _POSIX_THREAD_PRIO_PROTECT (== -1) - * If == 200112L, you can create priority ceiling mutexes - * Indicates the availability of: - * pthread_mutex_getprioceiling - * pthread_mutex_setprioceiling - * pthread_mutexattr_getprioceiling - * pthread_mutexattr_getprotocol + - * pthread_mutexattr_setprioceiling - * pthread_mutexattr_setprotocol + - * - * _POSIX_THREAD_PROCESS_SHARED (== -1) - * If set, you can create mutexes and condition - * variables that can be shared with another - * process.If set, indicates the availability - * of: - * pthread_mutexattr_getpshared - * pthread_mutexattr_setpshared - * pthread_condattr_getpshared - * pthread_condattr_setpshared - * - * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) - * If == 200112L you can use the special *_r library - * functions that provide thread-safe behaviour - * - * _POSIX_READER_WRITER_LOCKS (== 200112L) - * If == 200112L, you can use read/write locks - * - * _POSIX_SPIN_LOCKS (== 200112L) - * If == 200112L, you can use spin locks - * - * _POSIX_BARRIERS (== 200112L) - * If == 200112L, you can use barriers - * - * + These functions provide both 'inherit' and/or - * 'protect' protocol, based upon these macro - * settings. - * - * ------------------------------------------------------------- - */ - -/* - * POSIX Options - */ -#undef _POSIX_THREADS -#define _POSIX_THREADS 200809L - -#undef _POSIX_READER_WRITER_LOCKS -#define _POSIX_READER_WRITER_LOCKS 200809L - -#undef _POSIX_SPIN_LOCKS -#define _POSIX_SPIN_LOCKS 200809L - -#undef _POSIX_BARRIERS -#define _POSIX_BARRIERS 200809L - -#undef _POSIX_THREAD_SAFE_FUNCTIONS -#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L - -#undef _POSIX_THREAD_ATTR_STACKSIZE -#define _POSIX_THREAD_ATTR_STACKSIZE 200809L - -/* - * The following options are not supported - */ -#undef _POSIX_THREAD_ATTR_STACKADDR -#define _POSIX_THREAD_ATTR_STACKADDR -1 - -#undef _POSIX_THREAD_PRIO_INHERIT -#define _POSIX_THREAD_PRIO_INHERIT -1 - -#undef _POSIX_THREAD_PRIO_PROTECT -#define _POSIX_THREAD_PRIO_PROTECT -1 - -/* TPS is not fully supported. */ -#undef _POSIX_THREAD_PRIORITY_SCHEDULING -#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 - -#undef _POSIX_THREAD_PROCESS_SHARED -#define _POSIX_THREAD_PROCESS_SHARED -1 - - -/* - * POSIX 1003.1-2001 Limits - * =========================== - * - * These limits are normally set in , which is not provided with - * pthreads-win32. - * - * PTHREAD_DESTRUCTOR_ITERATIONS - * Maximum number of attempts to destroy - * a thread's thread-specific data on - * termination (must be at least 4) - * - * PTHREAD_KEYS_MAX - * Maximum number of thread-specific data keys - * available per process (must be at least 128) - * - * PTHREAD_STACK_MIN - * Minimum supported stack size for a thread - * - * PTHREAD_THREADS_MAX - * Maximum number of threads supported per - * process (must be at least 64). - * - * SEM_NSEMS_MAX - * The maximum number of semaphores a process can have. - * (must be at least 256) - * - * SEM_VALUE_MAX - * The maximum value a semaphore can have. - * (must be at least 32767) - * - */ -#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS -#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 - -#undef PTHREAD_DESTRUCTOR_ITERATIONS -#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS - -#undef _POSIX_THREAD_KEYS_MAX -#define _POSIX_THREAD_KEYS_MAX 128 - -#undef PTHREAD_KEYS_MAX -#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX - -#undef PTHREAD_STACK_MIN -#define PTHREAD_STACK_MIN 0 - -#undef _POSIX_THREAD_THREADS_MAX -#define _POSIX_THREAD_THREADS_MAX 64 - - /* Arbitrary value */ -#undef PTHREAD_THREADS_MAX -#define PTHREAD_THREADS_MAX 2019 - -#undef _POSIX_SEM_NSEMS_MAX -#define _POSIX_SEM_NSEMS_MAX 256 - - /* Arbitrary value */ -#undef SEM_NSEMS_MAX -#define SEM_NSEMS_MAX 1024 - -#undef _POSIX_SEM_VALUE_MAX -#define _POSIX_SEM_VALUE_MAX 32767 - -#undef SEM_VALUE_MAX -#define SEM_VALUE_MAX INT_MAX - - -#if defined(__GNUC__) && !defined(__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * The Open Watcom C/C++ compiler uses a non-standard calling convention - * that passes function args in registers unless __cdecl is explicitly specified - * in exposed function prototypes. - * - * We force all calls to cdecl even though this could slow Watcom code down - * slightly. If you know that the Watcom compiler will be used to build both - * the DLL and application, then you can probably define this as a null string. - * Remember that pthread.h (this file) is used for both the DLL and application builds. - */ -#define PTW32_CDECL __cdecl - -#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX -# include -#else -/* - * Generic handle type - intended to extend uniqueness beyond - * that available with a simple pointer. It should scale for either - * IA-32 or IA-64. - */ -typedef struct { - void * p; /* Pointer to actual object */ - unsigned int x; /* Extra information - reuse count etc */ -} ptw32_handle_t; - -typedef ptw32_handle_t pthread_t; -typedef struct pthread_attr_t_ * pthread_attr_t; -typedef struct pthread_once_t_ pthread_once_t; -typedef struct pthread_key_t_ * pthread_key_t; -typedef struct pthread_mutex_t_ * pthread_mutex_t; -typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; -typedef struct pthread_cond_t_ * pthread_cond_t; -typedef struct pthread_condattr_t_ * pthread_condattr_t; -#endif -typedef struct pthread_rwlock_t_ * pthread_rwlock_t; -typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; -typedef struct pthread_spinlock_t_ * pthread_spinlock_t; -typedef struct pthread_barrier_t_ * pthread_barrier_t; -typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; - -/* - * ==================== - * ==================== - * POSIX Threads - * ==================== - * ==================== - */ - -enum { -/* - * pthread_attr_{get,set}detachstate - */ - PTHREAD_CREATE_JOINABLE = 0, /* Default */ - PTHREAD_CREATE_DETACHED = 1, - -/* - * pthread_attr_{get,set}inheritsched - */ - PTHREAD_INHERIT_SCHED = 0, - PTHREAD_EXPLICIT_SCHED = 1, /* Default */ - -/* - * pthread_{get,set}scope - */ - PTHREAD_SCOPE_PROCESS = 0, - PTHREAD_SCOPE_SYSTEM = 1, /* Default */ - -/* - * pthread_setcancelstate paramters - */ - PTHREAD_CANCEL_ENABLE = 0, /* Default */ - PTHREAD_CANCEL_DISABLE = 1, - -/* - * pthread_setcanceltype parameters - */ - PTHREAD_CANCEL_ASYNCHRONOUS = 0, - PTHREAD_CANCEL_DEFERRED = 1, /* Default */ - -/* - * pthread_mutexattr_{get,set}pshared - * pthread_condattr_{get,set}pshared - */ - PTHREAD_PROCESS_PRIVATE = 0, - PTHREAD_PROCESS_SHARED = 1, - -/* - * pthread_mutexattr_{get,set}robust - */ - PTHREAD_MUTEX_STALLED = 0, /* Default */ - PTHREAD_MUTEX_ROBUST = 1, - -/* - * pthread_barrier_wait - */ - PTHREAD_BARRIER_SERIAL_THREAD = -1 -}; - -/* - * ==================== - * ==================== - * Cancelation - * ==================== - * ==================== - */ -#define PTHREAD_CANCELED ((void *)(size_t) -1) - - -/* - * ==================== - * ==================== - * Once Key - * ==================== - * ==================== - */ -#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} - -struct pthread_once_t_ -{ - int done; /* indicates if user function has been executed */ - void * lock; - int reserved1; - int reserved2; -}; - - -/* - * ==================== - * ==================== - * Object initialisers - * ==================== - * ==================== - */ -#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1) -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2) -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3) - -/* - * Compatibility with LinuxThreads - */ -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER - -#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1) - -#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) - -#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1) - - -/* - * Mutex types. - */ -enum -{ - /* Compatibility with LinuxThreads */ - PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, - /* For compatibility with POSIX */ - PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL -}; - - -typedef struct ptw32_cleanup_t ptw32_cleanup_t; - -#if defined(_MSC_VER) -/* Disable MSVC 'anachronism used' warning */ -#pragma warning( disable : 4229 ) -#endif - -typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); - -#if defined(_MSC_VER) -#pragma warning( default : 4229 ) -#endif - -struct ptw32_cleanup_t -{ - ptw32_cleanup_callback_t routine; - void *arg; - struct ptw32_cleanup_t *prev; -}; - -#if defined(__CLEANUP_SEH) - /* - * WIN32 SEH version of cancel cleanup. - */ - -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - ptw32_cleanup_t _cleanup; \ - \ - _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ - _cleanup.arg = (_arg); \ - __try \ - { \ - -#define pthread_cleanup_pop( _execute ) \ - } \ - __finally \ - { \ - if( _execute || AbnormalTermination()) \ - { \ - (*(_cleanup.routine))( _cleanup.arg ); \ - } \ - } \ - } - -#else /* __CLEANUP_SEH */ - -#if defined(__CLEANUP_C) - - /* - * C implementation of PThreads cancel cleanup - */ - -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - ptw32_cleanup_t _cleanup; \ - \ - ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ - -#define pthread_cleanup_pop( _execute ) \ - (void) ptw32_pop_cleanup( _execute ); \ - } - -#else /* __CLEANUP_C */ - -#if defined(__CLEANUP_CXX) - - /* - * C++ version of cancel cleanup. - * - John E. Bossom. - */ - - class PThreadCleanup { - /* - * PThreadCleanup - * - * Purpose - * This class is a C++ helper class that is - * used to implement pthread_cleanup_push/ - * pthread_cleanup_pop. - * The destructor of this class automatically - * pops the pushed cleanup routine regardless - * of how the code exits the scope - * (i.e. such as by an exception) - */ - ptw32_cleanup_callback_t cleanUpRout; - void * obj; - int executeIt; - - public: - PThreadCleanup() : - cleanUpRout( 0 ), - obj( 0 ), - executeIt( 0 ) - /* - * No cleanup performed - */ - { - } - - PThreadCleanup( - ptw32_cleanup_callback_t routine, - void * arg ) : - cleanUpRout( routine ), - obj( arg ), - executeIt( 1 ) - /* - * Registers a cleanup routine for 'arg' - */ - { - } - - ~PThreadCleanup() - { - if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) - { - (void) (*cleanUpRout)( obj ); - } - } - - void execute( int exec ) - { - executeIt = exec; - } - }; - - /* - * C++ implementation of PThreads cancel cleanup; - * This implementation takes advantage of a helper - * class who's destructor automatically calls the - * cleanup routine if we exit our scope weirdly - */ -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ - (void *) (_arg) ); - -#define pthread_cleanup_pop( _execute ) \ - cleanup.execute( _execute ); \ - } - -#else - -#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. - -#endif /* __CLEANUP_CXX */ - -#endif /* __CLEANUP_C */ - -#endif /* __CLEANUP_SEH */ - -/* - * =============== - * =============== - * Methods - * =============== - * =============== - */ - -/* - * PThread Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, - int *detachstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, - void **stackaddr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, - size_t * stacksize); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, - int detachstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, - void *stackaddr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, - size_t stacksize); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, - struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, - const struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, - int); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *, - int *); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, - int inheritsched); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr, - int * inheritsched); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, - int); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, - int *); - -/* - * PThread Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, - const pthread_attr_t * attr, - void *(PTW32_CDECL *start) (void *), - void *arg); - -PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); - -PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, - pthread_t t2); - -PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); - -PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, - void **value_ptr); - -PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); - -PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); - -PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, - int *oldstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, - int *oldtype); - -PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); - -PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, - void (PTW32_CDECL *init_routine) (void)); - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX -PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); - -PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, - ptw32_cleanup_callback_t routine, - void *arg); -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Thread Specific Data Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, - void (PTW32_CDECL *destructor) (void *)); - -PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); - -PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, - const void *value); - -PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); - - -/* - * Mutex Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t - * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, - int pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust( - pthread_mutexattr_t *attr, - int robust); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust( - const pthread_mutexattr_t * attr, - int * robust); - -/* - * Barrier Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t - * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, - int pshared); - -/* - * Mutex Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, - const pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex); - -/* - * Spinlock Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); - -/* - * Barrier Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, - const pthread_barrierattr_t * attr, - unsigned int count); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); - -/* - * Condition Variable Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, - int pshared); - -/* - * Condition Variable Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, - const pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, - pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, - pthread_mutex_t * mutex, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); - -/* - * Scheduling - */ -PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, - int policy, - const struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, - int *policy, - struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); - -PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); - -/* - * Read-Write Lock Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, - const pthread_rwlockattr_t *attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, - int pshared); - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 - -/* - * Signal Functions. Should be defined in but MSVC and MinGW32 - * already have signal.h that don't define these. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); - -/* - * Non-portable functions - */ - -/* - * Compatibility with Linux. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, - int kind); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, - int *kind); - -/* - * Possibly supported by other POSIX threads implementations - */ -PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); -PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); -PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread); - -/* - * Useful if an application wants to statically link - * the lib rather than load the DLL at run-time. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); - -/* - * Features that are auto-detected at load/run time. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); -enum ptw32_features { - PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ - PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ -}; - -/* - * Register a system time change with the library. - * Causes the library to perform various functions - * in response to the change. Should be called whenever - * the application's top level window receives a - * WM_TIMECHANGE message. It can be passed directly to - * pthread_create() as a new thread if desired. - */ -PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); - -#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - -/* - * Returns the Win32 HANDLE for the POSIX thread. - */ -PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); -/* - * Returns the win32 thread ID for POSIX thread. - */ -PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread); - - -/* - * Protected Methods - * - * This function blocks until the given WIN32 handle - * is signaled or pthread_cancel had been called. - * This function allows the caller to hook into the - * PThreads cancel mechanism. It is implemented using - * - * WaitForMultipleObjects - * - * on 'waitHandle' and a manually reset WIN32 Event - * used to implement pthread_cancel. The 'timeout' - * argument to TimedWait is simply passed to - * WaitForMultipleObjects. - */ -PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); -PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, - DWORD timeout); - -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Thread-Safe C Runtime Library Mappings. - */ -#if !defined(_UWIN) -# if defined(NEED_ERRNO) - PTW32_DLLPORT int * PTW32_CDECL _errno( void ); -# else -# if !defined(errno) -# if (defined(_MT) || defined(_DLL)) - __declspec(dllimport) extern int * __cdecl _errno(void); -# define errno (*_errno()) -# endif -# endif -# endif -#endif - -/* - * Some compiler environments don't define some things. - */ -#if defined(__BORLANDC__) -# define _ftime ftime -# define _timeb timeb -#endif - -#if defined(__cplusplus) - -/* - * Internal exceptions - */ -class ptw32_exception {}; -class ptw32_exception_cancel : public ptw32_exception {}; -class ptw32_exception_exit : public ptw32_exception {}; - -#endif - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - -/* FIXME: This is only required if the library was built using SEH */ -/* - * Get internal SEH tag - */ -PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); - -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -#if !defined(PTW32_BUILD) - -#if defined(__CLEANUP_SEH) - -/* - * Redefine the SEH __except keyword to ensure that applications - * propagate our internal exceptions up to the library's internal handlers. - */ -#define __except( E ) \ - __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ - ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) - -#endif /* __CLEANUP_SEH */ - -#if defined(__CLEANUP_CXX) - -/* - * Redefine the C++ catch keyword to ensure that applications - * propagate our internal exceptions up to the library's internal handlers. - */ -#if defined(_MSC_VER) - /* - * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' - * if you want Pthread-Win32 cancelation and pthread_exit to work. - */ - -#if !defined(PtW32NoCatchWarn) - -#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") -#pragma message("------------------------------------------------------------------") -#pragma message("When compiling applications with MSVC++ and C++ exception handling:") -#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") -#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") -#pragma message(" cancelation and pthread_exit to work. For example:") -#pragma message("") -#pragma message(" #if defined(PtW32CatchAll)") -#pragma message(" PtW32CatchAll") -#pragma message(" #else") -#pragma message(" catch(...)") -#pragma message(" #endif") -#pragma message(" {") -#pragma message(" /* Catchall block processing */") -#pragma message(" }") -#pragma message("------------------------------------------------------------------") - -#endif - -#define PtW32CatchAll \ - catch( ptw32_exception & ) { throw; } \ - catch( ... ) - -#else /* _MSC_VER */ - -#define catch( E ) \ - catch( ptw32_exception & ) { throw; } \ - catch( E ) - -#endif /* _MSC_VER */ - -#endif /* __CLEANUP_CXX */ - -#endif /* ! PTW32_BUILD */ - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#if defined(PTW32__HANDLE_DEF) -# undef HANDLE -#endif -#if defined(PTW32__DWORD_DEF) -# undef DWORD -#endif - -#undef PTW32_LEVEL -#undef PTW32_LEVEL_MAX - -#endif /* ! RC_INVOKED */ - -#endif /* PTHREAD_H */ diff --git a/pthreads/sched.h b/pthreads/sched.h deleted file mode 100644 index f36a97a..0000000 --- a/pthreads/sched.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Module: sched.h - * - * Purpose: - * Provides an implementation of POSIX realtime extensions - * as defined in - * - * POSIX 1003.1b-1993 (POSIX.1b) - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#if !defined(_SCHED_H) -#define _SCHED_H - -#undef PTW32_SCHED_LEVEL - -#if defined(_POSIX_SOURCE) -#define PTW32_SCHED_LEVEL 0 -/* Early POSIX */ -#endif - -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 -#undef PTW32_SCHED_LEVEL -#define PTW32_SCHED_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_SCHED_LEVEL -#define PTW32_SCHED_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_SCHED_LEVEL_MAX 3 - -#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL) -#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX -/* Include everything */ -#endif - - -#if defined(__GNUC__) && !defined(__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include -#endif -#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */ - -#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN) -# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX -/* For pid_t */ -# include -/* Required by Unix 98 */ -# include -# else - typedef int pid_t; -# endif -#else - typedef int pid_t; -#endif - -/* Thread scheduling policies */ - -enum { - SCHED_OTHER = 0, - SCHED_FIFO, - SCHED_RR, - SCHED_MIN = SCHED_OTHER, - SCHED_MAX = SCHED_RR -}; - -struct sched_param { - int sched_priority; -}; - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -PTW32_DLLPORT int __cdecl sched_yield (void); - -PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); - -PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); - -PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); - -PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); - -/* - * Note that this macro returns ENOTSUP rather than - * ENOSYS as might be expected. However, returning ENOSYS - * should mean that sched_get_priority_{min,max} are - * not implemented as well as sched_rr_get_interval. - * This is not the case, since we just don't support - * round-robin scheduling. Therefore I have chosen to - * return the same value as sched_setscheduler when - * SCHED_RR is passed to it. - */ -#define sched_rr_get_interval(_pid, _interval) \ - ( errno = ENOTSUP, (int) -1 ) - - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#undef PTW32_SCHED_LEVEL -#undef PTW32_SCHED_LEVEL_MAX - -#endif /* !_SCHED_H */ - diff --git a/pthreads/semaphore.h b/pthreads/semaphore.h deleted file mode 100644 index c6e9407..0000000 --- a/pthreads/semaphore.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Module: semaphore.h - * - * Purpose: - * Semaphores aren't actually part of the PThreads standard. - * They are defined by the POSIX Standard: - * - * POSIX 1003.1b-1993 (POSIX.1b) - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#if !defined( SEMAPHORE_H ) -#define SEMAPHORE_H - -#undef PTW32_SEMAPHORE_LEVEL - -#if defined(_POSIX_SOURCE) -#define PTW32_SEMAPHORE_LEVEL 0 -/* Early POSIX */ -#endif - -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 -#undef PTW32_SEMAPHORE_LEVEL -#define PTW32_SEMAPHORE_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_SEMAPHORE_LEVEL -#define PTW32_SEMAPHORE_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_SEMAPHORE_LEVEL_MAX 3 - -#if !defined(PTW32_SEMAPHORE_LEVEL) -#define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX -/* Include everything */ -#endif - -#if defined(__GNUC__) && ! defined (__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include -#endif -#endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */ - -#define _POSIX_SEMAPHORES - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -#if !defined(HAVE_MODE_T) -typedef unsigned int mode_t; -#endif - - -typedef struct sem_t_ * sem_t; - -PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, - int pshared, - unsigned int value); - -PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, - const struct timespec * abstime); - -PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, - int count); - -PTW32_DLLPORT int __cdecl sem_open (const char * name, - int oflag, - mode_t mode, - unsigned int value); - -PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_unlink (const char * name); - -PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, - int * sval); - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#undef PTW32_SEMAPHORE_LEVEL -#undef PTW32_SEMAPHORE_LEVEL_MAX - -#endif /* !SEMAPHORE_H */ diff --git a/status.o.REMOVED.git-id b/status.o.REMOVED.git-id index 6ca3b1e..09792e2 100644 --- a/status.o.REMOVED.git-id +++ b/status.o.REMOVED.git-id @@ -1 +1 @@ -9aa844df5159c2a246895c0eb2a306f53d0a36fd \ No newline at end of file +00319fecb996b4196487ff551c1c4fcd04063dcc \ No newline at end of file diff --git a/structs.h b/structs.h index 3fac6c5..674d430 100644 --- a/structs.h +++ b/structs.h @@ -44,6 +44,7 @@ typedef struct AppData int touchy; int mapMoved; + QuadTree *mapContinue; uint64_t lastFrameTime; } AppData; diff --git a/view1090.REMOVED.git-id b/view1090.REMOVED.git-id index 710990e..b424937 100644 --- a/view1090.REMOVED.git-id +++ b/view1090.REMOVED.git-id @@ -1 +1 @@ -cbbacac08ce30232fcad4a508249c7e61768effa \ No newline at end of file +c71ae5a169099a989da238f49c409fb014f13fd2 \ No newline at end of file diff --git a/view1090.c b/view1090.c index b3e8210..d2a32cb 100644 --- a/view1090.c +++ b/view1090.c @@ -89,9 +89,9 @@ void view1090InitConfig(void) { // void view1090Init(void) { - pthread_mutex_init(&Modes.pDF_mutex,NULL); - pthread_mutex_init(&Modes.data_mutex,NULL); - pthread_cond_init(&Modes.data_cond,NULL); + // pthread_mutex_init(&Modes.pDF_mutex,NULL); + // pthread_mutex_init(&Modes.data_mutex,NULL); + // pthread_cond_init(&Modes.data_cond,NULL); #ifdef _WIN32 if ( (!Modes.wsaData.wVersion) diff --git a/view1090.o.REMOVED.git-id b/view1090.o.REMOVED.git-id index 56946c2..2e96c58 100644 --- a/view1090.o.REMOVED.git-id +++ b/view1090.o.REMOVED.git-id @@ -1 +1 @@ -790297577270307a97648484360f0eeb3de83233 \ No newline at end of file +71f6442ad1518278cce9fee8235924b9bbe56cc6 \ No newline at end of file