3

I'm trying to trace the flow of a piece of code just to understand the points where the tasks go into D/S/R states (uninterruptible/interruptible/running). I do understand the meaning of each state, however doing an exercise shows confusing results and I wasn't able till now to figure out why.

The piece of code I'm running:

void foo() { pthread_setname_np(pthread_self(), "lock_func/1"); while(quit == false) { for(int64_t idx=0; idx<10000000;idx++) (void)idx; flag = true; cv1.notify_all(); } } void bar() { pthread_setname_np(pthread_self(), "lock_func/2"); std::mutex mutex1; std::unique_lock<std::mutex> lock(mutex1); while(!flag) cv1.wait(lock); flag = false; } int main(int argc, char *argv[]) { ... std::thread t1 = std::thread(foo); std::thread t2 = std::thread(bar); ... if (mlockall( MCL_CURRENT | MCL_FUTURE ) < 0) { perror("mlockall") } .... } 

I purposely don't use the mutex when setting the flag as I don't want the foo thread to block. So I don't care if bar misses some wakeups, it will be anyway woken up from time to time due to the loop in foo. The goal here is just to see the states of foo & bar task, now more focusing on bar. If I trace the sched_switch event in the ftrace, I do get the following:

 <idle>-0 [007] d... 335998: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120 lock_func/1-30296 [007] d... 335999: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120 <idle>-0 [007] d... 336000: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120 lock_func/1-30296 [007] d... 336001: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120 <idle>-0 [007] d... 336002: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120 lock_func/1-30296 [007] d... 336003: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120 <idle>-0 [007] d... 336004: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120 lock_func/1-30296 [007] d... 336005: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120 <idle>-0 [007] d... 336006: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120 lock_func/1-30296 [007] d... 336007: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120 <idle>-0 [007] d... 336008: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120 lock_func/1-30296 [007] d... 336009: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120 <idle>-0 [000] d... 336010: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120 lock_func/1-30296 [000] d... 336011: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 <idle>-0 [000] d... 336012: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120 

Observe how prev_state for my lock_func1 (bar) is always D (uninterruptible). Looking at the code a context switch can happen only on the condition variable sleep, or when time slice is finished (running in CFS scheduler)

cat /proc/30295/task/30296/wchan futex_wait_queue_me 

which according to the docs is a interruptible function. Checking multiple times the task state in proc shows always S:

cat /proc/30295/task/30296/stat 30295 (lock_func/1) S ... 

So the stat shows S-interruptible state, the futex_wait_queue_me is interruptible, however, the ftrace show always at the context switch time prev_state=D. Running this code and recording several seconds with ftrace shows only prev_state=D for my lock_func/1 (bar). I never get the S-interruptible.

Can someone explain why? Is the scheduler doing some state change in between?

Thanks.

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.