Skip to content

Commit 496b5ef

Browse files
author
Volodymyr Samokhatko
committed
tight: multithreaded
1 parent 0353465 commit 496b5ef

File tree

5 files changed

+1602
-1310
lines changed

5 files changed

+1602
-1310
lines changed

include/rfb/rfb.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ typedef UINT32 in_addr_t;
8484
#endif
8585
#endif
8686

87+
/* Maximum number of threads to use for multithreaded encoding, regardless of
88+
the CPU count */
89+
#define MAX_ENCODING_THREADS 8
90+
8791
struct _rfbClientRec;
8892
struct _rfbScreenInfo;
8993
struct rfbCursor;
@@ -372,6 +376,8 @@ typedef struct _rfbScreenInfo
372376
#ifdef LIBVNCSERVER_HAVE_LIBZ
373377
rfbSetXCutTextUTF8ProcPtr setXCutTextUTF8;
374378
#endif
379+
rfbBool rfbMT;
380+
int rfbNumThreads;
375381
} rfbScreenInfo, *rfbScreenInfoPtr;
376382

377383

@@ -705,6 +711,16 @@ typedef struct _rfbClientRec {
705711
rfbBool tightUsePixelFormat24;
706712
void *tightTJ;
707713
int tightPngDstDataLen;
714+
715+
/* Multithreaded tight encoding. */
716+
717+
rfbBool threadInit;
718+
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
719+
pthread_t thnd[MAX_ENCODING_THREADS];
720+
#elif defined(LIBVNCSERVER_HAVE_WIN32THREADS)
721+
uintptr_t thnd[MAX_ENCODING_THREADS];
722+
#endif
723+
708724
#endif
709725
#endif
710726
} rfbClientRec, *rfbClientPtr;

src/libvncserver/cargs.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ rfbUsage(void)
6060
fprintf(stderr, "-listenv6 ipv6addr listen for IPv6 connections only on network interface with\n");
6161
fprintf(stderr, " addr ipv6addr. '-listen localhost' and hostname work too.\n");
6262
#endif
63+
#if defined(LIBVNCSERVER_HAVE_LIBPTHREAD) || defined(LIBVNCSERVER_HAVE_WIN32THREADS)
64+
fprintf(stderr, "-nomt disable multithreaded Tight encoding\n");
65+
fprintf(stderr, "-nthreads N specify number of threads (1 <= N <= %d) to use with\n",
66+
MAX_ENCODING_THREADS);
67+
fprintf(stderr, " multithreaded Tight encoding [default: 1 per CPU core,\n");
68+
fprintf(stderr, " max. %d]\n", MAX_ENCODING_THREADS);
69+
#endif
6370

6471
for(extension=rfbGetExtensionIterator();extension;extension=extension->next)
6572
if(extension->usage)
@@ -202,6 +209,20 @@ rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
202209
}
203210
rfbScreen->listen6Interface = argv[++i];
204211
#endif
212+
#if defined(LIBVNCSERVER_HAVE_LIBPTHREAD) || defined(LIBVNCSERVER_HAVE_WIN32THREADS)
213+
} else if (strcmp(argv[i], "-nomt") == 0) {
214+
rfbScreen->rfbMT = FALSE;
215+
} else if (strcmp(argv[i], "-nthreads") == 0) {
216+
if (i + 1 >= *argc) {
217+
rfbUsage();
218+
return FALSE;
219+
}
220+
rfbScreen->rfbNumThreads = atoi(argv[++i]);
221+
if (rfbScreen->rfbNumThreads < 1 || rfbScreen->rfbNumThreads > MAX_ENCODING_THREADS) {
222+
rfbUsage();
223+
return FALSE;
224+
}
225+
#endif
205226
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
206227
} else if (strcmp(argv[i], "-sslkeyfile") == 0) { /* -sslkeyfile sslkeyfile */
207228
if (i + 1 >= *argc) {

src/libvncserver/main.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@
1010
* see GPL (latest version) for full details
1111
*/
1212

13+
#include <rfb/rfbconfig.h>
14+
15+
#if LIBVNCSERVER_HAVE_SCHED_H
16+
#define _GNU_SOURCE
17+
#include <sched.h>
18+
#endif
19+
1320
#ifdef __STRICT_ANSI__
1421
#define _BSD_SOURCE
1522
#endif
1623
#include <rfb/rfb.h>
24+
1725
#include <rfb/rfbregion.h>
1826
#include "private.h"
1927

@@ -55,6 +63,13 @@ char rfbEndianTest = (1==0);
5563
char rfbEndianTest = (1==1);
5664
#endif
5765

66+
#ifndef min
67+
inline static int min(int a, int b)
68+
{
69+
return a > b ? b : a;
70+
}
71+
#endif
72+
5873
/*
5974
* Protocol extensions
6075
*/
@@ -996,11 +1011,40 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
9961011

9971012
screen->permitFileTransfer = FALSE;
9981013

1014+
screen->rfbMT = TRUE;
1015+
screen->rfbNumThreads = 0;
1016+
9991017
if(!rfbProcessArguments(screen,argc,argv)) {
10001018
free(screen);
10011019
return NULL;
10021020
}
10031021

1022+
#if defined(LIBVNCSERVER_HAVE_LIBPTHREAD) || defined(LIBVNCSERVER_HAVE_WIN32THREADS)
1023+
#if defined(WIN32) || defined(__MINGW32__)
1024+
DWORD64 dwProcessAffinity, dwSystemAffinity;
1025+
GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinity, &dwSystemAffinity);
1026+
const int np = __popcnt64(dwProcessAffinity);
1027+
#elif LIBVNCSERVER_HAVE_SCHED_H
1028+
cpu_set_t cs;
1029+
CPU_ZERO(&cs);
1030+
sched_getaffinity(0, sizeof(cs), &cs);
1031+
const int np = CPU_COUNT(&cs);
1032+
#else
1033+
const int np = 1;
1034+
#endif
1035+
if (np == -1 && screen->rfbMT) {
1036+
rfbLog("WARNING: Could not determine CPU count. Multithreaded encoding disabled.\n");
1037+
screen->rfbMT = FALSE;
1038+
}
1039+
if (!screen->rfbMT) screen->rfbNumThreads = 1;
1040+
else if (screen->rfbNumThreads < 1) screen->rfbNumThreads = min(np, 4);
1041+
if (screen->rfbNumThreads > np) {
1042+
rfbLog("NOTICE: Encoding thread count has been clamped to CPU count\n");
1043+
screen->rfbNumThreads = np;
1044+
}
1045+
#endif
1046+
1047+
10041048
#ifdef WIN32
10051049
{
10061050
DWORD dummy=255;

src/libvncserver/rfbserver.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,15 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
504504
}
505505
}
506506

507+
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
508+
/* Multithreaded tight encoding. */
509+
510+
cl->threadInit = FALSE;
511+
#if defined(LIBVNCSERVER_HAVE_LIBPTHREAD) || defined(LIBVNCSERVER_HAVE_WIN32THREADS)
512+
memset(cl->thnd, 0, sizeof(cl->thnd));
513+
#endif
514+
#endif
515+
507516
for(extension = rfbGetExtensionIterator(); extension;
508517
extension=extension->next) {
509518
void* data = NULL;

0 commit comments

Comments
 (0)