Skip to content

Commit

Permalink
tight: multithreaded
Browse files Browse the repository at this point in the history
  • Loading branch information
Volodymyr Samokhatko committed Mar 17, 2023
1 parent 0353465 commit 496b5ef
Show file tree
Hide file tree
Showing 5 changed files with 1,602 additions and 1,310 deletions.
16 changes: 16 additions & 0 deletions include/rfb/rfb.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ typedef UINT32 in_addr_t;
#endif
#endif

/* Maximum number of threads to use for multithreaded encoding, regardless of
the CPU count */
#define MAX_ENCODING_THREADS 8

struct _rfbClientRec;
struct _rfbScreenInfo;
struct rfbCursor;
Expand Down Expand Up @@ -372,6 +376,8 @@ typedef struct _rfbScreenInfo
#ifdef LIBVNCSERVER_HAVE_LIBZ
rfbSetXCutTextUTF8ProcPtr setXCutTextUTF8;
#endif
rfbBool rfbMT;
int rfbNumThreads;
} rfbScreenInfo, *rfbScreenInfoPtr;


Expand Down Expand Up @@ -705,6 +711,16 @@ typedef struct _rfbClientRec {
rfbBool tightUsePixelFormat24;
void *tightTJ;
int tightPngDstDataLen;

/* Multithreaded tight encoding. */

rfbBool threadInit;
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
pthread_t thnd[MAX_ENCODING_THREADS];
#elif defined(LIBVNCSERVER_HAVE_WIN32THREADS)
uintptr_t thnd[MAX_ENCODING_THREADS];
#endif

#endif
#endif
} rfbClientRec, *rfbClientPtr;
Expand Down
21 changes: 21 additions & 0 deletions src/libvncserver/cargs.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ rfbUsage(void)
fprintf(stderr, "-listenv6 ipv6addr listen for IPv6 connections only on network interface with\n");
fprintf(stderr, " addr ipv6addr. '-listen localhost' and hostname work too.\n");
#endif
#if defined(LIBVNCSERVER_HAVE_LIBPTHREAD) || defined(LIBVNCSERVER_HAVE_WIN32THREADS)
fprintf(stderr, "-nomt disable multithreaded Tight encoding\n");
fprintf(stderr, "-nthreads N specify number of threads (1 <= N <= %d) to use with\n",
MAX_ENCODING_THREADS);
fprintf(stderr, " multithreaded Tight encoding [default: 1 per CPU core,\n");
fprintf(stderr, " max. %d]\n", MAX_ENCODING_THREADS);
#endif

for(extension=rfbGetExtensionIterator();extension;extension=extension->next)
if(extension->usage)
Expand Down Expand Up @@ -202,6 +209,20 @@ rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
}
rfbScreen->listen6Interface = argv[++i];
#endif
#if defined(LIBVNCSERVER_HAVE_LIBPTHREAD) || defined(LIBVNCSERVER_HAVE_WIN32THREADS)
} else if (strcmp(argv[i], "-nomt") == 0) {
rfbScreen->rfbMT = FALSE;
} else if (strcmp(argv[i], "-nthreads") == 0) {
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->rfbNumThreads = atoi(argv[++i]);
if (rfbScreen->rfbNumThreads < 1 || rfbScreen->rfbNumThreads > MAX_ENCODING_THREADS) {
rfbUsage();
return FALSE;
}
#endif
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
} else if (strcmp(argv[i], "-sslkeyfile") == 0) { /* -sslkeyfile sslkeyfile */
if (i + 1 >= *argc) {
Expand Down
44 changes: 44 additions & 0 deletions src/libvncserver/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@
* see GPL (latest version) for full details
*/

#include <rfb/rfbconfig.h>

#if LIBVNCSERVER_HAVE_SCHED_H
#define _GNU_SOURCE
#include <sched.h>
#endif

#ifdef __STRICT_ANSI__
#define _BSD_SOURCE
#endif
#include <rfb/rfb.h>

#include <rfb/rfbregion.h>
#include "private.h"

Expand Down Expand Up @@ -55,6 +63,13 @@ char rfbEndianTest = (1==0);
char rfbEndianTest = (1==1);
#endif

#ifndef min
inline static int min(int a, int b)
{
return a > b ? b : a;
}
#endif

/*
* Protocol extensions
*/
Expand Down Expand Up @@ -996,11 +1011,40 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,

screen->permitFileTransfer = FALSE;

screen->rfbMT = TRUE;
screen->rfbNumThreads = 0;

if(!rfbProcessArguments(screen,argc,argv)) {
free(screen);
return NULL;
}

#if defined(LIBVNCSERVER_HAVE_LIBPTHREAD) || defined(LIBVNCSERVER_HAVE_WIN32THREADS)
#if defined(WIN32) || defined(__MINGW32__)
DWORD64 dwProcessAffinity, dwSystemAffinity;
GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinity, &dwSystemAffinity);
const int np = __popcnt64(dwProcessAffinity);
#elif LIBVNCSERVER_HAVE_SCHED_H
cpu_set_t cs;
CPU_ZERO(&cs);
sched_getaffinity(0, sizeof(cs), &cs);
const int np = CPU_COUNT(&cs);
#else
const int np = 1;
#endif
if (np == -1 && screen->rfbMT) {
rfbLog("WARNING: Could not determine CPU count. Multithreaded encoding disabled.\n");
screen->rfbMT = FALSE;
}
if (!screen->rfbMT) screen->rfbNumThreads = 1;
else if (screen->rfbNumThreads < 1) screen->rfbNumThreads = min(np, 4);
if (screen->rfbNumThreads > np) {
rfbLog("NOTICE: Encoding thread count has been clamped to CPU count\n");
screen->rfbNumThreads = np;
}
#endif


#ifdef WIN32
{
DWORD dummy=255;
Expand Down
9 changes: 9 additions & 0 deletions src/libvncserver/rfbserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,15 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
}
}

#ifdef LIBVNCSERVER_HAVE_LIBJPEG
/* Multithreaded tight encoding. */

cl->threadInit = FALSE;
#if defined(LIBVNCSERVER_HAVE_LIBPTHREAD) || defined(LIBVNCSERVER_HAVE_WIN32THREADS)
memset(cl->thnd, 0, sizeof(cl->thnd));
#endif
#endif

for(extension = rfbGetExtensionIterator(); extension;
extension=extension->next) {
void* data = NULL;
Expand Down
Loading

0 comments on commit 496b5ef

Please sign in to comment.