Exemple #1
0
void Sleep_Sleep(struct qw_connection *qwc, unsigned int sleeptime)
{
	unsigned int real_sleep_time;
	unsigned long long curtime;
	unsigned long long endtime;
    int sleep_granularity;

    sleep_granularity = QWC_GetSleepGranularity(qwc);

	endtime = Sys_IntTime();

	endtime += sleeptime;

	if (sleeptime >= sleep_granularity)
	{
		real_sleep_time = sleeptime - sleep_granularity;

		usleep(real_sleep_time);
	}

	do
	{
		curtime = Sys_IntTime();
	} while(curtime < endtime);

#if 0
	if (curtime.tv_usec > 100)
	{
		printf("Asked to sleep %d us, usleept %d us\n", sleeptime, real_sleep_time);
		printf("Overslept %d us\n", curtime.tv_usec);
	}
#endif
}
unsigned int Con_DrawNotify(void)
{
	unsigned int maxnotifylines;
	unsigned int notifytime;
	unsigned long long now;
	unsigned int i;

	now = Sys_IntTime();

	notifytime = ((double)con_notifytime.value)*1000000;

	maxnotifylines = con_notifylines.value;
	if (maxnotifylines > MAXNOTIFYLINES)
		maxnotifylines = MAXNOTIFYLINES;

	i = (notifystart + (MAXNOTIFYLINES - maxnotifylines)) % MAXNOTIFYLINES;

	while(maxnotifylines && notifytimes[i] + notifytime < now)
	{
		i++;
		i %= MAXNOTIFYLINES;
		maxnotifylines--;
	}

	Con_DrawTextLines(0, maxnotifylines, lastline);

	return maxnotifylines;
}
int Sys_Input_GetKeyEvent(struct input_data *input, keynum_t *keynum, qboolean *down)
{
	pthread_mutex_lock(&input->key_mutex);
	
	if (input->repeatkey)
	{
		long long curtime = Sys_IntTime();

		while (input->nextrepeattime <= curtime)
		{
			add_to_event_queue(input, input->repeatkey, true);
			input->nextrepeattime += input->key_repeat_delay;
		}
	}
	
	pthread_mutex_unlock(&input->key_mutex);

	if (input->buttoneventhead == input->buttoneventtail)
	{
		return 0;
	}

	*keynum = input->buttonevents[input->buttoneventtail].key;
	*down = input->buttonevents[input->buttoneventtail].down;

	sequencepointkthx();

	input->buttoneventtail = (input->buttoneventtail + 1) % NUMBUTTONEVENTS;

	return 1;
}
static void ServerScanner_Thread_CheckTimeout(struct ServerScanner *serverscanner)
{
	struct qwserverpriv *qwserver;
	struct qwserverpriv *prevqwserver;
	unsigned long long curtime;

	curtime = Sys_IntTime();

	prevqwserver = 0;
	qwserver = serverscanner->qwserversscaninprogress;
	while(qwserver)
	{
		if (qwserver->packetsendtime + QWSERVERTIMEOUT <= curtime)
		{
			qwserver->pub.status = QWSS_FAILED;

			if (prevqwserver)
				prevqwserver->nextscaninprogress = qwserver->nextscaninprogress;
			else
				serverscanner->qwserversscaninprogress = qwserver->nextscaninprogress;

			serverscanner->numqwserversscaninprogress--;
		}
		else
			prevqwserver = qwserver;

		qwserver = qwserver->nextscaninprogress;
	}

	prevqwserver = 0;
	qwserver = serverscanner->qwserverspinginprogress;
	while(qwserver)
	{
		if (qwserver->packetsendtime + QWSERVERTIMEOUT <= curtime)
		{
			qwserver->pub.pingtime = 999999;

			if (prevqwserver)
				prevqwserver->nextpinginprogress = qwserver->nextpinginprogress;
			else
				serverscanner->qwserverspinginprogress = qwserver->nextpinginprogress;

			serverscanner->numqwserverspinginprogress--;
		}
		else
			prevqwserver = qwserver;

		qwserver = qwserver->nextpinginprogress;
	}
}
static void ServerScanner_Thread_SendQWRequest(struct ServerScanner *serverscanner, struct qwserverpriv *qwserver)
{
	static const char querystring[] = "\xff\xff\xff\xff" "status 23\n";

	qwserver->packetsendtime = Sys_IntTime();
	Sys_Net_Send(serverscanner->netdata, serverscanner->sockets[NA_IPV4], querystring, sizeof(querystring), &qwserver->pub.addr);
	if (qwserver->pub.status != QWSS_REQUESTSENT)
	{
		qwserver->pub.status = QWSS_REQUESTSENT;
		serverscanner->numqwserversscaninprogress++;
		qwserver->nextscaninprogress = serverscanner->qwserversscaninprogress;
		serverscanner->qwserversscaninprogress = qwserver;
	}
}
static void ServerScanner_Thread_SendQWPingRequest(struct ServerScanner *serverscanner, struct qwserverpriv *qwserver)
{
	unsigned long long curtime;
	static const char querystring[] = "\xff\xff\xff\xff" "k";

	curtime = Sys_IntTime();

	qwserver->packetsendtime = curtime;
	Sys_Net_Send(serverscanner->netdata, serverscanner->sockets[NA_IPV4], querystring, sizeof(querystring), &qwserver->pub.addr);

	serverscanner->numqwserverspinginprogress++;
	qwserver->nextpinginprogress = serverscanner->qwserverspinginprogress;
	serverscanner->qwserverspinginprogress = qwserver;

	serverscanner->lastpingtime = curtime;
}
static void Con_LayoutLine(unsigned int offset)
{
	unsigned int i;
	unsigned int j;
	unsigned short linestartcolour;
	unsigned short lastcolour;

	linestartcolour = 0x0fff;

	i = Con_BufferStringLength(offset);

	do
	{
		j = Con_BufferFindLinebreak(offset, i, &lastcolour);

		if ((lastline+2)%maxlines == firstline)
		{
			if (!Con_ExpandMaxLines())
			{
				firstline++;
				firstline = firstline % maxlines;
			}
		}

		if (displayline == lastline)
		{
			displayline++;
			displayline %= maxlines;
		}

		lastline++;
		lastline %= maxlines;

		lines[lastline] = offset;
		linestartcolours[lastline] = linestartcolour;

		notifytimes[notifystart] = Sys_IntTime();
		notifystart++;
		notifystart %= MAXNOTIFYLINES;

		offset += j;
		offset %= consize;
		i -= j;

		linestartcolour = lastcolour;
	} while(i);
}
unsigned int ServerScanner_DoStuffInternal(struct ServerScanner *serverscanner)
{
	struct qwserverpriv *qwserver;
	unsigned int i;
	unsigned long long curtime;
	unsigned int timeout;
	int r;
	unsigned char buf[8192];
	struct netaddr addr;

	if (serverscanner->status == SSS_ERROR || serverscanner->status == SSS_IDLE)
		return 50000;

	if (!serverscanner->initialstuffdone)
	{
		if (!ServerScanner_Thread_Init(serverscanner))
		{
			serverscanner->status = SSS_ERROR;
			return 50000;
		}

		ServerScanner_Thread_LookUpMasters(serverscanner);
		ServerScanner_Thread_OpenSockets(serverscanner);

		if (!serverscanner->numvalidmasterservers)
		{
			serverscanner->status = SSS_ERROR;
			return 50000;
		}

		serverscanner->starttime = Sys_IntTime();

		ServerScanner_Thread_QueryMasters(serverscanner);

		serverscanner->initialstuffdone = 1;
	}

	for(i=1;i<NA_NUMTYPES;i++)
	{
		if (!serverscanner->sockets[i])
			continue;

		while((r = Sys_Net_Receive(serverscanner->netdata, serverscanner->sockets[i], buf, sizeof(buf), &addr)) > 0)
		{
			ServerScanner_Thread_HandlePacket(serverscanner, buf, r, &addr);
		}
	}

	Sys_Thread_LockMutex(serverscanner->mutex);

	ServerScanner_Thread_CheckTimeout(serverscanner);

	if (serverscanner->status == SSS_SCANNING)
	{
		if (serverscanner->qwserversscanwaiting == 0 && serverscanner->qwserversscaninprogress == 0 && Sys_IntTime() > serverscanner->starttime + 2000000)
		{
			serverscanner->status = SSS_PINGING;
		}
	}

	if (serverscanner->status == SSS_PINGING)
	{
		if (serverscanner->qwserverspingwaiting == 0 && serverscanner->qwserverspinginprogress == 0)
		{
			if (serverscanner->qwserversscanwaiting)
				serverscanner->status = SSS_SCANNING;
			else
				serverscanner->status = SSS_IDLE;
		}
	}

	curtime = Sys_IntTime();

#warning Needs to schedule servers for scanning
	while (serverscanner->status == SSS_SCANNING && serverscanner->numqwserversscaninprogress < MAXCONCURRENTSCANS && serverscanner->qwserversscanwaiting)
	{
		qwserver = serverscanner->qwserversscanwaiting;
		ServerScanner_Thread_SendQWRequest(serverscanner, qwserver);
		serverscanner->qwserversscanwaiting = qwserver->nextscanwaiting;
		qwserver->nextscanwaiting = 0;
	}
			
	while (serverscanner->status == SSS_PINGING && serverscanner->numqwserverspinginprogress < MAXCONCURRENTPINGS && serverscanner->qwserverspingwaiting && serverscanner->lastpingtime + PINGINTERVAL <= curtime)
	{
		qwserver = serverscanner->qwserverspingwaiting;
		ServerScanner_Thread_SendQWPingRequest(serverscanner, qwserver);
		serverscanner->qwserverspingwaiting = qwserver->nextpingwaiting;
		qwserver->nextpingwaiting = 0;
	}

	timeout = 50000;
	if (serverscanner->status == SSS_SCANNING)
	{
		qwserver = serverscanner->qwserversscaninprogress;
		while(qwserver)
		{
			if (qwserver->packetsendtime + QWSERVERTIMEOUT >= curtime && qwserver->packetsendtime + QWSERVERTIMEOUT - curtime < timeout)
			{
				timeout = qwserver->packetsendtime + QWSERVERTIMEOUT - curtime;
			}
		
			qwserver = qwserver->nextscaninprogress;
		}
	}
	else if (serverscanner->status == SSS_PINGING)
	{
		qwserver = serverscanner->qwserverspinginprogress;
		while(qwserver)
		{
			if (qwserver->packetsendtime + QWSERVERTIMEOUT >= curtime && qwserver->packetsendtime + QWSERVERTIMEOUT - curtime < timeout)
			{
				timeout = qwserver->packetsendtime + QWSERVERTIMEOUT - curtime;
			}
	
			qwserver = qwserver->nextpinginprogress;
		}

		if (serverscanner->qwserverspingwaiting && serverscanner->lastpingtime + PINGINTERVAL >= curtime)
		{
			if (serverscanner->lastpingtime + PINGINTERVAL - curtime < timeout)
			{
				timeout = serverscanner->lastpingtime + PINGINTERVAL - curtime;
			}
		}
	}

	Sys_Thread_UnlockMutex(serverscanner->mutex);

	return timeout;
}
static void ServerScanner_Thread_HandlePacket(struct ServerScanner *serverscanner, unsigned char *data, unsigned int datalen, struct netaddr *addr)
{
	struct qwserverpriv *qwserver;
	struct qwserverpriv *prevqwserver;
	unsigned int i;
	struct netaddr newaddr;

	if (datalen && data[0] == 'l')
	{
		prevqwserver = 0;
		qwserver = serverscanner->qwserverspinginprogress;
		while(qwserver)
		{
			if (NET_CompareAdr(&qwserver->pub.addr, addr))
			{
				Sys_Thread_LockMutex(serverscanner->mutex);

				qwserver->pub.pingtime = Sys_IntTime() - qwserver->packetsendtime;

				serverscanner->updated = 1;

				Sys_Thread_UnlockMutex(serverscanner->mutex);

				if (prevqwserver)
					prevqwserver->nextpinginprogress = qwserver->nextpinginprogress;
				else
					serverscanner->qwserverspinginprogress = qwserver->nextpinginprogress;

				qwserver->nextpinginprogress = 0;
				serverscanner->numqwserverspinginprogress--;

				return;
			}

			prevqwserver = qwserver;
			qwserver = qwserver->nextpinginprogress;
		}

		return;
	}

	if (datalen < 4 || data[0] != 255 || data[1] != 255 || data[2] != 255 || data[3] != 255)
		return;

	data += 4;
	datalen -= 4;

	for(i=0;i<serverscanner->nummasterservers;i++)
	{
		if (NET_CompareAdr(&serverscanner->masterservers[i].addr, addr))
		{
			if (datalen < 2 || data[0] != 'd' || data[1] != '\n')
				return;

			data += 2;
			datalen -= 2;

			if ((datalen%6) != 0)
				return;

			for(i=0;i<datalen;i+=6)
			{
				if (serverscanner->numqwservers > 10000)
					return;

				newaddr.type = NA_IPV4;
				newaddr.addr.ipv4.address[0] = data[i + 0];
				newaddr.addr.ipv4.address[1] = data[i + 1];
				newaddr.addr.ipv4.address[2] = data[i + 2];
				newaddr.addr.ipv4.address[3] = data[i + 3];
				newaddr.addr.ipv4.port = (data[i + 4]<<8)|data[i + 5];

#warning Slow as f*****g hell.
				qwserver = serverscanner->qwservers;
				while(qwserver)
				{
					if (NET_CompareAdr(&newaddr, &qwserver->pub.addr))
						break;

					qwserver = qwserver->next;
				}

				if (qwserver && NET_CompareAdr(&newaddr, &qwserver->pub.addr))
				{
					continue;
				}

				qwserver = malloc(sizeof(*qwserver));
				if (qwserver == 0)
					break;

				memset(qwserver, 0, sizeof(*qwserver));

				qwserver->pub.addr = newaddr;
				qwserver->pub.status = QWSS_WAITING;

				if (serverscanner->numqwserversscaninprogress < MAXCONCURRENTSCANS)
				{
					ServerScanner_Thread_SendQWRequest(serverscanner, qwserver);
				}
				else
				{
					qwserver->nextscanwaiting = serverscanner->qwserversscanwaiting;
					serverscanner->qwserversscanwaiting = qwserver;
				}

				Sys_Thread_LockMutex(serverscanner->mutex);

				qwserver->next = serverscanner->qwservers;
				serverscanner->qwservers = qwserver;
				serverscanner->numqwservers++;

				Sys_Thread_UnlockMutex(serverscanner->mutex);
			}

			Sys_Thread_LockMutex(serverscanner->mutex);
			serverscanner->updated = 1;
			Sys_Thread_UnlockMutex(serverscanner->mutex);

			return;
		}
	}

	prevqwserver = 0;
	qwserver = serverscanner->qwserversscaninprogress;
	while(qwserver)
	{
		if (NET_CompareAdr(&qwserver->pub.addr, addr) && qwserver->pub.status == QWSS_REQUESTSENT)
		{
			Sys_Thread_LockMutex(serverscanner->mutex);

			serverscanner->updated = 1;

			ServerScanner_Thread_ParseQWServerReply(serverscanner, qwserver, data, datalen);

			Sys_Thread_UnlockMutex(serverscanner->mutex);

			if (prevqwserver)
				prevqwserver->nextscaninprogress = qwserver->nextscaninprogress;
			else
				serverscanner->qwserversscaninprogress = qwserver->nextscaninprogress;

			qwserver->nextscaninprogress = 0;
			serverscanner->numqwserversscaninprogress--;

			qwserver->nextpingwaiting = serverscanner->qwserverspingwaiting;
			serverscanner->qwserverspingwaiting = qwserver;

			return;
		}

		prevqwserver = qwserver;
		qwserver = qwserver->nextscaninprogress;
	}
}
static void input_callback(void *context, IOReturn result, void *sender, IOHIDValueRef value)
{
	struct input_data *input = (struct input_data*)context;
	IOHIDElementRef elem = IOHIDValueGetElement(value);
	uint32_t page = IOHIDElementGetUsagePage(elem);
	uint32_t usage = IOHIDElementGetUsage(elem);
	uint32_t val = IOHIDValueGetIntegerValue(value);

	if (page == kHIDPage_GenericDesktop)
	{
		if (input->ignore_mouse)
		{
			return;
		}

		switch (usage)
		{
			case kHIDUsage_GD_X:
				pthread_mutex_lock(&input->mouse_mutex);
				input->mouse_x += val;
				pthread_mutex_unlock(&input->mouse_mutex);
				break;
			case kHIDUsage_GD_Y:
				pthread_mutex_lock(&input->mouse_mutex);
				input->mouse_y += val;
				pthread_mutex_unlock(&input->mouse_mutex);
				break;
			case kHIDUsage_GD_Wheel:
				if ((int32_t)val > 0)
				{
					add_to_event_queue(input, K_MWHEELUP, true);
					add_to_event_queue(input, K_MWHEELUP, false);
				}
				else if ((int32_t)val < 0)
				{
					add_to_event_queue(input, K_MWHEELDOWN, true);
					add_to_event_queue(input, K_MWHEELDOWN, false);
				}
				break;
			default:
				break;
		}
	}
	else if (page == kHIDPage_Button)
	{
		if (input->ignore_mouse)
		{
			return;
		}

		if (usage < 1 || usage > 10)
		{
			usage = 10;
		}

		add_to_event_queue(input, K_MOUSE1 + usage - 1, val ? true : false);
	}
	else if (page == kHIDPage_KeyboardOrKeypad)
	{
		if (usage == kHIDUsage_KeyboardLeftGUI)
		{
			input->left_cmd_key_active = val ? true : false;
		}
		else if (usage == kHIDUsage_KeyboardRightGUI)
		{
			input->right_cmd_key_active = val ? true : false;
		}

		if (usage < sizeof(keytable) && (input->left_cmd_key_active || input->right_cmd_key_active))
		{
			if (keytable[usage] == 'c' && val)
			{
				add_to_event_queue(input, K_COPY, true);
				add_to_event_queue(input, K_COPY, false);
			}
			else if (keytable[usage] == 'v' && val)
			{
				add_to_event_queue(input, K_PASTE, true);
				add_to_event_queue(input, K_PASTE, false);
			}

			return;
		}

		if (usage < sizeof(keytable))
		{
			add_to_event_queue(input, keytable[usage], val ? true : false);

			pthread_mutex_lock(&input->key_mutex);

			if (val)
			{
				input->repeatkey = keytable[usage];
				input->nextrepeattime = Sys_IntTime() + input->key_repeat_initial_delay;
			}
			else
			{
				input->repeatkey = 0;
				input->nextrepeattime = 0;
			}

			pthread_mutex_unlock(&input->key_mutex);
		}
	}
	else if (page == 0xFF)
	{
		if (usage == kHIDUsage_KeyboardErrorUndefined)
		{
			input->fn_key_active = val ? true : false;
		}
	}
}
Exemple #11
0
static int get_sleep_granularity()
{
	unsigned long long basetime;
	unsigned long long sleeptime[NUMSAMPLES];
	int i;
	unsigned long long accum;
	unsigned int avg;
	unsigned int min;
	unsigned int max;
	unsigned int maxdist;
	unsigned int samples;
	double stddev;
	double tmpf;

	samples = NUMSAMPLES;

	for(i=0;i<NUMSAMPLES;i++)
	{
		usleep(1);
		basetime = Sys_IntTime();
		usleep(1);
		sleeptime[i] = Sys_IntTime() - basetime;
	}

	do
	{
		max = 0;
		min = 1000000;
		accum = 0;
		for(i=0;i<samples;i++)
		{
			accum+= sleeptime[i];
			stddev+= ((double)sleeptime[i])*((double)sleeptime[i]);
		
			if (sleeptime[i] < min)
				min = sleeptime[i];
			if (sleeptime[i] > max)
				max = sleeptime[i];
		}

		avg = accum/samples;

		stddev = 0;
		for(i=0;i<samples;i++)
		{
			tmpf = ((double)sleeptime[i]) - avg;
			tmpf*= tmpf;
			stddev+= tmpf;
		}
		stddev = sqrt(stddev/samples);

		maxdist = 0;
		for(i=0;i<samples;i++)
		{
			if (abs(sleeptime[i]-avg) > maxdist)
				maxdist = abs(sleeptime[i]-avg);
		}

#if 0
		printf("avg: %06d min: %06d max: %06d maxdist: %06d stddev: %.2f\n", avg, min, max, maxdist, (float)stddev);
#endif

		for(i=0;i<samples;i++)
		{
			if (abs(sleeptime[i]-avg) == maxdist)
			{
				memmove(&sleeptime[i], &sleeptime[i+1], (samples-i-1)*sizeof(*sleeptime));
				samples--;
				break;
			}
		}
	} while(stddev > (((double)avg)*0.01) && avg > 500); 

	if (samples < NUMSAMPLES/5)
	{
#if 0
		printf("System timing too unstable, assuming 8ms granularity\n");
#endif
		avg = 8000;
	}

	return avg;
}