summaryrefslogtreecommitdiffstats
path: root/x11vnc/rates.c
diff options
context:
space:
mode:
Diffstat (limited to 'x11vnc/rates.c')
-rw-r--r--x11vnc/rates.c732
1 files changed, 0 insertions, 732 deletions
diff --git a/x11vnc/rates.c b/x11vnc/rates.c
deleted file mode 100644
index ee9ca05..0000000
--- a/x11vnc/rates.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- rates.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "scan.h"
-
-int measure_speeds = 1;
-int speeds_net_rate = 0;
-int speeds_net_rate_measured = 0;
-int speeds_net_latency = 0;
-int speeds_net_latency_measured = 0;
-int speeds_read_rate = 0;
-int speeds_read_rate_measured = 0;
-
-
-int get_cmp_rate(void);
-int get_raw_rate(void);
-void initialize_speeds(void);
-int get_read_rate(void);
-int link_rate(int *latency, int *netrate);
-int get_net_rate(void);
-int get_net_latency(void);
-void measure_send_rates(int init);
-
-
-static void measure_display_hook(rfbClientPtr cl);
-static int get_rate(int which);
-static int get_latency(void);
-
-
-static void measure_display_hook(rfbClientPtr cl) {
- ClientData *cd = (ClientData *) cl->clientData;
- if (! cd) {
- return;
- }
- dtime0(&cd->timer);
-}
-
-static int get_rate(int which) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int irate, irate_min = 1; /* 1 KB/sec */
- int irate_max = 100000; /* 100 MB/sec */
- int count = 0;
- double slowest = -1.0, rate;
- static double save_rate = 1000 * NETRATE0;
-
- if (!screen) {
- return 0;
- }
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd = (ClientData *) cl->clientData;
-
- if (! cd) {
- continue;
- }
- if (cl->state != RFB_NORMAL) {
- continue;
- }
- if (cd->send_cmp_rate == 0.0 || cd->send_raw_rate == 0.0) {
- continue;
- }
- count++;
-
- if (which == 0) {
- rate = cd->send_cmp_rate;
- } else {
- rate = cd->send_raw_rate;
- }
- if (slowest == -1.0 || rate < slowest) {
- slowest = rate;
- }
-
- }
- rfbReleaseClientIterator(iter);
-
- if (! count) {
- return NETRATE0;
- }
-
- if (slowest == -1.0) {
- slowest = save_rate;
- } else {
- save_rate = slowest;
- }
-
- irate = (int) (slowest/1000.0);
- if (irate < irate_min) {
- irate = irate_min;
- }
- if (irate > irate_max) {
- irate = irate_max;
- }
-if (0) fprintf(stderr, "get_rate(%d) %d %.3f/%.3f\n", which, irate, save_rate, slowest);
-
- return irate;
-}
-
-static int get_latency(void) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int ilat, ilat_min = 1; /* 1 ms */
- int ilat_max = 2000; /* 2 sec */
- double slowest = -1.0, lat;
- static double save_lat = ((double) LATENCY0)/1000.0;
- int count = 0;
-
- if (!screen) {
- return 0;
- }
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd = (ClientData *) cl->clientData;
-
- if (! cd) {
- continue;
- }
- if (cl->state != RFB_NORMAL) {
- continue;
- }
- if (cd->latency == 0.0) {
- continue;
- }
- count++;
-
- lat = cd->latency;
- if (slowest == -1.0 || lat > slowest) {
- slowest = lat;
- }
- }
- rfbReleaseClientIterator(iter);
-
- if (! count) {
- return LATENCY0;
- }
-
- if (slowest == -1.0) {
- slowest = save_lat;
- } else {
- save_lat = slowest;
- }
-
- ilat = (int) (slowest * 1000.0);
- if (ilat < ilat_min) {
- ilat = ilat_min;
- }
- if (ilat > ilat_max) {
- ilat = ilat_max;
- }
-
- return ilat;
-}
-
-int get_cmp_rate(void) {
- return get_rate(0);
-}
-
-int get_raw_rate(void) {
- return get_rate(1);
-}
-
-void initialize_speeds(void) {
- char *s, *s_in, *p;
- int i;
-
- speeds_read_rate = 0;
- speeds_net_rate = 0;
- speeds_net_latency = 0;
- if (! speeds_str || *speeds_str == '\0') {
- s_in = strdup("");
- } else {
- s_in = strdup(speeds_str);
- }
-
- if (!strcmp(s_in, "modem")) {
- s = strdup("6,4,200");
- } else if (!strcmp(s_in, "dsl")) {
- s = strdup("6,100,50");
- } else if (!strcmp(s_in, "lan")) {
- s = strdup("6,5000,1");
- } else {
- s = strdup(s_in);
- }
-
- p = strtok(s, ",");
- i = 0;
- while (p) {
- double val;
- if (*p != '\0') {
- val = atof(p);
- if (i==0) {
- speeds_read_rate = (int) 1000000 * val;
- } else if (i==1) {
- speeds_net_rate = (int) 1000 * val;
- } else if (i==2) {
- speeds_net_latency = (int) val;
- }
- }
- i++;
- p = strtok(NULL, ",");
- }
- free(s);
- free(s_in);
-
- if (! speeds_read_rate) {
- int n = 0;
- double dt, timer;
-#ifdef MACOSX
- if (macosx_console && macosx_read_opengl && fullscreen) {
- copy_image(fullscreen, 0, 0, 0, 0);
- usleep(10 * 1000);
- }
-#endif
-
- dtime0(&timer);
- if (fullscreen) {
- copy_image(fullscreen, 0, 0, 0, 0);
- n = fullscreen->bytes_per_line * fullscreen->height;
- } else if (scanline) {
- copy_image(scanline, 0, 0, 0, 0);
- n = scanline->bytes_per_line * scanline->height;
- }
- dt = dtime(&timer);
- if (n && dt > 0.0) {
- double rate = ((double) n) / dt;
- speeds_read_rate_measured = (int) (rate/1000000.0);
- if (speeds_read_rate_measured < 1) {
- speeds_read_rate_measured = 1;
- } else {
- rfbLog("fb read rate: %d MB/sec\n",
- speeds_read_rate_measured);
- }
- }
- }
-}
-
-int get_read_rate(void) {
- if (speeds_read_rate) {
- return speeds_read_rate;
- }
- if (speeds_read_rate_measured) {
- return speeds_read_rate_measured;
- }
- return 0;
-}
-
-int link_rate(int *latency, int *netrate) {
- *latency = get_net_latency();
- *netrate = get_net_rate();
-
- if (speeds_str) {
- if (!strcmp(speeds_str, "modem")) {
- return LR_DIALUP;
- } else if (!strcmp(speeds_str, "dsl")) {
- return LR_BROADBAND;
- } else if (!strcmp(speeds_str, "lan")) {
- return LR_LAN;
- }
- }
-
- if (*latency == LATENCY0 && *netrate == NETRATE0) {
- return LR_UNSET;
- } else if (*latency > 150 || *netrate < 20) {
- return LR_DIALUP;
- } else if (*latency > 50 || *netrate < 150) {
- return LR_BROADBAND;
- } else if (*latency < 10 && *netrate > 300) {
- return LR_LAN;
- } else {
- return LR_UNKNOWN;
- }
-}
-
-int get_net_rate(void) {
- int spm = speeds_net_rate_measured;
- if (speeds_net_rate) {
- return speeds_net_rate;
- }
- if (! spm || spm == NETRATE0) {
- speeds_net_rate_measured = get_cmp_rate();
- }
- if (speeds_net_rate_measured) {
- return speeds_net_rate_measured;
- }
- return 0;
-}
-
-int get_net_latency(void) {
- int spm = speeds_net_latency_measured;
- if (speeds_net_latency) {
- return speeds_net_latency;
- }
- if (! spm || spm == LATENCY0) {
- speeds_net_latency_measured = get_latency();
- }
- if (speeds_net_latency_measured) {
- return speeds_net_latency_measured;
- }
- return 0;
-}
-
-void measure_send_rates(int init) {
- double cmp_rate, raw_rate;
- static double now, start = 0.0;
- static rfbDisplayHookPtr orig_display_hook = NULL;
- double cmp_max = 1.0e+08; /* 100 MB/sec */
- double cmp_min = 1000.0; /* 9600baud */
- double lat_max = 5.0; /* 5 sec */
- double lat_min = .0005; /* 0.5 ms */
- int min_cmp = 10000, nclients;
- rfbClientIteratorPtr iter;
- rfbClientPtr cl0, cl;
- int msg = 0, clcnt0 = 0, cc;
- int db = 0, ouch_db = 0, ouch = 0;
-
- if (! measure_speeds) {
- return;
- }
- if (speeds_net_rate && speeds_net_latency) {
- return;
- }
- if (!client_count) {
- return;
- }
-
- if (! orig_display_hook) {
- orig_display_hook = screen->displayHook;
- }
-
- if (start == 0.0) {
- dtime(&start);
- }
-
- dtime0(&now);
- if (now < last_client_gone+4.0) {
- return;
- }
- now = now - start;
-
- nclients = 0;
-
- if (!screen) {
- return;
- }
-
- cl0 = NULL;
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd = (ClientData *) cl->clientData;
-
- if (! cd) {
- continue;
- }
- if (cd->send_cmp_rate > 0.0) {
- continue;
- }
- if (cl->onHold) {
- continue;
- }
- nclients++;
- if (cl0 == NULL) {
- cl0 = cl;
- }
- }
- rfbReleaseClientIterator(iter);
-
- cl = cl0;
- cc = 0;
-
- while (cl != NULL && cc++ == 0) {
- int defer, i, cbs, rbs;
- char *httpdir;
- double dt, dt1 = 0.0, dt2, dt3;
- double tm, spin_max = 15.0, spin_lat_max = 1.5;
- int got_t2 = 0, got_t3 = 0;
- ClientData *cd = (ClientData *) cl->clientData;
-
-#if 0
- for (i=0; i<MAX_ENCODINGS; i++) {
- cbs += cl->bytesSent[i];
- }
- rbs = cl->rawBytesEquivalent;
-#else
-#if LIBVNCSERVER_HAS_STATS
- cbs = rfbStatGetSentBytes(cl);
- rbs = rfbStatGetSentBytesIfRaw(cl);
-#endif
-#endif
-
- if (init) {
-
-if (db) fprintf(stderr, "%d client num rects req: %d mod: %d cbs: %d "
- "rbs: %d dt1: %.3f t: %.3f\n", init,
- (int) sraRgnCountRects(cl->requestedRegion),
- (int) sraRgnCountRects(cl->modifiedRegion), cbs, rbs, dt1, now);
-
- cd->timer = dnow();
- cd->cmp_bytes_sent = cbs;
- cd->raw_bytes_sent = rbs;
- continue;
- }
-
- /* first part of the bulk transfer of initial screen */
- dt1 = dtime(&cd->timer);
-
-if (db) fprintf(stderr, "%d client num rects req: %d mod: %d cbs: %d "
- "rbs: %d dt1: %.3f t: %.3f\n", init,
- (int) sraRgnCountRects(cl->requestedRegion),
- (int) sraRgnCountRects(cl->modifiedRegion), cbs, rbs, dt1, now);
-
- if (dt1 <= 0.0) {
- continue;
- }
-
- cbs = cbs - cd->cmp_bytes_sent;
- rbs = rbs - cd->raw_bytes_sent;
-
- if (cbs < min_cmp) {
- continue;
- }
-
- if (ouch_db) fprintf(stderr, "START-OUCH: %d\n", client_count);
- clcnt0 = client_count;
-#define OUCH ( ouch || (ouch = (!client_count || client_count != clcnt0 || dnow() < last_client_gone+4.0)) )
-
- rfbPE(1000);
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-A\n");
- if (OUCH) continue;
-
- if (use_threads) LOCK(cl->updateMutex);
-
- if (sraRgnCountRects(cl->modifiedRegion)) {
- rfbPE(1000);
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-B\n");
- if (use_threads) UNLOCK(cl->updateMutex);
- if (OUCH) continue;
- }
-
- if (use_threads) UNLOCK(cl->updateMutex);
-
- defer = screen->deferUpdateTime;
- httpdir = screen->httpDir;
- screen->deferUpdateTime = 0;
- screen->httpDir = NULL;
-
- /* mark a small rectangle: */
- mark_rect_as_modified(0, 0, 16, 16, 1);
-
- dtime0(&tm);
-
- dt2 = 0.0;
- dt3 = 0.0;
-
- if (dt1 < 0.25) {
- /* try to cut it down to avoid long pauses. */
- spin_max = 5.0;
- }
-
- /* when req1 = 1 mod1 == 0, end of 2nd part of bulk transfer */
- while (1) {
- int req0, req1, mod0, mod1;
-
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-C1\n");
- if (OUCH) break;
-
- if (use_threads) LOCK(cl->updateMutex);
-
- req0 = sraRgnCountRects(cl->requestedRegion);
- mod0 = sraRgnCountRects(cl->modifiedRegion);
-
- if (use_threads) UNLOCK(cl->updateMutex);
-
- if (use_threads) {
- usleep(1000);
- } else {
- if (mod0) {
- rfbPE(1000);
- } else {
- rfbCFD(1000);
- }
- }
- dt = dtime(&tm);
- dt2 += dt;
- if (dt2 > spin_max) {
- break;
- }
-
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-C2\n");
- if (OUCH) break;
-
- if (use_threads) LOCK(cl->updateMutex);
-
- req1 = sraRgnCountRects(cl->requestedRegion);
- mod1 = sraRgnCountRects(cl->modifiedRegion);
-
- if (use_threads) UNLOCK(cl->updateMutex);
-
-if (db) fprintf(stderr, "dt2 calc: num rects req: %d/%d mod: %d/%d "
- "fbu-sent: %d dt: %.4f dt2: %.4f tm: %.4f\n",
- req0, req1, mod0, mod1,
-#if 0
- cl->framebufferUpdateMessagesSent,
-#else
-#if LIBVNCSERVER_HAS_STATS
- rfbStatGetMessageCountSent(cl, rfbFramebufferUpdate),
-#endif
-#endif
- dt, dt2, tm);
- if (req1 != 0 && mod1 == 0) {
- got_t2 = 1;
- break;
- }
- }
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-D\n");
- if (OUCH) goto ouch;
-
- if (! got_t2) {
- dt2 = 0.0;
- } else {
- int tr, trm = 3;
- double dts[10];
-
- /*
- * Note: since often select(2) cannot sleep
- * less than 1/HZ (e.g. 10ms), the resolution
- * of the latency may be messed up by something
- * of this order. Effect may occur on both ends,
- * i.e. the viewer may not respond immediately.
- */
-
- for (tr = 0; tr < trm; tr++) {
- usleep(5000);
-
- /* mark a 2nd small rectangle: */
- mark_rect_as_modified(0, 0, 16, 16, 1);
- i = 0;
- dtime0(&tm);
- dt3 = 0.0;
-
- /*
- * when req1 > 0 and mod1 == 0, we say
- * that is the "ping" time.
- */
- while (1) {
- int req0, req1, mod0, mod1;
-
- if (use_threads) LOCK(cl->updateMutex);
-
- req0 = sraRgnCountRects(cl->requestedRegion);
- mod0 = sraRgnCountRects(cl->modifiedRegion);
-
- if (use_threads) UNLOCK(cl->updateMutex);
-
- if (i == 0) {
- rfbPE(0);
- } else {
- if (use_threads) {
- usleep(1000);
- } else {
- /* try to get it all */
- rfbCFD(1000*1000);
- }
- }
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-E\n");
- if (OUCH) goto ouch;
- dt = dtime(&tm);
- i++;
-
- dt3 += dt;
- if (dt3 > spin_lat_max) {
- break;
- }
-
- if (use_threads) LOCK(cl->updateMutex);
-
- req1 = sraRgnCountRects(cl->requestedRegion);
- mod1 = sraRgnCountRects(cl->modifiedRegion);
-
- if (use_threads) UNLOCK(cl->updateMutex);
-
-if (db) fprintf(stderr, "dt3 calc: num rects req: %d/%d mod: %d/%d "
- "fbu-sent: %d dt: %.4f dt3: %.4f tm: %.4f\n",
- req0, req1, mod0, mod1,
-#if 0
- cl->framebufferUpdateMessagesSent,
-#else
-#if LIBVNCSERVER_HAS_STATS
- rfbStatGetMessageCountSent(cl, rfbFramebufferUpdate),
-#endif
-#endif
- dt, dt3, tm);
-
- if (req1 != 0 && mod1 == 0) {
- dts[got_t3++] = dt3;
- break;
- }
- }
- }
-
- if (! got_t3) {
- dt3 = 0.0;
- } else {
- if (got_t3 == 1) {
- dt3 = dts[0];
- } else if (got_t3 == 2) {
- dt3 = dts[1];
- } else {
- if (dts[2] > 0.0) {
- double rat = dts[1]/dts[2];
- if (rat > 0.5 && rat < 2.0) {
- dt3 = dts[1]+dts[2];
- dt3 *= 0.5;
- } else {
- dt3 = dts[1];
- }
- } else {
- dt3 = dts[1];
- }
- }
- }
- }
-
- ouch:
-
- screen->deferUpdateTime = defer;
- screen->httpDir = httpdir;
-
- if (OUCH && ouch_db) fprintf(stderr, "***OUCH-F\n");
- if (OUCH) break;
-
- dt = dt1 + dt2;
-
-
- if (dt3 <= dt2/2.0) {
- /* guess only 1/2 a ping for reply... */
- dt = dt - dt3/2.0;
- }
-
- cmp_rate = cbs/dt;
- raw_rate = rbs/dt;
-
- if (cmp_rate > cmp_max) {
- cmp_rate = cmp_max;
- }
- if (cmp_rate <= cmp_min) {
- cmp_rate = cmp_min;
- }
-
- cd->send_cmp_rate = cmp_rate;
- cd->send_raw_rate = raw_rate;
-
- if (dt3 > lat_max) {
- dt3 = lat_max;
- }
- if (dt3 <= lat_min) {
- dt3 = lat_min;
- }
-
- cd->latency = dt3;
-
- rfbLog("client %d network rate %.1f KB/sec (%.1f eff KB/sec)\n",
- cd->uid, cmp_rate/1000.0, raw_rate/1000.0);
- rfbLog("client %d latency: %.1f ms\n", cd->uid, 1000.0*dt3);
- rfbLog("dt1: %.4f, dt2: %.4f dt3: %.4f bytes: %d\n",
- dt1, dt2, dt3, cbs);
- msg = 1;
- }
-
- if (msg) {
- int link, latency, netrate;
- char *str = "error";
-
- link = link_rate(&latency, &netrate);
- if (link == LR_UNSET) {
- str = "LR_UNSET";
- } else if (link == LR_UNKNOWN) {
- str = "LR_UNKNOWN";
- } else if (link == LR_DIALUP) {
- str = "LR_DIALUP";
- } else if (link == LR_BROADBAND) {
- str = "LR_BROADBAND";
- } else if (link == LR_LAN) {
- str = "LR_LAN";
- }
- rfbLog("link_rate: %s - %d ms, %d KB/s\n", str, latency,
- netrate);
- }
-
- if (init) {
- if (nclients) {
- screen->displayHook = measure_display_hook;
- }
- } else {
- screen->displayHook = orig_display_hook;
- }
-}
-
OpenPOWER on IntegriCloud