DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
sys_shared.c File Reference
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <time.h>
#include <dlfcn.h>
#include <signal.h>
#include "quakedef.h"
#include "taskqueue.h"
#include "thread.h"
#include "libcurl.h"
+ Include dependency graph for sys_shared.c:

Go to the source code of this file.

Macros

#define SUPPORTDLL
 

Functions

void Sys_AllowProfiling (qbool enable)
 
int Sys_CheckParm (const char *parm)
 
char * Sys_ConsoleInput (void)
 Reads a line from POSIX stdin or the Windows console.
 
double Sys_DirtyTime (void)
 
void Sys_Error (const char *error,...)
 Causes the entire program to exit ASAP.
 
static const char * Sys_FindExecutableName (void)
 
static const char * Sys_FindInPATH (const char *name, char namesep, const char *PATH, char pathsep, char *buf, size_t bufsize)
 
static void Sys_Frame (void)
 JS+WebGL doesn't support a main loop, only a function called to run a frame.
 
void Sys_FreeLibrary (dllhandle_t *handle)
 
voidSys_GetProcAddress (dllhandle_t handle, const char *name)
 
static void Sys_HandleCrash (int sig)
 Halt and try not to catch fire.
 
static void Sys_HandleSignal (int sig)
 
void Sys_Init_Commands (void)
 called after command system is initialized but before first Con_Print
 
void Sys_InitProcessNice (void)
 called to set process priority for dedicated servers
 
static void Sys_InitSignals (void)
 SDL2 only handles SIGINT and SIGTERM by default and doesn't log anything.
 
qbool Sys_LoadDependency (const char **dllnames, dllhandle_t *handle, const dllfunction_t *fcts)
 
static qbool Sys_LoadDependencyFunctions (dllhandle_t dllhandle, const dllfunction_t *fcts, qbool complain, qbool has_next)
 
qbool Sys_LoadLibrary (const char *name, dllhandle_t *handle)
 
qbool Sys_LoadSelf (dllhandle_t *handle)
 
int Sys_Main (int argc, char *argv[])
 main() but renamed so we can wrap it in sys_sdl.c and sys_null.c to avoid needing to include SDL.h in this file (would make the dedicated server require SDL).
 
void Sys_MakeProcessMean (void)
 
void Sys_MakeProcessNice (void)
 
void Sys_Print (const char *text, size_t textlen)
 (may) output text to terminal which launched program is POSIX async-signal-safe textlen excludes any (optional) \0 terminator
 
void Sys_Printf (const char *fmt,...)
 used to report failures inside Con_Printf()
 
void Sys_ProvideSelfFD (void)
 
static const char * Sys_SigDesc (int sig)
 
double Sys_Sleep (double time)
 called to yield for a little bit so as not to hog cpu when paused or debugging
 
size_t Sys_TimeString (char buf[], size_t bufsize, const char *timeformat)
 
static void Sys_UpdateOutFD_c (cvar_t *var)
 
static double Sys_UpdateTime (double newtime, double oldtime)
 

Variables

static double benchmark_time
 
sys_t sys
 
static cvar_t sys_debugsleep = {CF_SHARED, "sys_debugsleep", "0", "write requested and attained sleep times to standard output, to be used with gnuplot"}
 
cvar_t sys_libdir = {CF_READONLY | CF_SHARED, "sys_libdir", "", "Default engine library directory"}
 
static cvar_t sys_stdout = {CF_SHARED, "sys_stdout", "1", "0: nothing is written to stdout (-nostdout cmdline option sets this), 1: normal messages are written to stdout, 2: normal messages are written to stderr (-stderr cmdline option sets this)"}
 
static cvar_t sys_stdout_blocks = {CF_SHARED, "sys_stdout_blocks", "0", "1: writes to stdout and stderr streams will block (causing a stutter or complete halt) if the buffer is full, ensuring no messages are lost at a price"}
 
cvar_t sys_usenoclockbutbenchmark = {CF_SHARED, "sys_usenoclockbutbenchmark", "0", "don't use ANY real timing, and simulate a clock (for benchmarking); the game then runs as fast as possible. Run a QC mod with bots that does some stuff, then does a quit at the end, to benchmark a server. NEVER do this on a public server."}
 
static cvar_t sys_usesdldelay = {CF_SHARED, "sys_usesdldelay", "0", "use SDL_Delay() (low precision, for debugging)"}
 
static cvar_t sys_usesdlgetticks = {CF_SHARED, "sys_usesdlgetticks", "0", "use SDL_GetTicks() timer (low precision, for debugging)"}
 

Macro Definition Documentation

◆ SUPPORTDLL

#define SUPPORTDLL

Definition at line 7 of file sys_shared.c.

Function Documentation

◆ Sys_AllowProfiling()

void Sys_AllowProfiling ( qbool enable)

on some build/platform combinations (such as Linux gcc with the -pg profiling option) this can turn on/off profiling, used primarily to limit profiling to certain areas of the code, such as ingame performance without regard for loading/shutdown performance (-profilegameonly on commandline)

Definition at line 65 of file sys_shared.c.

66{
67#ifdef __ANDROID__
68#ifdef USE_PROFILER
69 extern void monstartup(const char *libname);
70 extern void moncleanup(void);
71 if (enable)
72 monstartup("libmain.so");
73 else
74 moncleanup();
75#endif
76#elif (defined(__linux__) && (defined(__GLIBC__) || defined(__GNU_LIBRARY__))) || defined(__FreeBSD__)
77 extern int moncontrol(int);
78 moncontrol(enable);
79#endif
80}

Referenced by CL_DisconnectEx(), CL_SignonReply(), Host_Init(), Host_Shutdown(), Sys_Frame(), and Sys_Main().

◆ Sys_CheckParm()

◆ Sys_ConsoleInput()

char * Sys_ConsoleInput ( void )

Reads a line from POSIX stdin or the Windows console.

Definition at line 667 of file sys_shared.c.

668{
669 static char text[MAX_INPUTLINE];
670#ifdef WIN32
671 static unsigned int len = 0;
672 int c;
673
674 // read a line out
675 while (_kbhit ())
676 {
677 c = _getch ();
678 if (c == '\r')
679 {
680 text[len] = '\0';
681 _putch ('\n');
682 len = 0;
683 return text;
684 }
685 if (c == '\b')
686 {
687 if (len)
688 {
689 _putch (c);
690 _putch (' ');
691 _putch (c);
692 len--;
693 }
694 continue;
695 }
696 if (len < sizeof (text) - 1)
697 {
698 _putch (c);
699 text[len] = c;
700 len++;
701 }
702 }
703#else
704 fd_set fdset;
705 struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 };
706
707 FD_ZERO(&fdset);
708 FD_SET(fileno(stdin), &fdset);
709 if (select(1, &fdset, NULL, NULL, &timeout) != -1 && FD_ISSET(fileno(stdin), &fdset))
710 return fgets(text, sizeof(text), stdin);
711#endif
712 return NULL;
713}
string fgets(float fhandle)
#define MAX_INPUTLINE
maximum size of console commandline, QuakeC strings, and many other text processing buffers
Definition qdefs.h:94
#define NULL
Definition qtypes.h:12

References fgets(), MAX_INPUTLINE, and NULL.

Referenced by Cbuf_Frame_Input().

◆ Sys_DirtyTime()

double Sys_DirtyTime ( void )

Definition at line 417 of file sys_shared.c.

418{
419 // first all the OPTIONAL timers
420
421 // benchmark timer (fake clock)
423 {
424 double old_benchmark_time = benchmark_time;
425 benchmark_time += 1;
426 if(benchmark_time == old_benchmark_time)
427 Sys_Error("sys_usenoclockbutbenchmark cannot run any longer, sorry");
428 return benchmark_time * 0.000001;
429 }
430
432 return (double) Sys_SDL_GetTicks() / 1000.0;
433
434#if HAVE_QUERYPERFORMANCECOUNTER
435 if (sys_usequeryperformancecounter.integer)
436 {
437 // QueryPerformanceCounter
438 // platform:
439 // Windows 95/98/ME/NT/2000/XP
440 // features:
441 // + very accurate (constant-rate TSCs on modern systems)
442 // known issues:
443 // - does not necessarily match realtime too well (tends to get faster and faster in win98)
444 // - wraps around occasionally on some platforms (depends on CPU speed and probably other unknown factors)
445 // - higher access latency on Vista
446 // Microsoft says on Win 7 or later, latency and overhead are very low, synchronisation is excellent.
447 LARGE_INTEGER PerformanceCount;
448
449 if (PerformanceFreq.QuadPart)
450 {
451 QueryPerformanceCounter (&PerformanceCount);
452 return (double)PerformanceCount.QuadPart * (1.0 / (double)PerformanceFreq.QuadPart);
453 }
454 else
455 {
456 Con_Printf("No hardware timer available\n");
457 // fall back to other clock sources
458 Cvar_SetValueQuick(&sys_usequeryperformancecounter, false);
459 }
460 }
461#endif
462
463#if HAVE_CLOCKGETTIME
464 {
465 struct timespec ts;
466# ifdef CLOCK_MONOTONIC_RAW
467 // Linux-specific, SDL_GetPerformanceCounter() uses it
468 clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
469# elif defined(CLOCK_MONOTONIC)
470 // POSIX
471 clock_gettime(CLOCK_MONOTONIC, &ts);
472# else
473 // sunos
474 clock_gettime(CLOCK_HIGHRES, &ts);
475# endif
476 return (double) ts.tv_sec + ts.tv_nsec / 1000000000.0;
477 }
478#endif
479
480 // now all the FALLBACK timers
481#if HAVE_TIMEGETTIME
482 {
483 // timeGetTime
484 // platform:
485 // Windows 95/98/ME/NT/2000/XP
486 // features:
487 // reasonable accuracy (millisecond)
488 // issues:
489 // wraps around every 47 days or so (but this is non-fatal to us, odd times are rejected, only causes a one frame stutter)
490 // requires Sys_SetTimerResolution()
491 return (double) timeGetTime() / 1000.0;
492 }
493#else
494 // fallback for using the SDL timer if no other timer is available
495 // this calls Sys_Error() if not linking against SDL
496 return (double) Sys_SDL_GetTicks() / 1000.0;
497#endif
498}
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
void Cvar_SetValueQuick(cvar_t *var, float value)
Definition cvar.c:473
int integer
Definition cvar.h:73
unsigned int Sys_SDL_GetTicks(void)
Definition sys_null.c:27
qbool sys_supportsdlgetticks
Definition sys_null.c:26
static cvar_t sys_usesdlgetticks
Definition sys_shared.c:306
void Sys_Error(const char *error,...)
Causes the entire program to exit ASAP.
Definition sys_shared.c:724
static double benchmark_time
Definition sys_shared.c:317
cvar_t sys_usenoclockbutbenchmark
Definition sys_shared.c:301

References benchmark_time, Con_Printf(), Cvar_SetValueQuick(), cvar_t::integer, Sys_Error(), Sys_SDL_GetTicks(), sys_supportsdlgetticks, sys_usenoclockbutbenchmark, and sys_usesdlgetticks.

Referenced by CL_Frame(), CL_KeepaliveMessage(), CL_TimeRefresh_f(), CL_UpdateScreen(), CLVM_ExecuteProgram(), Crypto_ServerParsePacket(), Host_Init(), PRVM_CallProfile(), PRVM_Prog_Load(), R_TimeReport(), R_TimeReport_BeginFrame(), R_TimeReport_EndFrame(), SV_Frame(), SV_ThreadFunc(), SVVM_ExecuteProgram(), Sys_Frame(), Sys_Sleep(), VM_CL_R_AddDynamicLight(), VM_CL_R_AddEntities(), VM_CL_R_AddEntity(), VM_CL_R_RenderScene(), VM_gettime(), and while().

◆ Sys_Error()

void Sys_Error ( const char * error,
... )

Causes the entire program to exit ASAP.

Trailing
should be omitted.

Definition at line 724 of file sys_shared.c.

725{
726 va_list argptr;
727 char string[MAX_INPUTLINE];
728 int i;
729
730 // Disable Sys_HandleSignal() but not Sys_HandleCrash()
732
733 // set output to blocking stderr
734 sys.outfd = fileno(stderr);
735#ifndef WIN32
736 fcntl(sys.outfd, F_SETFL, fcntl(sys.outfd, F_GETFL, 0) & ~O_NONBLOCK);
737#endif
738
739 va_start (argptr,error);
740 dpvsnprintf (string, sizeof (string), error, argptr);
741 va_end (argptr);
742
743 Con_Printf(CON_ERROR "Engine Aborted: %s\n^9%s\n", string, engineversion);
744
745 dp_strlcat(string, "\n\n", sizeof(string));
746 dp_strlcat(string, engineversion, sizeof(string));
747
748 // Most shutdown funcs can't be called here as they could error while we error.
749
750 // DP8 TODO: send a disconnect message indicating we aborted, see Host_Error() and Sys_HandleCrash()
751
752 if (cls.demorecording)
754 if (sv.active)
755 {
756 sv.active = false; // make SV_DropClient() skip the QC stuff to avoid recursive errors
757 for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
758 if (host_client->active)
759 SV_DropClient(false, "Server aborted!"); // closes demo file
760 }
761 // don't want a dead window left blocking the OS UI or the abort dialog
762 VID_Shutdown();
764
765 host.state = host_failed; // make Sys_HandleSignal() call _Exit()
766 Sys_SDL_Dialog("Engine Aborted", string);
767
768 fflush(stderr);
769 exit (1);
770}
void CL_Stop_f(cmd_state_t *cmd)
Definition cl_demo.c:307
client_static_t cls
Definition cl_main.c:116
cmd_state_t * cmd_local
command interpreter for local commands injected by SVQC, CSQC, MQC, server or client engine code uses...
Definition cmd.c:25
int dpvsnprintf(char *buffer, size_t buffersize, const char *format, va_list args)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:1010
#define dp_strlcat(dst, src, dsize)
Definition common.h:304
#define CON_ERROR
Definition console.h:102
char engineversion[128]
version string for the corner of the console, crash messages, status command, etc
Definition host.c:304
#define O_NONBLOCK
Definition fs.c:61
host_static_t host
Definition host.c:41
@ host_failed
crashed or aborted, SDL dialog open
Definition host.h:29
@ host_shutdown
states >= host_shutdown cause graceful shutdown, see Sys_HandleCrash() comments
Definition host.h:27
void error(string err,...)
server_t sv
local server
Definition sv_main.c:223
void SV_DropClient(qbool leaving, const char *reason,...)
Definition sv_main.c:1018
server_static_t svs
persistant server info
Definition sv_main.c:224
client_t * host_client
Definition sv_main.c:29
void S_StopAllSounds(void)
Definition snd_main.c:1710
qbool demorecording
Definition client.h:584
qbool active
false = empty client slot
Definition server.h:185
int state
Definition host.h:44
struct client_s * clients
client slots
Definition server.h:30
int maxclients
number of svs.clients slots (updated by maxplayers command)
Definition server.h:28
qbool active
false if only a net client
Definition server.h:66
int outfd
Definition sys.h:149
void Sys_SDL_Dialog(const char *title, const char *string)
Definition sys_null.c:13
void VID_Shutdown(void)
Called at shutdown.
Definition vid_null.c:28

References client_t::active, server_t::active, CL_Stop_f(), server_static_t::clients, cls, cmd_local, CON_ERROR, Con_Printf(), client_static_t::demorecording, dp_strlcat, dpvsnprintf(), engineversion, error(), host, host_client, host_failed, host_shutdown, i, MAX_INPUTLINE, server_static_t::maxclients, O_NONBLOCK, sys_t::outfd, S_StopAllSounds(), host_static_t::state, sv, SV_DropClient(), svs, sys, Sys_SDL_Dialog(), and VID_Shutdown().

Referenced by _Mem_Alloc(), _Mem_AllocPool(), _Mem_CheckSentinels(), _Mem_CheckSentinelsGlobal(), _Mem_EmptyPool(), _Mem_Free(), _Mem_FreeBlock(), _Mem_FreePool(), Buffer_Callback(), CL_CutDemo(), CL_ExpandEntities(), Clump_AllocBlock(), Clump_FreeBlock(), COM_ChangeGameTypeForGameDirs(), FS_SetGameDirs(), GL_InitFunctions(), GL_Setup(), Host_Error(), Host_LockSession(), M_Menu_Keys_f(), Mem_ExpandableArray_FreeRecord(), MVM_error_cmd(), PHYS_NudgeOutOfSolid(), R_BufferData_Store(), R_Mesh_TexBind(), R_Mesh_TexBound(), R_Mesh_TexCoordPointer(), R_RegisterModule(), R_SetupTexture(), R_UploadFullTexture(), R_UploadPartialTexture(), RSurf_DrawBatch(), SCR_CaptureVideo_Avi_BeginVideo(), SCR_CaptureVideo_Ogg_Interleave(), SCR_CaptureVideo_RIFF_IndexEntry(), SCR_CaptureVideo_RIFF_MakeIxChunk(), SCR_CaptureVideo_RIFF_OverflowCheck(), setuptex(), SV_SendClientMessages(), Sys_DirtyTime(), Sys_SDL_Delay(), Sys_SDL_GetTicks(), Sys_SDL_Init(), Sys_Sleep(), VID_Init(), VID_InitMode(), VID_InitModeGL(), VID_Restart_f(), VID_Start(), and VM_nudgeoutofsolid().

◆ Sys_FindExecutableName()

static const char * Sys_FindExecutableName ( void )
static

Definition at line 797 of file sys_shared.c.

798{
799#if defined(WIN32)
800 return sys.argv[0];
801#else
802 static char exenamebuf[MAX_OSPATH+1];
803 ssize_t n = -1;
804#if defined(__FreeBSD__)
805 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
806 size_t exenamebuflen = sizeof(exenamebuf)-1;
807 if (sysctl(mib, 4, exenamebuf, &exenamebuflen, NULL, 0) == 0)
808 {
809 n = exenamebuflen;
810 }
811#elif defined(__linux__)
812 n = readlink("/proc/self/exe", exenamebuf, sizeof(exenamebuf)-1);
813#endif
814 if(n > 0 && (size_t)(n) < sizeof(exenamebuf))
815 {
816 exenamebuf[n] = 0;
817 return exenamebuf;
818 }
819 if(strchr(sys.argv[0], '/'))
820 return sys.argv[0]; // possibly a relative path
821 else
822 return Sys_FindInPATH(sys.argv[0], '/', getenv("PATH"), ':', exenamebuf, sizeof(exenamebuf));
823#endif
824}
#define n(x, y)
#define MAX_OSPATH
max length of a filesystem pathname
Definition qdefs.h:175
static const char * Sys_FindInPATH(const char *name, char namesep, const char *PATH, char pathsep, char *buf, size_t bufsize)
Definition sys_shared.c:773

References sys_t::argv, MAX_OSPATH, n, NULL, sys, and Sys_FindInPATH().

Referenced by Sys_ProvideSelfFD().

◆ Sys_FindInPATH()

static const char * Sys_FindInPATH ( const char * name,
char namesep,
const char * PATH,
char pathsep,
char * buf,
size_t bufsize )
static

Definition at line 773 of file sys_shared.c.

774{
775 const char *p = PATH;
776 const char *q;
777 if(p && name)
778 {
779 while((q = strchr(p, ':')))
780 {
781 dpsnprintf(buf, bufsize, "%.*s%c%s", (int)(q-p), p, namesep, name);
783 return buf;
784 p = q + 1;
785 }
786 if(!q) // none found - try the last item
787 {
788 dpsnprintf(buf, bufsize, "%s%c%s", p, namesep, name);
790 return buf;
791 }
792 }
793 return name;
794}
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997
qbool FS_SysFileExists(const char *path)
Look for a file in the filesystem only.
Definition fs.c:3744
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glquake.h:657
const GLchar * name
Definition glquake.h:601

References buf, dpsnprintf(), FS_SysFileExists(), and name.

Referenced by Sys_FindExecutableName().

◆ Sys_Frame()

static void Sys_Frame ( void )
static

JS+WebGL doesn't support a main loop, only a function called to run a frame.

Definition at line 1133 of file sys_shared.c.

1134{
1135 double time, newtime, sleeptime;
1136#ifdef __EMSCRIPTEN__
1137 static double sleepstarttime = 0;
1138 host.sleeptime = Sys_DirtyTime() - sleepstarttime;
1139#endif
1140
1141 if (setjmp(host.abortframe)) // Something bad happened, or the server disconnected
1142 host.state = host_active; // In case we were loading
1143
1144 if (host.state >= host_shutdown) // see Sys_HandleCrash() comments
1145 {
1146#ifdef __EMSCRIPTEN__
1147 emscripten_cancel_main_loop();
1148#endif
1149#ifdef __ANDROID__
1150 Sys_AllowProfiling(false);
1151#endif
1152 Host_Shutdown();
1153 exit(0);
1154 }
1155
1156 newtime = Sys_DirtyTime();
1158 host.dirtytime = newtime;
1159
1160 sleeptime = Host_Frame(time);
1161 sleeptime -= Sys_DirtyTime() - host.dirtytime; // execution time
1162
1163#ifdef __EMSCRIPTEN__
1164 // This platform doesn't support a main loop... it will sleep when Sys_Frame() returns.
1165 // Not using emscripten_sleep() via Sys_Sleep() because it would cause two sleeps per frame.
1166 if (!vid_vsync.integer) // see VID_SetVsync_c()
1167 emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, host.restless ? 0 : sleeptime * 1000.0);
1168 sleepstarttime = Sys_DirtyTime();
1169#else
1170 host.sleeptime = Sys_Sleep(sleeptime);
1171#endif
1172}
float time
void Host_Shutdown(void)
Definition host.c:571
double Host_Frame(double time)
Definition host.c:618
@ host_active
Definition host.h:25
double sleeptime
time spent sleeping after the last frame
Definition host.h:48
qbool restless
don't sleep
Definition host.h:49
double dirtytime
the main loop wall time for this frame, equal to Sys_DirtyTime() at the start of this host frame
Definition host.h:47
jmp_buf abortframe
Definition host.h:43
double realtime
the accumulated mainloop time since application started (with filtering), without any slowmo or clamp...
Definition host.h:46
void Sys_AllowProfiling(qbool enable)
Definition sys_shared.c:65
double Sys_DirtyTime(void)
Definition sys_shared.c:417
double Sys_Sleep(double time)
called to yield for a little bit so as not to hog cpu when paused or debugging
Definition sys_shared.c:500
static double Sys_UpdateTime(double newtime, double oldtime)
cvar_t vid_vsync
Definition vid_shared.c:149

References host_static_t::abortframe, host_static_t::dirtytime, host, host_active, Host_Frame(), Host_Shutdown(), host_shutdown, cvar_t::integer, host_static_t::realtime, host_static_t::restless, host_static_t::sleeptime, host_static_t::state, Sys_AllowProfiling(), Sys_DirtyTime(), Sys_Sleep(), Sys_UpdateTime(), time, and vid_vsync.

Referenced by Sys_Main().

◆ Sys_FreeLibrary()

void Sys_FreeLibrary ( dllhandle_t * handle)

Definition at line 245 of file sys_shared.c.

246{
247#ifdef SUPPORTDLL
248 if (handle == NULL || *handle == NULL)
249 return;
250
251#ifdef WIN32
252 FreeLibrary (*handle);
253#else
254 dlclose (*handle);
255#endif
256
257 *handle = NULL;
258#endif
259}

References NULL.

Referenced by Crypto_CloseLibrary(), Crypto_Rijndael_CloseLibrary(), CURL_CloseLibrary(), Font_CloseLibrary(), FS_Shutdown(), JPEG_CloseLibrary(), LibAV_LoadLibrary(), LibAvW_CloseLibrary(), LibAvW_OpenLibrary(), OGG_CloseLibrary(), PK3_CloseLibrary(), PNG_CloseLibrary(), PNG_OpenLibrary(), SCR_CaptureVideo_Ogg_CloseDLL(), Sys_LoadDependency(), XMP_CloseLibrary(), and XMP_OpenLibrary().

◆ Sys_GetProcAddress()

void * Sys_GetProcAddress ( dllhandle_t handle,
const char * name )

Definition at line 261 of file sys_shared.c.

262{
263#ifdef SUPPORTDLL
264#ifdef WIN32
265 return (void *)GetProcAddress (handle, name);
266#else
267 return (void *)dlsym (handle, name);
268#endif
269#else
270 return NULL;
271#endif
272}

References name, and NULL.

Referenced by Sys_LoadDependencyFunctions().

◆ Sys_HandleCrash()

static void Sys_HandleCrash ( int sig)
static

Halt and try not to catch fire.

Writing to any file could corrupt it, any uneccessary code could crash while we crash. Try to use only POSIX async-signal-safe library functions here (see: man signal-safety).

Definition at line 994 of file sys_shared.c.

995{
996#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
997 // Before doing anything else grab the stack frame addresses
998 #include <execinfo.h>
999 void *stackframes[32];
1000 int framecount = backtrace(stackframes, 32);
1001 char **btstrings;
1002#endif
1003 char dialogtext[3072];
1004 const char *sigdesc;
1005
1006 // Break any loop and disable Sys_HandleSignal()
1008 return;
1010
1011 sigdesc = Sys_SigDesc(sig);
1012
1013 // set output to blocking stderr and print header, backtrace, version
1014 sys.outfd = fileno(stderr); // not async-signal-safe :(
1015#ifndef WIN32
1016 fcntl(sys.outfd, F_SETFL, fcntl(sys.outfd, F_GETFL, 0) & ~O_NONBLOCK);
1017 Sys_Print("\n\n\x1B[1;37;41m Engine Crash: ", 30);
1018 Sys_Print(sigdesc, strlen(sigdesc));
1019 Sys_Print(" \x1B[m\n", 8);
1020 #if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
1021 // the first two addresses will be in this function and in signal() in libc
1022 backtrace_symbols_fd(stackframes + 2, framecount - 2, sys.outfd);
1023 #endif
1024 Sys_Print("\x1B[1m", 4);
1026 Sys_Print("\x1B[m\n", 4);
1027#else // Windows console doesn't support colours
1028 Sys_Print("\n\nEngine Crash: ", 16);
1029 Sys_Print(sigdesc, strlen(sigdesc));
1030 Sys_Print("\n", 1);
1032 Sys_Print("\n", 1);
1033#endif
1034
1035 // DP8 TODO: send a disconnect message indicating we crashed, see Sys_Error() and Host_Error()
1036
1037 // don't want a dead window left blocking the OS UI or the crash dialog
1038 VID_Shutdown();
1040
1041 // prepare the dialogtext: signal, backtrace, version
1042 // the dp_st* funcs are POSIX async-signal-safe IF we don't trigger their warnings
1043 dp_strlcpy(dialogtext, sigdesc, sizeof(dialogtext));
1044 dp_strlcat(dialogtext, "\n\n", sizeof(dialogtext));
1045#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
1046 btstrings = backtrace_symbols(stackframes + 2, framecount - 2); // calls malloc :(
1047 if (btstrings)
1048 for (int i = 0; i < framecount - 2; ++i)
1049 {
1050 dp_strlcat(dialogtext, btstrings[i], sizeof(dialogtext));
1051 dp_strlcat(dialogtext, "\n", sizeof(dialogtext));
1052 }
1053#endif
1054 dp_strlcat(dialogtext, "\n", sizeof(dialogtext));
1055 dp_strlcat(dialogtext, engineversion, sizeof(dialogtext));
1056
1057 host.state = host_failed; // make Sys_HandleSignal() call _Exit()
1058 Sys_SDL_Dialog("Engine Crash", dialogtext);
1059
1060 fflush(stderr); // not async-signal-safe :(
1061
1062 // Continue execution with default signal handling.
1063 // A real crash will be re-triggered so the platform can handle it,
1064 // a fake crash (kill -SEGV) will cause a graceful shutdown.
1065 signal(sig, SIG_DFL);
1066}
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
@ host_failing
crashing (inside crash handler)
Definition host.h:28
float strlen(string s)
static const char * Sys_SigDesc(int sig)
Definition sys_shared.c:967
void Sys_Print(const char *text, size_t textlen)
(may) output text to terminal which launched program is POSIX async-signal-safe textlen excludes any ...
Definition sys_shared.c:615

References dp_strlcat, dp_strlcpy, engineversion, host, host_failed, host_failing, i, O_NONBLOCK, sys_t::outfd, S_StopAllSounds(), host_static_t::state, strlen(), sys, Sys_Print(), Sys_SDL_Dialog(), Sys_SigDesc(), and VID_Shutdown().

Referenced by Sys_InitSignals().

◆ Sys_HandleSignal()

static void Sys_HandleSignal ( int sig)
static

Definition at line 1068 of file sys_shared.c.

1069{
1070 const char *sigdesc;
1071
1072 // Break any loop, eg if each Sys_Print triggers a SIGPIPE
1074 return;
1075
1076 sigdesc = Sys_SigDesc(sig);
1077 Sys_Print("\nReceived ", 10);
1078 Sys_Print(sigdesc, strlen(sigdesc));
1079 Sys_Print(" signal, exiting...\n", 20);
1080 if (host.state == host_failed)
1081 {
1082 // user is trying to kill the process while the SDL dialog is open
1083 fflush(stderr); // not async-signal-safe :(
1084 _Exit(sig);
1085 }
1087}

References host, host_failed, host_failing, host_shutdown, host_static_t::state, strlen(), Sys_Print(), and Sys_SigDesc().

Referenced by Sys_InitSignals().

◆ Sys_Init_Commands()

void Sys_Init_Commands ( void )

called after command system is initialized but before first Con_Print

Definition at line 353 of file sys_shared.c.

354{
358#if HAVE_TIMEGETTIME || HAVE_QUERYPERFORMANCECOUNTER || HAVE_CLOCKGETTIME
360 {
363 }
364#endif
365#if HAVE_QUERYPERFORMANCECOUNTER
366 Cvar_RegisterVariable(&sys_usequeryperformancecounter);
367#endif
368
371#ifndef WIN32
373#endif
374}
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599
void Cvar_RegisterCallback(cvar_t *variable, void(*callback)(cvar_t *))
Definition cvar.c:495
static cvar_t sys_usesdldelay
Definition sys_shared.c:307
static cvar_t sys_stdout_blocks
Definition sys_shared.c:314
static void Sys_UpdateOutFD_c(cvar_t *var)
Definition sys_shared.c:342
static cvar_t sys_stdout
Definition sys_shared.c:312
cvar_t sys_libdir
Definition sys_shared.c:302
static cvar_t sys_debugsleep
Definition sys_shared.c:305

References Cvar_RegisterCallback(), Cvar_RegisterVariable(), sys_debugsleep, sys_libdir, sys_stdout, sys_stdout_blocks, sys_supportsdlgetticks, Sys_UpdateOutFD_c(), sys_usenoclockbutbenchmark, sys_usesdldelay, and sys_usesdlgetticks.

Referenced by Host_Init().

◆ Sys_InitProcessNice()

void Sys_InitProcessNice ( void )

called to set process priority for dedicated servers

Definition at line 955 of file sys_shared.c.

956{
957}

Referenced by Host_Init().

◆ Sys_InitSignals()

static void Sys_InitSignals ( void )
static

SDL2 only handles SIGINT and SIGTERM by default and doesn't log anything.

Definition at line 1090 of file sys_shared.c.

1091{
1092 // Windows only supports the C99 signals
1093 signal(SIGINT, Sys_HandleSignal);
1094 signal(SIGILL, Sys_HandleCrash);
1095 signal(SIGABRT, Sys_HandleCrash);
1096 signal(SIGFPE, Sys_HandleCrash);
1097 signal(SIGSEGV, Sys_HandleCrash);
1098 signal(SIGTERM, Sys_HandleSignal);
1099#ifndef WIN32
1100 // POSIX has several others worth catching
1101 signal(SIGHUP, Sys_HandleSignal);
1102 signal(SIGQUIT, Sys_HandleSignal);
1103 signal(SIGBUS, Sys_HandleCrash);
1104 signal(SIGPIPE, Sys_HandleSignal);
1105#endif
1106}
static void Sys_HandleCrash(int sig)
Halt and try not to catch fire.
Definition sys_shared.c:994
static void Sys_HandleSignal(int sig)

References Sys_HandleCrash(), and Sys_HandleSignal().

Referenced by Sys_Main().

◆ Sys_LoadDependency()

qbool Sys_LoadDependency ( const char ** dllnames,
dllhandle_t * handle,
const dllfunction_t * fcts )

Loads a dependency library.

Parameters
dllnamesa NULL terminated array of possible names for the DLL you want to load.
handle
fcts

Definition at line 131 of file sys_shared.c.

132{
133#ifdef SUPPORTDLL
134 const dllfunction_t *func;
135 dllhandle_t dllhandle = 0;
136 unsigned int i;
137
138 if (handle == NULL)
139 return false;
140
141#ifndef WIN32
142#ifdef PREFER_PRELOAD
143 dllhandle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
144 if(Sys_LoadDependencyFunctions(dllhandle, fcts, false, false))
145 {
146 Con_DPrintf ("All of %s's functions were already linked in! Not loading dynamically...\n", dllnames[0]);
147 *handle = dllhandle;
148 return true;
149 }
150 else
151 Sys_FreeLibrary(&dllhandle);
152notfound:
153#endif
154#endif
155
156 // Initializations
157 for (func = fcts; func && func->name != NULL; func++)
158 *func->funcvariable = NULL;
159
160 // Try every possible name
161 Con_DPrintf ("Trying to load library...");
162 for (i = 0; dllnames[i] != NULL; i++)
163 {
164 Con_DPrintf (" \"%s\"", dllnames[i]);
165#ifdef WIN32
166# ifndef DONT_USE_SETDLLDIRECTORY
167# ifdef _WIN64
168 SetDllDirectory("bin64");
169# else
170 SetDllDirectory("bin32");
171# endif
172# endif
173#endif
174 if(Sys_LoadLibrary(dllnames[i], &dllhandle))
175 {
176 if (Sys_LoadDependencyFunctions(dllhandle, fcts, true, (dllnames[i+1] != NULL) || (strrchr(sys.argv[0], '/'))))
177 break;
178 else
179 Sys_FreeLibrary (&dllhandle);
180 }
181 }
182
183 // see if the names can be loaded relative to the executable path
184 // (this is for Mac OSX which does not check next to the executable)
185 if (!dllhandle && strrchr(sys.argv[0], '/'))
186 {
187 char path[MAX_OSPATH];
188 dp_strlcpy(path, sys.argv[0], sizeof(path));
189 strrchr(path, '/')[1] = 0;
190 for (i = 0; dllnames[i] != NULL; i++)
191 {
192 char temp[MAX_OSPATH];
193 dp_strlcpy(temp, path, sizeof(temp));
194 dp_strlcat(temp, dllnames[i], sizeof(temp));
195 Con_DPrintf (" \"%s\"", temp);
196
197 if(Sys_LoadLibrary(temp, &dllhandle))
198 {
199 if (Sys_LoadDependencyFunctions(dllhandle, fcts, true, (dllnames[i+1] != NULL) || (strrchr(sys.argv[0], '/'))))
200 break;
201 else
202 Sys_FreeLibrary (&dllhandle);
203 }
204 }
205 }
206
207 // No DLL found
208 if (! dllhandle)
209 {
210 Con_DPrintf(" - failed.\n");
211 return false;
212 }
213
214 Con_DPrintf(" - loaded.\n");
215 Con_Printf("Loaded library \"%s\"\n", dllnames[i]);
216
217 *handle = dllhandle;
218 return true;
219#else
220 return false;
221#endif
222}
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
void ** funcvariable
Definition sys.h:175
const char * name
Definition sys.h:174
void * dllhandle_t
Definition sys.h:169
qbool Sys_LoadLibrary(const char *name, dllhandle_t *handle)
Definition sys_shared.c:224
static qbool Sys_LoadDependencyFunctions(dllhandle_t dllhandle, const dllfunction_t *fcts, qbool complain, qbool has_next)
Definition sys_shared.c:91
void Sys_FreeLibrary(dllhandle_t *handle)
Definition sys_shared.c:245

References sys_t::argv, Con_DPrintf(), Con_Printf(), dp_strlcat, dp_strlcpy, dllfunction_t::funcvariable, i, MAX_OSPATH, dllfunction_t::name, NULL, sys, Sys_FreeLibrary(), Sys_LoadDependencyFunctions(), and Sys_LoadLibrary().

Referenced by Crypto_OpenLibrary(), Crypto_Rijndael_OpenLibrary(), CURL_OpenLibrary(), Font_OpenLibrary(), FS_ChooseUserDir(), JPEG_OpenLibrary(), LibAV_LoadLibrary(), LibAvW_OpenLibrary(), OGG_OpenLibrary(), PK3_OpenLibrary(), PNG_OpenLibrary(), SCR_CaptureVideo_Ogg_OpenLibrary(), VID_Shared_Init(), and XMP_OpenLibrary().

◆ Sys_LoadDependencyFunctions()

static qbool Sys_LoadDependencyFunctions ( dllhandle_t dllhandle,
const dllfunction_t * fcts,
qbool complain,
qbool has_next )
static

Definition at line 91 of file sys_shared.c.

92{
93 const dllfunction_t *func;
94 if(dllhandle)
95 {
96 for (func = fcts; func && func->name != NULL; func++)
97 if (!(*func->funcvariable = (void *) Sys_GetProcAddress (dllhandle, func->name)))
98 {
99 if(complain)
100 {
101 Con_DPrintf (" - missing function \"%s\" - broken library!", func->name);
102 if(has_next)
103 Con_DPrintf("\nContinuing with");
104 }
105 goto notfound;
106 }
107 return true;
108
109 notfound:
110 for (func = fcts; func && func->name != NULL; func++)
111 *func->funcvariable = NULL;
112 }
113 return false;
114}
void * Sys_GetProcAddress(dllhandle_t handle, const char *name)
Definition sys_shared.c:261

References Con_DPrintf(), dllfunction_t::funcvariable, dllfunction_t::name, NULL, and Sys_GetProcAddress().

Referenced by Sys_LoadDependency().

◆ Sys_LoadLibrary()

qbool Sys_LoadLibrary ( const char * name,
dllhandle_t * handle )

Loads a library.

Parameters
namea string of the library filename
handle
Returns
true if library was loaded successfully

Definition at line 224 of file sys_shared.c.

225{
226 dllhandle_t dllhandle = 0;
227
228 if(handle == NULL)
229 return false;
230
231#ifdef SUPPORTDLL
232# ifdef WIN32
233 dllhandle = LoadLibrary (name);
234# else
235 dllhandle = dlopen (name, RTLD_LAZY | RTLD_GLOBAL);
236# endif
237#endif
238 if(!dllhandle)
239 return false;
240
241 *handle = dllhandle;
242 return true;
243}

References name, and NULL.

Referenced by Sys_LoadDependency().

◆ Sys_LoadSelf()

qbool Sys_LoadSelf ( dllhandle_t * handle)

Definition at line 116 of file sys_shared.c.

117{
118 dllhandle_t dllhandle = 0;
119
120 if (handle == NULL)
121 return false;
122#ifdef WIN32
123 dllhandle = LoadLibrary (NULL);
124#else
125 dllhandle = dlopen (NULL, RTLD_NOW | RTLD_GLOBAL);
126#endif
127 *handle = dllhandle;
128 return true;
129}

References NULL.

◆ Sys_Main()

int Sys_Main ( int argc,
char * argv[] )

main() but renamed so we can wrap it in sys_sdl.c and sys_null.c to avoid needing to include SDL.h in this file (would make the dedicated server require SDL).

SDL builds need SDL.h in the file where main() is defined because SDL renames and wraps main().

Definition at line 1178 of file sys_shared.c.

1179{
1180 sys.argc = argc;
1181 sys.argv = (const char **)argv;
1182
1183 // COMMANDLINEOPTION: Console: -nostdout disables text output to the terminal the game was launched from
1184 // COMMANDLINEOPTION: -noterminal disables console output on stdout
1185 if(Sys_CheckParm("-noterminal") || Sys_CheckParm("-nostdout"))
1186 sys_stdout.string = "0";
1187 // COMMANDLINEOPTION: -stderr moves console output to stderr
1188 else if(Sys_CheckParm("-stderr"))
1189 sys_stdout.string = "2";
1190 // too early for Cvar_SetQuick
1193#ifndef WIN32
1194 fcntl(fileno(stdin), F_SETFL, fcntl(fileno(stdin), F_GETFL, 0) | O_NONBLOCK);
1195 // stdout/stderr will be set to blocking in Sys_Print() if so configured, or during a fatal error.
1196 fcntl(fileno(stdout), F_SETFL, fcntl(fileno(stdout), F_GETFL, 0) | O_NONBLOCK);
1197 fcntl(fileno(stderr), F_SETFL, fcntl(fileno(stderr), F_GETFL, 0) | O_NONBLOCK);
1198#endif
1199
1200 sys.selffd = -1;
1201 Sys_ProvideSelfFD(); // may call Con_Printf() so must be after sys.outfd is set
1202
1203#ifdef __ANDROID__
1204 Sys_AllowProfiling(true);
1205#endif
1206
1208
1209#ifdef WIN32
1210 Sys_SetTimerResolution();
1211#endif
1212
1213 Host_Init();
1214#ifdef __EMSCRIPTEN__
1215 emscripten_set_main_loop(Sys_Frame, 0, true); // doesn't return
1216#else
1217 while(true)
1218 Sys_Frame();
1219#endif
1220
1221 return 0;
1222}
void Host_Init(void)
Definition host.c:377
string argv(float n)
float value
Definition cvar.h:74
const char * string
Definition cvar.h:71
int selffd
Definition sys.h:148
static void Sys_InitSignals(void)
SDL2 only handles SIGINT and SIGTERM by default and doesn't log anything.
void Sys_ProvideSelfFD(void)
Definition sys_shared.c:826
static void Sys_Frame(void)
JS+WebGL doesn't support a main loop, only a function called to run a frame.
int Sys_CheckParm(const char *parm)
Definition sys_shared.c:327

References sys_t::argc, argv(), sys_t::argv, Host_Init(), cvar_t::integer, O_NONBLOCK, sys_t::selffd, cvar_t::string, sys, Sys_AllowProfiling(), Sys_CheckParm(), Sys_Frame(), Sys_InitSignals(), Sys_ProvideSelfFD(), sys_stdout, Sys_UpdateOutFD_c(), and cvar_t::value.

Referenced by main().

◆ Sys_MakeProcessMean()

void Sys_MakeProcessMean ( void )

Definition at line 961 of file sys_shared.c.

962{
963}

Referenced by Host_AbortCurrentFrame(), and SV_SpawnServer().

◆ Sys_MakeProcessNice()

void Sys_MakeProcessNice ( void )

Definition at line 958 of file sys_shared.c.

959{
960}

Referenced by SV_SpawnServer().

◆ Sys_Print()

void Sys_Print ( const char * text,
size_t textlen )

(may) output text to terminal which launched program is POSIX async-signal-safe textlen excludes any (optional) \0 terminator

Definition at line 615 of file sys_shared.c.

616{
617#ifdef __ANDROID__
618 if (developer.integer > 0)
619 {
620 __android_log_write(ANDROID_LOG_DEBUG, sys.argv[0], text);
621 }
622#else
623 if(sys.outfd < 0)
624 return;
625 #ifndef WIN32
626 // BUG: for some reason, NDELAY also affects stdout (1) when used on stdin (0).
627 // this is because both go to /dev/tty by default!
628 {
629 int origflags = fcntl(sys.outfd, F_GETFL, 0);
631 fcntl(sys.outfd, F_SETFL, origflags & ~O_NONBLOCK);
632 #else
633 #define write _write
634 #endif
635 while(*text && textlen)
636 {
637 fs_offset_t written = (fs_offset_t)write(sys.outfd, text, textlen);
638 if(written <= 0)
639 break; // sorry, I cannot do anything about this error - without an output
640 text += written;
641 textlen -= written;
642 }
643 #ifndef WIN32
645 fcntl(sys.outfd, F_SETFL, origflags);
646 }
647 #endif
648 //fprintf(stdout, "%s", text);
649#endif
650}
int64_t fs_offset_t
Definition fs.h:37
cvar_t developer
Definition host.c:48

References sys_t::argv, developer, cvar_t::integer, O_NONBLOCK, sys_t::outfd, sys, and sys_stdout_blocks.

Referenced by Con_MaskPrint(), dpvsnprintf(), Sys_HandleCrash(), Sys_HandleSignal(), and Sys_Printf().

◆ Sys_Printf()

◆ Sys_ProvideSelfFD()

void Sys_ProvideSelfFD ( void )

Definition at line 826 of file sys_shared.c.

827{
828 if(sys.selffd != -1)
829 return;
831}
int FS_SysOpenFD(const char *filepath, const char *mode, qbool nonblocking)
Definition fs.c:2468
static const char * Sys_FindExecutableName(void)
Definition sys_shared.c:797

References FS_SysOpenFD(), sys_t::selffd, sys, and Sys_FindExecutableName().

Referenced by Sys_Main().

◆ Sys_SigDesc()

static const char * Sys_SigDesc ( int sig)
static

Definition at line 967 of file sys_shared.c.

968{
969 switch (sig)
970 {
971 // Windows only supports the C99 signals
972 case SIGINT: return "Interrupt";
973 case SIGILL: return "Illegal instruction";
974 case SIGABRT: return "Aborted";
975 case SIGFPE: return "Floating point exception";
976 case SIGSEGV: return "Segmentation fault";
977 case SIGTERM: return "Termination";
978#ifndef WIN32
979 // POSIX has several others worth catching
980 case SIGHUP: return "Hangup";
981 case SIGQUIT: return "Quit";
982 case SIGBUS: return "Bus error (bad memory access)";
983 case SIGPIPE: return "Broken pipe";
984#endif
985 default: return "Yo dawg, we bugged out while bugging out";
986 }
987}

Referenced by Sys_HandleCrash(), and Sys_HandleSignal().

◆ Sys_Sleep()

double Sys_Sleep ( double time)

called to yield for a little bit so as not to hog cpu when paused or debugging

Definition at line 500 of file sys_shared.c.

501{
502 double dt;
503 uint32_t msec, usec, nsec;
504
505 if (time < 1.0/1000000.0 || host.restless)
506 return 0; // not sleeping this frame
507 if (time >= 1)
508 time = 0.999999; // simpler, also ensures values are in range for all platform APIs
509 msec = time * 1000;
510 usec = time * 1000000;
511 nsec = time * 1000000000;
512
514 {
515 double old_benchmark_time = benchmark_time;
516 benchmark_time += usec;
517 if(benchmark_time == old_benchmark_time)
518 Sys_Error("sys_usenoclockbutbenchmark cannot run any longer, sorry");
519 return 0;
520 }
521
523 Con_Printf("sys_debugsleep: requested %u, ", usec);
524 dt = Sys_DirtyTime();
525
526 // less important on newer libcurl so no need to disturb dedicated servers
527 if (cls.state != ca_dedicated && Curl_Select(msec))
528 {
529 // a transfer is ready or we finished sleeping
530 }
532 Sys_SDL_Delay(msec);
533#if HAVE_SELECT
535 {
536 struct timeval tv;
537 lhnetsocket_t *s;
538 fd_set fdreadset;
539 int lastfd = -1;
540
541 FD_ZERO(&fdreadset);
543 {
544 if (s->address.addresstype == LHNETADDRESSTYPE_INET4 || s->address.addresstype == LHNETADDRESSTYPE_INET6)
545 {
546 if (lastfd < s->inetsocket)
547 lastfd = s->inetsocket;
548 #if defined(WIN32) && !defined(_MSC_VER)
549 FD_SET((int)s->inetsocket, &fdreadset);
550 #else
551 FD_SET((unsigned int)s->inetsocket, &fdreadset);
552 #endif
553 }
554 }
555 tv.tv_sec = 0;
556 tv.tv_usec = usec;
557 // on Win32, select() cannot be used with all three FD list args being NULL according to MSDN
558 // (so much for POSIX...), not with an empty fd_set either.
559 select(lastfd + 1, &fdreadset, NULL, NULL, &tv);
560 }
561#endif
562#if HAVE_CLOCK_NANOSLEEP
563 else
564 {
565 struct timespec ts;
566 ts.tv_sec = 0;
567 ts.tv_nsec = nsec;
568 clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
569 }
570#elif HAVE_SELECT_POSIX
571 else
572 {
573 struct timeval tv;
574 tv.tv_sec = 0;
575 tv.tv_usec = usec;
576 select(0, NULL, NULL, NULL, &tv);
577 }
578#elif HAVE_WIN32_USLEEP // Windows XP/2003 minimum
579 else
580 {
581 HANDLE timer;
582 LARGE_INTEGER sleeptime;
583
584 // takes 100ns units, negative indicates relative time
585 sleeptime.QuadPart = -((int64_t)nsec / 100);
586 timer = CreateWaitableTimer(NULL, true, NULL);
587 SetWaitableTimer(timer, &sleeptime, 0, NULL, NULL, 0);
588 WaitForSingleObject(timer, INFINITE);
589 CloseHandle(timer);
590 }
591#elif HAVE_Sleep
592 else
593 Sleep(msec);
594#else
595 else
596 Sys_SDL_Delay(msec);
597#endif
598
599 dt = Sys_DirtyTime() - dt;
601 Con_Printf("got %u, oversleep %d\n", (uint32_t)(dt * 1000000), (uint32_t)(dt * 1000000) - usec);
602 return (dt < 0 || dt >= 1800) ? 0 : dt;
603}
@ ca_dedicated
Definition client.h:530
#define List_For_Each_Entry(pos, head, type, member)
Definition com_list.h:121
lhnetsocket_t lhnet_socketlist
Definition lhnet.c:717
@ LHNETADDRESSTYPE_INET6
Definition lhnet.h:15
@ LHNETADDRESSTYPE_INET4
Definition lhnet.h:14
bool Curl_Select(int timeout_ms)
Definition libcurl.c:1263
cvar_t sv_checkforpacketsduringsleep
Definition sv_main.c:76
cactive_t state
Definition client.h:568
llist_t list
Definition lhnet.h:47
void Sys_SDL_Delay(unsigned int milliseconds)
Definition sys_null.c:32

References benchmark_time, ca_dedicated, cls, Con_Printf(), Curl_Select(), host, cvar_t::integer, lhnet_socketlist, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, lhnetsocket_t::list, List_For_Each_Entry, NULL, host_static_t::restless, client_static_t::state, sv_checkforpacketsduringsleep, sys_debugsleep, Sys_DirtyTime(), Sys_Error(), Sys_SDL_Delay(), sys_supportsdlgetticks, sys_usenoclockbutbenchmark, sys_usesdldelay, and time.

Referenced by attempt_malloc(), CL_Frame(), SV_ThreadFunc(), Sys_Frame(), and TaskQueue_ThreadFunc().

◆ Sys_TimeString()

size_t Sys_TimeString ( char buf[],
size_t bufsize,
const char * timeformat )
Returns
current timestamp

Definition at line 45 of file sys_shared.c.

46{
47 time_t mytime = time(NULL);
48 size_t strlen;
49#if _MSC_VER >= 1400
50 struct tm mytm;
51 localtime_s(&mytm, &mytime);
52 strlen = strftime(buf, bufsize, timeformat, &mytm);
53#else
54 strlen = strftime(buf, bufsize, timeformat, localtime(&mytime));
55#endif
56 if (!strlen) // means the array contents are undefined (but it's not always an error)
57 buf[0] = '\0'; // better fix it
58 return strlen;
59}
cvar_t timeformat
Definition host.c:56

References buf, NULL, strlen(), time, and timeformat.

Referenced by CL_FinishTimeDemo(), CL_Locs_Save_f(), CL_ParseServerInfo(), Con_MaskPrint(), Sbar_ShowFPS(), SCR_ScreenShot_f(), and SV_SendServerinfo().

◆ Sys_UpdateOutFD_c()

static void Sys_UpdateOutFD_c ( cvar_t * var)
static

Definition at line 342 of file sys_shared.c.

343{
344 switch (sys_stdout.integer)
345 {
346 case 0: sys.outfd = -1; break;
347 default:
348 case 1: sys.outfd = fileno(stdout); break;
349 case 2: sys.outfd = fileno(stderr); break;
350 }
351}

References cvar_t::integer, sys_t::outfd, sys, and sys_stdout.

Referenced by Sys_Init_Commands(), and Sys_Main().

◆ Sys_UpdateTime()

static double Sys_UpdateTime ( double newtime,
double oldtime )
inlinestatic

Definition at line 1109 of file sys_shared.c.

1110{
1111 double time = newtime - oldtime;
1112
1113 if (time < 0)
1114 {
1115 // warn if it's significant
1116 if (time < -0.01)
1117 Con_Printf(CON_WARN "Host_UpdateTime: time stepped backwards (went from %f to %f, difference %f)\n", oldtime, newtime, time);
1118 time = 0;
1119 }
1120 else if (time >= 1800)
1121 {
1122 Con_Printf(CON_WARN "Host_UpdateTime: time stepped forward (went from %f to %f, difference %f)\n", oldtime, newtime, time);
1123 time = 0;
1124 }
1125
1126 return time;
1127}
#define CON_WARN
Definition console.h:101

References Con_Printf(), CON_WARN, and time.

Referenced by Sys_Frame().

Variable Documentation

◆ benchmark_time

double benchmark_time
static

Definition at line 317 of file sys_shared.c.

Referenced by Sys_DirtyTime(), and Sys_Sleep().

◆ sys

◆ sys_debugsleep

cvar_t sys_debugsleep = {CF_SHARED, "sys_debugsleep", "0", "write requested and attained sleep times to standard output, to be used with gnuplot"}
static

Definition at line 305 of file sys_shared.c.

305{CF_SHARED, "sys_debugsleep", "0", "write requested and attained sleep times to standard output, to be used with gnuplot"};
#define CF_SHARED
Definition cmd.h:67

Referenced by Sys_Init_Commands(), and Sys_Sleep().

◆ sys_libdir

cvar_t sys_libdir = {CF_READONLY | CF_SHARED, "sys_libdir", "", "Default engine library directory"}

Definition at line 302 of file sys_shared.c.

302{CF_READONLY | CF_SHARED, "sys_libdir", "", "Default engine library directory"};
#define CF_READONLY
cvar cannot be changed from the console or the command buffer, and is considered CF_PERSISTENT
Definition cmd.h:54

Referenced by Sys_Init_Commands().

◆ sys_stdout

cvar_t sys_stdout = {CF_SHARED, "sys_stdout", "1", "0: nothing is written to stdout (-nostdout cmdline option sets this), 1: normal messages are written to stdout, 2: normal messages are written to stderr (-stderr cmdline option sets this)"}
static

Definition at line 312 of file sys_shared.c.

312{CF_SHARED, "sys_stdout", "1", "0: nothing is written to stdout (-nostdout cmdline option sets this), 1: normal messages are written to stdout, 2: normal messages are written to stderr (-stderr cmdline option sets this)"};

Referenced by Sys_Init_Commands(), Sys_Main(), and Sys_UpdateOutFD_c().

◆ sys_stdout_blocks

cvar_t sys_stdout_blocks = {CF_SHARED, "sys_stdout_blocks", "0", "1: writes to stdout and stderr streams will block (causing a stutter or complete halt) if the buffer is full, ensuring no messages are lost at a price"}
static

Definition at line 314 of file sys_shared.c.

314{CF_SHARED, "sys_stdout_blocks", "0", "1: writes to stdout and stderr streams will block (causing a stutter or complete halt) if the buffer is full, ensuring no messages are lost at a price"};

Referenced by Sys_Init_Commands(), and Sys_Print().

◆ sys_usenoclockbutbenchmark

cvar_t sys_usenoclockbutbenchmark = {CF_SHARED, "sys_usenoclockbutbenchmark", "0", "don't use ANY real timing, and simulate a clock (for benchmarking); the game then runs as fast as possible. Run a QC mod with bots that does some stuff, then does a quit at the end, to benchmark a server. NEVER do this on a public server."}

Definition at line 301 of file sys_shared.c.

301{CF_SHARED, "sys_usenoclockbutbenchmark", "0", "don't use ANY real timing, and simulate a clock (for benchmarking); the game then runs as fast as possible. Run a QC mod with bots that does some stuff, then does a quit at the end, to benchmark a server. NEVER do this on a public server."};

Referenced by Sys_DirtyTime(), Sys_Init_Commands(), and Sys_Sleep().

◆ sys_usesdldelay

cvar_t sys_usesdldelay = {CF_SHARED, "sys_usesdldelay", "0", "use SDL_Delay() (low precision, for debugging)"}
static

Definition at line 307 of file sys_shared.c.

307{CF_SHARED, "sys_usesdldelay", "0", "use SDL_Delay() (low precision, for debugging)"};

Referenced by Sys_Init_Commands(), and Sys_Sleep().

◆ sys_usesdlgetticks

cvar_t sys_usesdlgetticks = {CF_SHARED, "sys_usesdlgetticks", "0", "use SDL_GetTicks() timer (low precision, for debugging)"}
static

Definition at line 306 of file sys_shared.c.

306{CF_SHARED, "sys_usesdlgetticks", "0", "use SDL_GetTicks() timer (low precision, for debugging)"};

Referenced by Sys_DirtyTime(), and Sys_Init_Commands().