+
+void Sys_ProvideSelfFD(void)
+{
+ if(com_selffd != -1)
+ return;
+ com_selffd = FS_SysOpenFD(Sys_FindExecutableName(), "rb", false);
+}
+
+// for x86 cpus only... (x64 has SSE2_PRESENT)
+#if defined(SSE_POSSIBLE) && !defined(SSE2_PRESENT)
+// code from SDL, shortened as we can expect CPUID to work
+static int CPUID_Features(void)
+{
+ int features = 0;
+# if defined(__GNUC__) && defined(__i386__)
+ __asm__ (
+" movl %%ebx,%%edi\n"
+" xorl %%eax,%%eax \n"
+" incl %%eax \n"
+" cpuid # Get family/model/stepping/features\n"
+" movl %%edx,%0 \n"
+" movl %%edi,%%ebx\n"
+ : "=m" (features)
+ :
+ : "%eax", "%ecx", "%edx", "%edi"
+ );
+# elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
+ __asm {
+ xor eax, eax
+ inc eax
+ cpuid ; Get family/model/stepping/features
+ mov features, edx
+ }
+# else
+# error SSE_POSSIBLE set but no CPUID implementation
+# endif
+ return features;
+}
+#endif
+
+#ifdef SSE_POSSIBLE
+qboolean Sys_HaveSSE(void)
+{
+ // COMMANDLINEOPTION: SSE: -nosse disables SSE support and detection
+ if(COM_CheckParm("-nosse"))
+ return false;
+#ifdef SSE_PRESENT
+ return true;
+#else
+ // COMMANDLINEOPTION: SSE: -forcesse enables SSE support and disables detection
+ if(COM_CheckParm("-forcesse") || COM_CheckParm("-forcesse2"))
+ return true;
+ if(CPUID_Features() & (1 << 25))
+ return true;
+ return false;
+#endif
+}
+
+qboolean Sys_HaveSSE2(void)
+{
+ // COMMANDLINEOPTION: SSE2: -nosse2 disables SSE2 support and detection
+ if(COM_CheckParm("-nosse") || COM_CheckParm("-nosse2"))
+ return false;
+#ifdef SSE2_PRESENT
+ return true;
+#else
+ // COMMANDLINEOPTION: SSE2: -forcesse2 enables SSE2 support and disables detection
+ if(COM_CheckParm("-forcesse2"))
+ return true;
+ if((CPUID_Features() & (3 << 25)) == (3 << 25)) // SSE is 1<<25, SSE2 is 1<<26
+ return true;
+ return false;
+#endif
+}
+#endif
+
+/// called to set process priority for dedicated servers
+#if defined(__linux__)
+#include <sys/resource.h>
+#include <errno.h>
+static int nicelevel;
+static qboolean nicepossible;
+static qboolean isnice;
+void Sys_InitProcessNice (void)
+{
+ struct rlimit lim;
+ nicepossible = false;
+ if(COM_CheckParm("-nonice"))
+ return;
+ errno = 0;
+ nicelevel = getpriority(PRIO_PROCESS, 0);
+ if(errno)
+ {
+ Con_Printf("Kernel does not support reading process priority - cannot use niceness\n");
+ return;
+ }
+ if(getrlimit(RLIMIT_NICE, &lim))
+ {
+ Con_Printf("Kernel does not support lowering nice level again - cannot use niceness\n");
+ return;
+ }
+ if(lim.rlim_cur != RLIM_INFINITY && nicelevel < (int) (20 - lim.rlim_cur))
+ {
+ Con_Printf("Current nice level is below the soft limit - cannot use niceness\n");
+ return;
+ }
+ nicepossible = true;
+ isnice = false;
+}
+void Sys_MakeProcessNice (void)
+{
+ if(!nicepossible)
+ return;
+ if(isnice)
+ return;
+ Con_DPrintf("Process is becoming 'nice'...\n");
+ if(setpriority(PRIO_PROCESS, 0, 19))
+ Con_Printf("Failed to raise nice level to %d\n", 19);
+ isnice = true;
+}
+void Sys_MakeProcessMean (void)
+{
+ if(!nicepossible)
+ return;
+ if(!isnice)
+ return;
+ Con_DPrintf("Process is becoming 'mean'...\n");
+ if(setpriority(PRIO_PROCESS, 0, nicelevel))
+ Con_Printf("Failed to lower nice level to %d\n", nicelevel);
+ isnice = false;
+}
+#else
+void Sys_InitProcessNice (void)
+{
+}
+void Sys_MakeProcessNice (void)
+{
+}
+void Sys_MakeProcessMean (void)
+{
+}
+#endif