Permalink
Browse files

scheduler: First cut at blocked threads.

They still occupy their run queues, but get shuffled if they
get to the front and haven't been unblocked yet.

Used by proper timing-side pthread_join for now. We'll move over
all the blocking syscalls to a similar model, as opposed to the current
one, where we just reshuffle the run queues on a blocking call and hope
for the best.

TESTED=manual, probably not enough

Change-Id: Ib847e8cf7990d20d0b2494002c33fc40bff695e5
  • Loading branch information...
s-kanev committed Apr 25, 2016
1 parent 50d2ad9 commit f8422d1ce0ddd727467f0b504b64548e1e6bf3b6
@@ -142,6 +142,7 @@ toolchain {
compiler_flag: "-DROI_DEBUG"
compiler_flag: "-DSPECULATION_DEBUG"
compiler_flag: "-DPROFILING_DEBUG"
+ compiler_flag: "-DPTHREADS_DEBUG"
}
compilation_mode_flags {
@@ -314,6 +315,7 @@ toolchain {
compiler_flag: "-DROI_DEBUG"
compiler_flag: "-DSPECULATION_DEBUG"
compiler_flag: "-DPROFILING_DEBUG"
+ compiler_flag: "-DPTHREADS_DEBUG"
}
compilation_mode_flags {
View
@@ -206,6 +206,10 @@ VOID AddGiveUpHandshake(THREADID tid, bool start_ignoring, bool reschedule);
* de-scheduled. It should be rescheduled with ScheduleThread(). */
VOID SyncWithTimingSim(THREADID tid);
+/* Similar to AddGiveUpHandshake(). Except, once consumed, the thread will
+ * wait to join @blocked_on. */
+void AddBlockedHandshake(THREADID tid, pid_t blocked_on);
+
/* Tell the scheduler to schedule a thread. */
VOID ScheduleThread(THREADID tid);
@@ -236,6 +236,23 @@ void AddGiveUpHandshake(THREADID tid, bool start_ignoring, bool reschedule) {
xiosim::buffer_management::FlushBuffers(tstate->tid);
}
+/* ========================================================================== */
+void AddBlockedHandshake(THREADID tid, pid_t blocked_on) {
+ if (ExecMode != EXECUTION_MODE_SIMULATE)
+ return;
+
+ thread_state_t* tstate = get_tls(tid);
+ handshake_container_t* handshake = xiosim::buffer_management::GetBuffer(tstate->tid);
+ handshake->flags.valid = true;
+ handshake->flags.real = false;
+ handshake->flags.blockThread = true;
+ /* We'll abuse mem_buffer to store the pid to block on for now. */
+ handshake->mem_buffer.push_back(std::make_pair(blocked_on, 0));
+ xiosim::buffer_management::ProducerDone(tstate->tid);
+
+ xiosim::buffer_management::FlushBuffers(tstate->tid);
+}
+
/* ========================================================================== */
VOID ScheduleThread(THREADID tid) {
if (ExecMode != EXECUTION_MODE_SIMULATE)
@@ -1001,16 +1018,6 @@ VOID ThreadFini(THREADID tid, const CONTEXT* ctxt, INT32 code, VOID* v) {
cerr << "[" << tstate->tid << "] Thread exit. ID: " << tid << endl;
lk_unlock(printing_lock);
- BOOL was_scheduled = tstate->num_inst > 0;
-
- /* Ignore threads which we weren't going to simulate.
- It's ok that we're not locking tstate here, because no one is using it */
- if (!was_scheduled) {
- delete tstate;
- PIN_DeleteThreadDataKey(tid);
- return;
- }
-
/* There will be no further instructions instrumented (on this thread).
* Mark it as finishing and let the handshake buffer drain.
* Once this last handshake gets executed by a core, it will make
@@ -17,6 +17,7 @@ struct handshake_flags_t {
bool giveCoreUp : 1; /* Notify the scheduler to release thread */
bool giveUpReschedule : 1; /* When ^ is true, should thread get re-scheduled */
bool killThread : 1; /* Thread is exiting, deschedule it and clean up once consumed */
+ bool blockThread : 1;
bool brtaken : 1; /* Taken or Not-Taken for branch instructions */
bool flush_pipe : 1; /* Flush core pipelie */
bool real : 1; /* Is this a real instruction */
Oops, something went wrong.

0 comments on commit f8422d1

Please sign in to comment.