Think Stitch
  最近の更新


生産者・消費者問題 4

今回も Pthread Model Checker を使って生産者・消費者問題を調べます.

前回に引き続き,条件変数を1個にまとめたモデルを使います.バッファ長 2,生産者,消費者ともに2個にするとデッドロックはありません.

0  バッファがフルだったときだけ signal を発行する

生産者も消費者も,データを入れたり出したりしたときは無条件に signal を発行していますよね.

void *consumer(void *arg)
{
    while (true) {
        pthread_mutex_lock(&mutex);
        while (count == 0) {
            pthread_cond_wait(&cv, &mutex);
        }
        count--;
        pthread_cond_signal(&cv);               // *A
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

でも,たとえば消費者の立場で考えると,生産者が寝ている可能性があるのはバッファがフルだったときです(ちょっと曖昧にいってます).だったらそのときだけ signal を出せばいいんじゃないのか?というのが今回の問題です.

void *consumer(void *arg)
{
    while (true) {
        pthread_mutex_lock(&mutex);
        while (count == 0) {
            pthread_cond_wait(&cv, &mutex);
        }
        count--;
        if (count == N - 1) {                   // *B
            pthread_cond_signal(&cv);
        }
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

検査をしてみるとデッドロックが見つかります.レポート全体は後ろにまわして,サマリーを見ます.

#5 pthp[0] lock mutex
#8 pthp[0] load count
#9 pthp[0] store count
    count = 1
#10 pthp[0] signal cv
#11 pthp[0] unlock mutex

#12 pthp[0] lock mutex
#18 pthp[0] load count
#20 pthp[0] store count
    count = 2
#22 pthp[0] signal cv
#24 pthp[0] unlock mutex

#26 pthp[0] lock mutex
#28 pthp[0] load count
#32 pthp[0] wait cv mutex

#34 pthp[1] lock mutex
#36 pthp[1] load count
#39 pthp[1] wait cv mutex

#40 pthc[1] lock mutex
#43 pthc[1] load count
#44 pthc[1] store count
    count = 1
    2 pthp[1] 36 wait cv
#47 pthc[1] signal cv           #
    2 pthp[1] 36
#48 pthc[1] unlock mutex

#49 pthc[1] lock mutex
#52 pthc[1] load count
#53 pthc[1] store count         # no signal
    count = 0
#56 pthc[1] unlock mutex

#57 pthc[1] lock mutex
#58 pthc[1] load count
#60 pthc[1] wait cv mutex

#62 pthc[0] lock mutex
#63 pthc[0] load count
#65 pthc[0] wait cv mutex

#66 pthp[1] lock mutex
#69 pthp[1] load count
#70 pthp[1] store count
    count = 1
    3 pthc[0] 24 wait cv
#71 pthp[1] signal cv
    3 pthc[0] 24
#72 pthp[1] unlock mutex

#73 pthp[1] lock mutex
#76 pthp[1] load count
#77 pthp[1] store count
    count = 2
    1 pthp[0] 36 wait cv
#78 pthp[1] signal cv
    1 pthp[0] 36
#79 pthp[1] unlock mutex

#80 pthp[1] lock mutex
#81 pthp[1] load count
#83 pthp[1] wait cv mutex

#84 pthp[0] lock mutex
#85 pthp[0] load count
#87 pthp[0] wait cv mutex

#88 pthc[0] lock mutex
#91 pthc[0] load count
#92 pthc[0] store count
    count = 1
    1 pthp[0] 36 wait cv
    2 pthp[1] 36 wait cv
    3 pthc[0] 28
    4 pthc[1] 24 wait cv
#95 pthc[0] signal cv           # A
    1 pthp[0] 36 wait cv
    2 pthp[1] 36 wait cv
    3 pthc[0] 28
    4 pthc[1] 24
#96 pthc[0] unlock mutex

#97 pthc[0] lock mutex
#100 pthc[0] load count
#101 pthc[0] store count        # B: no signal
    count = 0
#104 pthc[0] unlock mutex

#105 pthc[1] lock mutex
#106 pthc[1] load count
#110 pthc[1] wait cv mutex

#111 pthc[0] lock mutex
#112 pthc[0] load count
#116 pthc[0] wait cv mutex

バッファフルではないので消費者が signal を出していないところが2か所あります.問題は最後のところで,A ではバッファがフルだったので signal を出しているのですが,これがもう1つの消費者を起こしてしまいます.データはもう1つあるのですけど,こちらでは signal が出ないので,結果生産者が起きる機会が失われてしまいました.

実際に実行してみると,すぐにデッドロックします.

2017/10/10

1  レポート

------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 1
------------------------
#1 main tau
59: for (i = 0; i < NP; ++i) {
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 2
    i = 0
------------------------
#2 main tau
59: for (i = 0; i < NP; ++i) {
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 3
    i = 0
------------------------
#3 main create pthp[0]
60: pthread_create(&pthp[i], NULL, &producer, (void *)(intptr_t)i);
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 5
    i = 0
1 pthp[0] 30
    arg = 0
------------------------
#4 pthp[0] tau
20: while (true) {
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 5
    i = 0
1 pthp[0] 31
------------------------
#5 pthp[0] lock mutex
21: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex pthp[0]
thread:
0 main 5
    i = 0
1 pthp[0] 32
------------------------
#6 pthp[0] load count
22: while (count == N) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthp[0]
thread:
0 main 5
    i = 0
1 pthp[0] 33
    t17 = 0
------------------------
#7 pthp[0] tau
22: while (count == N) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthp[0]
thread:
0 main 5
    i = 0
1 pthp[0] 35
------------------------
#8 pthp[0] load count
27: count++;
------------------------
global vars:
    count = 0
mutex:
    mutex pthp[0]
thread:
0 main 5
    i = 0
1 pthp[0] 37
    t18 = 0
------------------------
#9 pthp[0] store count
27: count++;
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[0]
thread:
0 main 5
    i = 0
1 pthp[0] 38
------------------------
#10 pthp[0] signal cv
29: pthread_cond_signal(&cv);
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[0]
thread:
0 main 5
    i = 0
1 pthp[0] 39
------------------------
#11 pthp[0] unlock mutex
30: pthread_mutex_unlock(&mutex);
------------------------
global vars:
    count = 1
mutex:
    mutex <unlocked>
thread:
0 main 5
    i = 0
1 pthp[0] 31
------------------------
#12 pthp[0] lock mutex
21: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[0]
thread:
0 main 5
    i = 0
1 pthp[0] 32
------------------------
#13 pthp[0] load count
22: while (count == N) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[0]
thread:
0 main 5
    i = 0
1 pthp[0] 33
    t17 = 1
------------------------
#14 main tau
59: for (i = 0; i < NP; ++i) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[0]
thread:
0 main 2
    i = 1
1 pthp[0] 33
    t17 = 1
------------------------
#15 main tau
59: for (i = 0; i < NP; ++i) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[0]
thread:
0 main 3
    i = 1
1 pthp[0] 33
    t17 = 1
------------------------
#16 pthp[0] tau
22: while (count == N) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[0]
thread:
0 main 3
    i = 1
1 pthp[0] 35
------------------------
#17 main create pthp[1]
60: pthread_create(&pthp[i], NULL, &producer, (void *)(intptr_t)i);
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[0]
thread:
0 main 5
    i = 1
1 pthp[0] 35
2 pthp[1] 30
    arg = 1
------------------------
#18 pthp[0] load count
27: count++;
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[0]
thread:
0 main 5
    i = 1
1 pthp[0] 37
    t18 = 1
2 pthp[1] 30
    arg = 1
------------------------
#19 main tau
59: for (i = 0; i < NP; ++i) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[0]
thread:
0 main 2
    i = 2
1 pthp[0] 37
    t18 = 1
2 pthp[1] 30
    arg = 1
------------------------
#20 pthp[0] store count
27: count++;
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 2
    i = 2
1 pthp[0] 38
2 pthp[1] 30
    arg = 1
------------------------
#21 main tau
59: for (i = 0; i < NP; ++i) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 4
1 pthp[0] 38
2 pthp[1] 30
    arg = 1
------------------------
#22 pthp[0] signal cv
29: pthread_cond_signal(&cv);
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 4
1 pthp[0] 39
2 pthp[1] 30
    arg = 1
------------------------
#23 main tau
63: for (i = 0; i < NC; ++i) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 6
    i = 0
1 pthp[0] 39
2 pthp[1] 30
    arg = 1
------------------------
#24 pthp[0] unlock mutex
30: pthread_mutex_unlock(&mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex <unlocked>
thread:
0 main 6
    i = 0
1 pthp[0] 31
2 pthp[1] 30
    arg = 1
------------------------
#25 main tau
63: for (i = 0; i < NC; ++i) {
------------------------
global vars:
    count = 2
mutex:
    mutex <unlocked>
thread:
0 main 7
    i = 0
1 pthp[0] 31
2 pthp[1] 30
    arg = 1
------------------------
#26 pthp[0] lock mutex
21: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 7
    i = 0
1 pthp[0] 32
2 pthp[1] 30
    arg = 1
------------------------
#27 main create pthc[0]
64: pthread_create(&pthc[i], NULL, &consumer, (void *)(intptr_t)i);
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 9
    i = 0
1 pthp[0] 32
2 pthp[1] 30
    arg = 1
3 pthc[0] 18
    arg = 0
------------------------
#28 pthp[0] load count
22: while (count == N) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 9
    i = 0
1 pthp[0] 33
    t17 = 2
2 pthp[1] 30
    arg = 1
3 pthc[0] 18
    arg = 0
------------------------
#29 main tau
63: for (i = 0; i < NC; ++i) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 6
    i = 1
1 pthp[0] 33
    t17 = 2
2 pthp[1] 30
    arg = 1
3 pthc[0] 18
    arg = 0
------------------------
#30 pthp[0] tau
22: while (count == N) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 6
    i = 1
1 pthp[0] 34
2 pthp[1] 30
    arg = 1
3 pthc[0] 18
    arg = 0
------------------------
#31 main tau
63: for (i = 0; i < NC; ++i) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 7
    i = 1
1 pthp[0] 34
2 pthp[1] 30
    arg = 1
3 pthc[0] 18
    arg = 0
------------------------
#32 pthp[0] wait cv mutex
24: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex <unlocked>
thread:
0 main 7
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 30
    arg = 1
3 pthc[0] 18
    arg = 0
------------------------
#33 pthp[1] tau
20: while (true) {
------------------------
global vars:
    count = 2
mutex:
    mutex <unlocked>
thread:
0 main 7
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 31
3 pthc[0] 18
    arg = 0
------------------------
#34 pthp[1] lock mutex
21: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[1]
thread:
0 main 7
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 32
3 pthc[0] 18
    arg = 0
------------------------
#35 main create pthc[1]
64: pthread_create(&pthc[i], NULL, &consumer, (void *)(intptr_t)i);
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 32
3 pthc[0] 18
    arg = 0
4 pthc[1] 18
    arg = 1
------------------------
#36 pthp[1] load count
22: while (count == N) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 33
    t17 = 2
3 pthc[0] 18
    arg = 0
4 pthc[1] 18
    arg = 1
------------------------
#37 pthc[1] tau
38: while (true) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 33
    t17 = 2
3 pthc[0] 18
    arg = 0
4 pthc[1] 19
------------------------
#38 pthp[1] tau
22: while (count == N) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 34
3 pthc[0] 18
    arg = 0
4 pthc[1] 19
------------------------
#39 pthp[1] wait cv mutex
24: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 18
    arg = 0
4 pthc[1] 19
------------------------
#40 pthc[1] lock mutex
39: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 18
    arg = 0
4 pthc[1] 20
------------------------
#41 pthc[1] load count
40: while (count == 0) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 18
    arg = 0
4 pthc[1] 21
    t14 = 2
------------------------
#42 pthc[1] tau
40: while (count == 0) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 18
    arg = 0
4 pthc[1] 23
------------------------
#43 pthc[1] load count
45: count--;
------------------------
global vars:
    count = 2
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 18
    arg = 0
4 pthc[1] 25
    t15 = 2
------------------------
#44 pthc[1] store count
45: count--;
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 18
    arg = 0
4 pthc[1] 26
------------------------
#45 pthc[1] load count
47: if (count == N - 1) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 18
    arg = 0
4 pthc[1] 27
    t16 = 1
------------------------
#46 pthc[1] tau
47: if (count == N - 1) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 18
    arg = 0
4 pthc[1] 28
------------------------
#47 pthc[1] signal cv
48: pthread_cond_signal(&cv);
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 29
------------------------
#48 pthc[1] unlock mutex
50: pthread_mutex_unlock(&mutex);
------------------------
global vars:
    count = 1
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 19
------------------------
#49 pthc[1] lock mutex
39: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 20
------------------------
#50 pthc[1] load count
40: while (count == 0) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 21
    t14 = 1
------------------------
#51 pthc[1] tau
40: while (count == 0) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 23
------------------------
#52 pthc[1] load count
45: count--;
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 25
    t15 = 1
------------------------
#53 pthc[1] store count
45: count--;
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 26
------------------------
#54 pthc[1] load count
47: if (count == N - 1) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 27
    t16 = 0
------------------------
#55 pthc[1] tau
47: if (count == N - 1) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 29
------------------------
#56 pthc[1] unlock mutex
50: pthread_mutex_unlock(&mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 19
------------------------
#57 pthc[1] lock mutex
39: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 20
------------------------
#58 pthc[1] load count
40: while (count == 0) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 21
    t14 = 0
------------------------
#59 pthc[1] tau
40: while (count == 0) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 22
------------------------
#60 pthc[1] wait cv mutex
42: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 18
    arg = 0
4 pthc[1] 24 wait cv
------------------------
#61 pthc[0] tau
38: while (true) {
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 19
4 pthc[1] 24 wait cv
------------------------
#62 pthc[0] lock mutex
39: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 20
4 pthc[1] 24 wait cv
------------------------
#63 pthc[0] load count
40: while (count == 0) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 21
    t14 = 0
4 pthc[1] 24 wait cv
------------------------
#64 pthc[0] tau
40: while (count == 0) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 22
4 pthc[1] 24 wait cv
------------------------
#65 pthc[0] wait cv mutex
42: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36
3 pthc[0] 24 wait cv
4 pthc[1] 24 wait cv
------------------------
#66 pthp[1] lock mutex
24: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 32
3 pthc[0] 24 wait cv
4 pthc[1] 24 wait cv
------------------------
#67 pthp[1] load count
22: while (count == N) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 33
    t17 = 0
3 pthc[0] 24 wait cv
4 pthc[1] 24 wait cv
------------------------
#68 pthp[1] tau
22: while (count == N) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 35
3 pthc[0] 24 wait cv
4 pthc[1] 24 wait cv
------------------------
#69 pthp[1] load count
27: count++;
------------------------
global vars:
    count = 0
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 37
    t18 = 0
3 pthc[0] 24 wait cv
4 pthc[1] 24 wait cv
------------------------
#70 pthp[1] store count
27: count++;
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 38
3 pthc[0] 24 wait cv
4 pthc[1] 24 wait cv
------------------------
#71 pthp[1] signal cv
29: pthread_cond_signal(&cv);
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 39
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#72 pthp[1] unlock mutex
30: pthread_mutex_unlock(&mutex);
------------------------
global vars:
    count = 1
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 31
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#73 pthp[1] lock mutex
21: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 32
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#74 pthp[1] load count
22: while (count == N) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 33
    t17 = 1
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#75 pthp[1] tau
22: while (count == N) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 35
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#76 pthp[1] load count
27: count++;
------------------------
global vars:
    count = 1
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 37
    t18 = 1
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#77 pthp[1] store count
27: count++;
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 38
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#78 pthp[1] signal cv
29: pthread_cond_signal(&cv);
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36
2 pthp[1] 39
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#79 pthp[1] unlock mutex
30: pthread_mutex_unlock(&mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36
2 pthp[1] 31
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#80 pthp[1] lock mutex
21: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36
2 pthp[1] 32
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#81 pthp[1] load count
22: while (count == N) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36
2 pthp[1] 33
    t17 = 2
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#82 pthp[1] tau
22: while (count == N) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36
2 pthp[1] 34
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#83 pthp[1] wait cv mutex
24: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36
2 pthp[1] 36 wait cv
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#84 pthp[0] lock mutex
24: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 9
    i = 1
1 pthp[0] 32
2 pthp[1] 36 wait cv
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#85 pthp[0] load count
22: while (count == N) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 9
    i = 1
1 pthp[0] 33
    t17 = 2
2 pthp[1] 36 wait cv
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#86 pthp[0] tau
22: while (count == N) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthp[0]
thread:
0 main 9
    i = 1
1 pthp[0] 34
2 pthp[1] 36 wait cv
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#87 pthp[0] wait cv mutex
24: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 24
4 pthc[1] 24 wait cv
------------------------
#88 pthc[0] lock mutex
42: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 2
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 20
4 pthc[1] 24 wait cv
------------------------
#89 pthc[0] load count
40: while (count == 0) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 21
    t14 = 2
4 pthc[1] 24 wait cv
------------------------
#90 pthc[0] tau
40: while (count == 0) {
------------------------
global vars:
    count = 2
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 23
4 pthc[1] 24 wait cv
------------------------
#91 pthc[0] load count
45: count--;
------------------------
global vars:
    count = 2
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 25
    t15 = 2
4 pthc[1] 24 wait cv
------------------------
#92 pthc[0] store count
45: count--;
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 26
4 pthc[1] 24 wait cv
------------------------
#93 pthc[0] load count
47: if (count == N - 1) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 27
    t16 = 1
4 pthc[1] 24 wait cv
------------------------
#94 pthc[0] tau
47: if (count == N - 1) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 28
4 pthc[1] 24 wait cv
------------------------
#95 pthc[0] signal cv
48: pthread_cond_signal(&cv);
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 29
4 pthc[1] 24
------------------------
#96 pthc[0] unlock mutex
50: pthread_mutex_unlock(&mutex);
------------------------
global vars:
    count = 1
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 19
4 pthc[1] 24
------------------------
#97 pthc[0] lock mutex
39: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 20
4 pthc[1] 24
------------------------
#98 pthc[0] load count
40: while (count == 0) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 21
    t14 = 1
4 pthc[1] 24
------------------------
#99 pthc[0] tau
40: while (count == 0) {
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 23
4 pthc[1] 24
------------------------
#100 pthc[0] load count
45: count--;
------------------------
global vars:
    count = 1
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 25
    t15 = 1
4 pthc[1] 24
------------------------
#101 pthc[0] store count
45: count--;
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 26
4 pthc[1] 24
------------------------
#102 pthc[0] load count
47: if (count == N - 1) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 27
    t16 = 0
4 pthc[1] 24
------------------------
#103 pthc[0] tau
47: if (count == N - 1) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 29
4 pthc[1] 24
------------------------
#104 pthc[0] unlock mutex
50: pthread_mutex_unlock(&mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 19
4 pthc[1] 24
------------------------
#105 pthc[1] lock mutex
42: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 19
4 pthc[1] 20
------------------------
#106 pthc[1] load count
40: while (count == 0) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 19
4 pthc[1] 21
    t14 = 0
------------------------
#107 pthc[1] tau
40: while (count == 0) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 9
    i = 1
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 19
4 pthc[1] 22
------------------------
#108 main tau
63: for (i = 0; i < NC; ++i) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 6
    i = 2
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 19
4 pthc[1] 22
------------------------
#109 main tau
63: for (i = 0; i < NC; ++i) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[1]
thread:
0 main 8
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 19
4 pthc[1] 22
------------------------
#110 pthc[1] wait cv mutex
42: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 8
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 19
4 pthc[1] 24 wait cv
------------------------
#111 pthc[0] lock mutex
39: pthread_mutex_lock(&mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 8
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 20
4 pthc[1] 24 wait cv
------------------------
#112 pthc[0] load count
40: while (count == 0) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 8
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 21
    t14 = 0
4 pthc[1] 24 wait cv
------------------------
#113 main tau
67: for (i = 0; i < NP; ++i) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 10
    i = 0
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 21
    t14 = 0
4 pthc[1] 24 wait cv
------------------------
#114 pthc[0] tau
40: while (count == 0) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 10
    i = 0
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 22
4 pthc[1] 24 wait cv
------------------------
#115 main tau
67: for (i = 0; i < NP; ++i) {
------------------------
global vars:
    count = 0
mutex:
    mutex pthc[0]
thread:
0 main 11
    i = 0
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 22
4 pthc[1] 24 wait cv
------------------------
#116 pthc[0] wait cv mutex
42: pthread_cond_wait(&cv, &mutex);
------------------------
global vars:
    count = 0
mutex:
    mutex <unlocked>
thread:
0 main 11
    i = 0
1 pthp[0] 36 wait cv
2 pthp[1] 36 wait cv
3 pthc[0] 24 wait cv
4 pthc[1] 24 wait cv
------------------------
© 2013-2017 PRINCIPIA Limited