Example #1
0
void worker_scheduleEvent(Event* event, SimulationTime nano_delay, GQuark receiver_node_id) {
    /* TODO create accessors, or better yet refactor the work to event class */
    utility_assert(event);

    /* get our thread-private worker */
    Worker* worker = _worker_getPrivate();

    /* when the event will execute */
    shadowevent_setTime(event, worker->clock_now + nano_delay);

    /* parties involved. sender may be NULL, receiver may not! */
    Host* sender = worker->cached_node;

    /* we MAY NOT OWN the receiver, so do not write to it! */
    Host* receiver = receiver_node_id == 0 ? sender : _slave_getHost(worker->slave, receiver_node_id);
    utility_assert(receiver);

    /* the NodeEvent needs a pointer to the correct node */
    shadowevent_setNode(event, receiver);

    /* if we are not going to execute any more events, free it and return */
    if(slave_isKilled(worker->slave)) {
        shadowevent_free(event);
        return;
    }

    /* engine is not killed, assert accurate worker clock */
    utility_assert(worker->clock_now != SIMTIME_INVALID);

    /* figure out where to push the event */
    if(worker->serialEventQueue) {
        /* single-threaded, push to global serial queue */
        eventqueue_push(worker->serialEventQueue, event);
    } else {
        /* non-local events must be properly delayed so the event wont show up at another worker
         * before the next scheduling interval. this is only a problem if the sender and
         * receivers have been assigned to different workers. */
        if(!host_isEqual(receiver, sender)) {
            SimulationTime jump = slave_getMinTimeJump(worker->slave);
            SimulationTime minTime = worker->clock_now + jump;

            /* warn and adjust time if needed */
            SimulationTime eventTime = shadowevent_getTime(event);
            if(eventTime < minTime) {
                info("Inter-node event time %"G_GUINT64_FORMAT" changed to %"G_GUINT64_FORMAT" due to minimum delay %"G_GUINT64_FORMAT,
                        eventTime, minTime, jump);
                shadowevent_setTime(event, minTime);
            }
        }

        /* multi-threaded, push event to receiver node */
        EventQueue* eventq = host_getEvents(receiver);
        eventqueue_push(eventq, event);
    }
}
Example #2
0
void worker_scheduleEvent(Event* event, SimulationTime nano_delay, GQuark receiver_node_id) {
	/* TODO create accessors, or better yet refactor the work to event class */
	MAGIC_ASSERT(event);
	MAGIC_ASSERT((&(event->super)));

	/* get our thread-private worker */
	Worker* worker = worker_getPrivate();
	Engine* engine = worker->cached_engine;

	/* when the event will execute */
	event->time = worker->clock_now + nano_delay;

	/* parties involved. sender may be NULL, receiver may not! */
	Node* sender = worker->cached_node;

	/* we MAY NOT OWN the receiver, so do not write to it! */
	Node* receiver = receiver_node_id == 0 ? sender : internetwork_getNode(worker_getInternet(), receiver_node_id);
	g_assert(receiver);

	/* the NodeEvent needs a pointer to the correct node */
	event->node = receiver;

	/* if we are not going to execute any more events, free it and return */
	if(engine_isKilled(engine)) {
		shadowevent_free(event);
		return;
	}

	/* engine is not killed, assert accurate worker clock */
	g_assert(worker->clock_now != SIMTIME_INVALID);

	/* non-local events must be properly delayed */
	SimulationTime jump = engine_getMinTimeJump(engine);
	if(!node_isEqual(receiver, sender)) {
		SimulationTime minTime = worker->clock_now + jump;

		/* warn and adjust time if needed */
		if(event->time < minTime) {
			debug("Inter-node event time %lu changed to %lu due to minimum delay %lu",
					event->time, minTime, jump);
			event->time = minTime;
		}
	}

	/* figure out where to push the event */
	if(engine_getNumThreads(engine) > 1) {
		/* multi-threaded, push event to receiver node */
		EventQueue* eventq = node_getEvents(receiver);
		eventqueue_push(eventq, event);
	} else {
		/* single-threaded, push to master queue */
		engine_pushEvent(engine, (Event*)event);
	}
}