コード例 #1
0
static void _schedulerpolicyhoststeal_findMinTime(Host* host, HostStealSearchState* state) {
    g_rw_lock_reader_lock(&state->data->lock);
    HostStealQueueData* qdata = g_hash_table_lookup(state->data->hostToQueueDataMap, host);
    g_rw_lock_reader_unlock(&state->data->lock);
    utility_assert(qdata);

    g_mutex_lock(&(qdata->lock));
    Event* event = priorityqueue_peek(qdata->pq);
    g_mutex_unlock(&(qdata->lock));

    if(event != NULL) {
        state->nextEventTime = MIN(state->nextEventTime, event_getTime(event));
    }
}
コード例 #2
0
static Event* _schedulerpolicyhoststeal_popFromThread(SchedulerPolicy* policy, HostStealThreadData* tdata, GQueue* assignedHosts, SimulationTime barrier) {
    /* if there is no tdata, that means this thread didn't get any hosts assigned to it */
    if(!tdata) {
        return NULL;
    }

    HostStealPolicyData* data = policy->data;

    while(!g_queue_is_empty(assignedHosts) || tdata->runningHost) {
        /* if there's no running host, we completed the last assignment and need a new one */
        if(!tdata->runningHost) {
            tdata->runningHost = g_queue_pop_head(assignedHosts);
        }
        Host* host = tdata->runningHost;
        g_rw_lock_reader_lock(&data->lock);
        HostStealQueueData* qdata = g_hash_table_lookup(data->hostToQueueDataMap, host);
        g_rw_lock_reader_unlock(&data->lock);
        utility_assert(qdata);

        g_mutex_lock(&(qdata->lock));
        Event* nextEvent = priorityqueue_peek(qdata->pq);
        SimulationTime eventTime = (nextEvent != NULL) ? event_getTime(nextEvent) : SIMTIME_INVALID;

        if(nextEvent != NULL && eventTime < barrier) {
            utility_assert(eventTime >= qdata->lastEventTime);
            qdata->lastEventTime = eventTime;
            nextEvent = priorityqueue_pop(qdata->pq);
            qdata->nPopped++;
            /* migrate iff a migration is needed */
            _schedulerpolicyhoststeal_migrateHost(policy, host, pthread_self());
        } else {
            nextEvent = NULL;
        }

        if(nextEvent == NULL) {
            /* no more events on the runningHost, mark it as NULL so we get a new one */
            g_queue_push_tail(tdata->processedHosts, host);
            tdata->runningHost = NULL;
        }

        g_mutex_unlock(&(qdata->lock));

        if(nextEvent != NULL) {
            return nextEvent;
        }
    }

    /* if we make it here, all hosts for this thread have no more events before barrier */
    return NULL;
}
コード例 #3
0
static void _schedulerpolicyhoststeal_push(SchedulerPolicy* policy, Event* event, Host* srcHost, Host* dstHost, SimulationTime barrier) {
    MAGIC_ASSERT(policy);
    HostStealPolicyData* data = policy->data;

    /* non-local events must be properly delayed so the event wont show up at another host
     * before the next scheduling interval. if the thread scheduler guaranteed to always run
     * the minimum time event accross all of its assigned hosts, then we would only need to
     * do the time adjustment if the srcThread and dstThread are not identical. however,
     * the logic of this policy allows a thread to run all events from a given host before
     * moving on to the next host, so we must adjust the time whenever the srcHost and
     * dstHost are not the same. */
    SimulationTime eventTime = event_getTime(event);

    if(srcHost != dstHost && eventTime < barrier) {
        event_setTime(event, barrier);
        info("Inter-host event time %"G_GUINT64_FORMAT" changed to %"G_GUINT64_FORMAT" "
                "to ensure event causality", eventTime, barrier);
    }

    g_rw_lock_reader_lock(&data->lock);
    /* we want to track how long this thread spends idle waiting to push the event */
    HostStealThreadData* tdata = g_hash_table_lookup(data->threadToThreadDataMap, GUINT_TO_POINTER(pthread_self()));

    /* get the queue for the destination */
    HostStealQueueData* qdata = g_hash_table_lookup(data->hostToQueueDataMap, dstHost);
    g_rw_lock_reader_unlock(&data->lock);
    utility_assert(qdata);

    /* tracking idle time spent waiting for the destination queue lock */
    if(tdata) {
        g_timer_continue(tdata->pushIdleTime);
        g_mutex_lock(&(tdata->lock));
    }
    g_mutex_lock(&(qdata->lock));
    if(tdata) {
        g_timer_stop(tdata->pushIdleTime);
    }

    /* 'deliver' the event to the destination queue */
    priorityqueue_push(qdata->pq, event);
    qdata->nPushed++;

    /* release the destination queue lock */
    g_mutex_unlock(&(qdata->lock));
    if(tdata) {
        g_mutex_unlock(&(tdata->lock));
    }
}
コード例 #4
0
ファイル: shd-scheduler.c プロジェクト: desphunter/shadow
void scheduler_push(Scheduler* scheduler, Event* event, GQuark senderHostID, GQuark receiverHostID) {
    MAGIC_ASSERT(scheduler);

    SimulationTime eventTime = event_getTime(event);
    if(eventTime > scheduler->endTime) {
        event_unref(event);
        return;
    }

    /* parties involved. sender may be NULL, receiver may not!
     * we MAY NOT OWN the receiver, so do not write to it! */
    Host* sender = scheduler_getHost(scheduler, senderHostID);
    Host* receiver = scheduler_getHost(scheduler, receiverHostID);
    utility_assert(receiver);
    utility_assert(receiver == event_getHost(event));

    /* push to a queue based on the policy */
    scheduler->policy->push(scheduler->policy, event, sender, receiver, scheduler->currentRound.endTime);
}