I remember the time around circa 1996 <-> 2000, NT4/2000 where high uptimes on my work machines (i remember a NT4 machine with an uptime of 1200 days), the performance stayed the same. The network stack etc ran fine, and security wasn’t a problem..
Nowadays, it’s different. Windows 2003 is a piece of crap, it runs like shit when it’s up for a long time… I’ve noticed machines that have been up for over 30 days and ones that have been up 3 days have different performance (game server bullet reg) profiles per say. It’s driving me up the wall.
The problem is, I can’t figure out why! Doesn’t seem to be any memory leaks, paged pool/nonpaged pool memory looks good on the 30 day machine.
Microsoft is the largest software company in the world but they can’t seem to stop shit from breaking.
Bottom line, *NIX is far superior to windows when it comes to performance of time critical apps, like gameservers. You shouldn’t have to reboot a machine because it doesn’
t feel right and/or performs badly
I don’t have to reboot our cisco gear if the PPS on vlan12 isn’t as high as it should be
Misc
[root@bravo /tmp]# ktrace -p 86175 && sleep 10 && ktrace -C
Ktrace is a very good utility
[root@bravo /tmp]# linux_kdump | grep linux_nanosleep | wc -l
19815
[root@bravo /tmp]# linux_kdump | grep gettimeofday | wc -l
109332
gettimeofday() is used on source to measure the server FPS.
nanosleep() is used, for sleeping and waking up for a frame.
So, this means a couple of things. gettimeofday is archaic, nonstandard, and imprecise. srcds should use clock_gettime() instead. Don’t trust rcon stats for FPS, because in reality it doesn’t mean anything. As long as the ticrate stays at the level the server says it is, then everything is fine. In the case of CS:Source, the tickrate and server FPS are completely seperate, unlike HL1.6
#define gettimeofday(tv) clock_gettime(CLOCK_REALTIME, tv)
Still reversing the game to see what high fps really does.
Code, Game Stuff
#if !defined ( _WIN32 )
char *pPingType;
int type;
if ( (CheckParm ("-pingboost", &pPingType)) && pPingType )
{
type=atoi( pPingType );
switch( type ) {
case 1:
//printf("Using timer method\n");
signal(SIGALRM,alarmFunc);
Sys_Sleep=Sys_Sleep_Timer;
break;
case 2:
Sys_Sleep = Sys_Sleep_Select;
break;
case 3:
Sys_Sleep = Sys_Sleep_Net;
// we Sys_GetProcAddress NET_Sleep() from
//engine_i386.so later in this function
break;
default: // just in case
Sys_Sleep=Sys_Sleep_Old;
break;
}
}
#endif
Here’s the functions that are used by -pingboost {1,2,3}
void Sys_Sleep_Select( int msec )
{
#ifdef _WIN32
Sleep( msec );
#else // _WIN32
struct timeval tv;
// Assumes msec < 1000
tv.tv_sec = 0;
tv.tv_usec = 1000 * msec;
select( 1, NULL, NULL, NULL, &tv );
#endif // _WIN32
}
We use select() here, nothing special, nfds with 1 and timeout being tv.
void Sys_Sleep_Timer( int msec )
{
#ifdef _WIN32
Sleep( msec );
#else
// linux runs on a 100Hz scheduling clock, so the minimum latency from
// usleep is 10msec. However, people want lower latency than this..
//
// There are a few solutions, one is to use the realtime scheduler in the
// kernel BUT this needs root privelleges to start. It also can play
// unfriendly with other programs.
// Another solution is to use software timers, they use the RTC of the
// system and are accurate to microseconds (or so).
// timers, via setitimer() are used here
struct itimerval tm;
tm.it_value.tv_sec=msec/1000; // convert msec to seconds
tm.it_value.tv_usec=(msec%1000)*1E3; // get the number of msecs and change to micros
tm.it_interval.tv_sec = 0;
tm.it_interval.tv_usec = 0;
paused=0;
if( setitimer(ITIMER_REAL,&tm,NULL)==0)
{ // set the timer to trigger
pause(); // wait for the signal
}
paused=1;
#endif
}
Doing a Sleep(1) for 1msec on windows 2003 returns 1.95 (1000 / 1.95 = 512.82fps)
Doing a usleep(1) on *NIX returns better results, around 1.10 depending on the OS etc.
Main
On your vlan(s) you will need to “no ip redirect” to prevent the CPU usage from going up the wall.
Networking