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; } } }
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; }