Esempio n. 1
0
int aioPoll(int microSeconds)
{
  int	 fd;
  fd_set rd, wr, ex;
  unsigned long long us;

  FPRINTF((stderr, "aioPoll(%d)\n", microSeconds));
  DO_TICK(SHOULD_TICK());

  /* get out early if there is no pending i/o and no need to relinquish cpu */

  if ((maxFd == 0) && (microSeconds == 0))
    return 0;

  rd= rdMask;
  wr= wrMask;
  ex= exMask;
  us= ioUTCMicroseconds();

  for (;;)
    {
      struct timeval tv;
      int n;
      unsigned long long now;
      tv.tv_sec=  microSeconds / 1000000;
      tv.tv_usec= microSeconds % 1000000;
      n= select(maxFd, &rd, &wr, &ex, &tv);
      if (n  > 0) break;
      if (n == 0) return 0;
      if (errno && (EINTR != errno))
	{
	  fprintf(stderr, "errno %d\n", errno);
	  perror("select");
	  return 0;
	}
      now= ioUTCMicroseconds();
      microSeconds -= max(now - us,1);
      if (microSeconds <= 0)
	return 0;
      us= now;
    }

  for (fd= 0; fd < maxFd; ++fd)
    {
#     define _DO(FLAG, TYPE)				\
      {							\
	if (FD_ISSET(fd, &TYPE))			\
	  {						\
	    aioHandler handler= TYPE##Handler[fd];	\
	    FD_CLR(fd, &TYPE##Mask);			\
	    TYPE##Handler[fd]= undefinedHandler;	\
	    handler(fd, clientData[fd], FLAG);		\
	  }						\
      }
      _DO_FLAG_TYPE();
#     undef _DO
    }
  return 1;
}
void
fakevm()
{
	while (1) {
		(void)ioUTCMicroseconds();
		if ((vmcount += 1ULL) % CHECK_COUNT == 0
		 && ioHeartbeatFrequency(0) == 0)
			lockedup("in vm");
		if (checkForEvents) {
			checkForEvents = 0;
			ioSynchronousCheckForEvents();
		}
	}
}
Esempio n. 3
0
/* Add or remove a synchronous tickee.  If periodms is non zero add the tickee
 * calling it every periodms, aligned to roundms, if non-zero.  If periodms is
 * zero, remove tickee.
 */
void
addSynchronousTickee(void (*tickee)(void), unsigned periodms, unsigned roundms)
{
	int i;

	if (!periodms) {
		for (i = 0; i < numSyncTickees; i++)
			if (synch[i].tickee == tickee) {
				--numSyncTickees;
				if (i < numSyncTickees)
					memmove(synch + i,
							synch + i + 1,
							sizeof(synch[i]) * (numSyncTickees - i));
				return;
			}
		return;
	}
	for (i = 0; i < NUM_SYNCHRONOUS_TICKEES; i++)
		if (i >= numSyncTickees
		 || !synch[i].tickee
		 || synch[i].tickee == tickee) {
			synch[i].tickee = tickee;
			synch[i].tickeePeriodUsecs = periodms * MicrosecondsPerMillisecond;
			synch[i].tickeeDeadlineUsecs = synch[i].tickeePeriodUsecs
										+ ioUTCMicroseconds();
			if (roundms) {
				synch[i].tickeeDeadlineUsecs -= synch[i].tickeeDeadlineUsecs
										% (roundms * MicrosecondsPerMillisecond);
				if (synch[i].tickeeDeadlineUsecs < ioUTCMicroseconds())
					synch[i].tickeeDeadlineUsecs += synch[i].tickeePeriodUsecs;
			}
			if (i >= numSyncTickees)
				++numSyncTickees;
			return;
		}
	error("ran out of synchronous tickee slots");
}
void
hptick(void)
{
	unsigned long long start = ioUTCMicroseconds();

	yield = 1;
	sqLowLevelMFence();
	while (ioUTCMicroseconds() - start < hptickusecs)
		if ((hpcount += 1ULL) % CHECK_COUNT == 0
		 && ioHeartbeatFrequency(0) == 0)
			lockedup("in hptick");
	yield = 0;
	sqLowLevelMFence();
	if (yieldMethod == yield_via_wait_signal) {
		if (pthread_mutex_trylock(&yield_sync) == 0) {/* success */
			pthread_mutex_unlock(&yield_sync);
			not_blocked_count += 1;
		}
		else {
			pthread_cond_signal(&yield_cond);
			unblock_count += 1;
		}
	}
}
Esempio n. 5
0
void
ioSynchronousCheckForEvents()
{
	int i;

#if ITIMER_HEARTBEAT
	extern void yieldToHighPriorityTickerThread(void);
	sqLowLevelMFence();
	if (shouldYieldToHighPriorityTickerThread)
		yieldToHighPriorityTickerThread();
#endif
	for (i = 0; i < numSyncTickees; i++)
		if (synch[i].tickee
		 && ioUTCMicroseconds() >= synch[i].tickeeDeadlineUsecs) {
			synch[i].tickeeDeadlineUsecs += synch[i].tickeePeriodUsecs;
			synch[i].tickee();
		}
}
Esempio n. 6
0
/* Add or remove an asynchronous tickee.  If periodms is non zero add the
 * tickee, calling it every periodms.
 *
 * N.B. addHighPriorityTickee is called from the VM thread, whereas
 * checkHighPriorityTickees is called from the high-priority heartbeat thread
 * (or an interrupt).  The above 64-bit variables must therefore be read and
 * written atomically to avoid either thread reading or writing a modified
 * half of the variable while the other half has yet to be updated.
 */
void
addHighPriorityTickee(void (*tickee)(void), unsigned periodms)
{
	int i;

	if (!periodms) {
		for (i = 0; i < numAsyncTickees; i++)
			/* We cannot safely copy the data to keep used tickees contiguous
			 * because checkHighPriorityTickees could be called during the move.
			 * This implies first checking for an existing tickee below before
			 * using an empty slot because an empty slot can be created before
			 * a used (and subsequently modified) tickee.
			 */
			if (async[i].tickee == tickee) {
				async[i].tickee = 0;
				sqLowLevelMFence();
				return;
			}
		return;
	}
	for (i = 0; i < numAsyncTickees; i++)
		if (async[i].tickee == tickee)
			break;
	if (i >= numAsyncTickees)
		for (i = 0; i < NUM_ASYNCHRONOUS_TICKEES; i++)
			if (i >= numAsyncTickees
			 || !async[i].tickee)
				break;
	if (i >= NUM_ASYNCHRONOUS_TICKEES)
		error("ran out of asyncronous tickee slots");

	/* first disable the tickee while updating the entry. */
	async[i].tickee = 0;
	sqLowLevelMFence();
	async[i].tickeePeriodUsecs = periodms * MicrosecondsPerMillisecond;
	async[i].tickeeDeadlineUsecs = async[i].tickeePeriodUsecs
								+ ioUTCMicroseconds();
	async[i].inProgress = 0;
	async[i].tickee = tickee;
	if (i >= numAsyncTickees)
		++numAsyncTickees;
	sqLowLevelMFence();
}