sima/autoconf/
sima/hosts/i386/
sima/mudlib/
sima/mudlib/kernel/
sima/mudlib/obj/
sima/mudlib/sys/
sima/synhash/mips/
/*  Copyright 1995, 1997 J"orn Rennecke */

#include <signal.h>
#include "common.h"
#include "object.h"
#include "comm.h"
#define NEED_JOBTAB
#include "schedule.h"

int job_mask;

int32 async_current_time, current_time;
volatile int total_alarms, call_out_missing;

static void flag_call_out(void);
struct interactive **pending_link;

typedef union {
  fd_set full;
  struct {
    long i[(MAX_USER+MAX_MISC_DESCRIPTORS-1)/8/sizeof(long)+1];
  } small;
} fd_uset;

void schedule(void) {
    fd_uset readfds[2];
    static const struct itimerval itv = {
	{ TICK_SEC, TICK_USEC } , { TICK_SEC, TICK_USEC }
    };
    static struct sigaction alarm_action = {
	(RETSIGTYPE(*)(int))flag_call_out, 0, SA_RESTART
    };
    struct interactive *new_pending, *old_pending;

    sigaction(SIGALRM, &alarm_action, 0);
    setitimer(ITIMER_REAL, &itv, 0);
    bzero(&readfds, sizeof readfds);
    start_comm(&readfds[0].full);
    pending_link = &new_pending;
    for (;;) {
	struct timeval timeout;
	int npending;

	readfds[1].small = readfds[0].small;
	*pending_link = 0;
	timeout.tv_sec = !((p_int)new_pending|job_tab.mask);
	timeout.tv_usec = 0;
	npending = select(comm_nfds, &readfds[1].full, 0, 0, &timeout);
	old_pending = new_pending;
	pending_link = &new_pending;
	pending_commands(old_pending);
	if (npending <= 0) {
	    if (npending && errno != EINTR)
		perror("select");
	} else {
	    /*
	     * walk_fdset() will read new commands, execute max. one per
	     * user, and append users with remaining commands to
	     * pending_link. It also handles new connections and erq.
	     */
	    walk_fdset(&readfds[1].full, npending);
	}
	job_tab.mask |= job_tab.isr_mask[0];
	EXTRA_JOBS();
    }
}

void flag_call_out(void) {
    call_out_missing +=
      job_tab.isr_mask[0] | job_tab.isr_mask[1] >> JOB_check_call_out & 1;
    ISR_SET_JOBS(JOB(call_out)+JOB(check_call_out));
    total_alarms++;
}

void check_call_out() {
    CLEAR_JOB(check_call_out);
    TRANSFER_ISR_JOBS;
    if (job_tab.mask & JOB(do_compact_mappings))
	do_compact_mappings();
}

void shutdown_simulation() {
    fatal("shutdown\n");
}