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 e4f3e72 commit bfc59ca
Show file tree
Hide file tree
Showing 5 changed files with 1,642 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
84 changes: 84 additions & 0 deletions src/libvncserver/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
* 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
Expand All @@ -25,6 +32,10 @@
#define true -1
#endif

#ifdef LIBVNCSERVER_HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif

#ifdef LIBVNCSERVER_HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
Expand Down Expand Up @@ -55,6 +66,43 @@ 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

#ifdef __APPLE__
typedef struct cpu_set {
uint64_t count;
} cpu_set_t;

static inline void
CPU_ZERO(cpu_set_t *cs) { cs->count = 0; }

static inline int
CPU_COUNT(cpu_set_t *cs) { return __builtin_popcountll(cs->count); }

int sched_getaffinity(pid_t pid, size_t cpu_size, cpu_set_t *cpu_set)
{
int i;
int32_t core_count = 0;
size_t len = sizeof(core_count);
int ret = sysctlbyname("machdep.cpu.core_count", &core_count, &len, 0, 0);
if (ret) {
rfbErr("error while get core count %d\n", ret);
return -1;
}
cpu_set->count = 0;
for (i = 0; i < core_count; i++) {
cpu_set->count |= (1 << i);
}

return 0;
}
#endif

/*
* Protocol extensions
*/
Expand Down Expand Up @@ -996,11 +1044,47 @@ 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);
#if defined(__MINGW32__)
const int np = __builtin_popcountll(dwProcessAffinity);
#else
const int np = __popcnt64(dwProcessAffinity);
#endif
#elif LIBVNCSERVER_HAVE_SCHED_H
cpu_set_t cs;
CPU_ZERO(&cs);
int cpus = -1;
if (sched_getaffinity(0, sizeof(cs), &cs) == 0) {
cpus = CPU_COUNT(&cs);
}
const int np = cpus;
#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 bfc59ca

Please sign in to comment.