remzi-arpacidusseau / ostep-homework

2.1k stars 999 forks source link

Condition Variables #11

Open laushkeen opened 4 years ago

laushkeen commented 4 years ago

I attempted to do homework, task 4 from the chapter "Condition Variables":

Let’s look at some timings. How long do you think the following execution, with one producer, three consumers, a single-entry shared buffer, and each consumer pausing at point c3 for a second, will take? ./main-two-cvs-while -p 1 -c 3 -m 1 -C 0,0,0,1,0,0,0:0,0,0,1,0,0,0:0,0,0,1,0,0,0 -l 10 -v -t

When I launch main-one-cv-while.c using this code, the program seems to fall into the deadlock:

NF P0 C0 C1 C2 0 [--- ] p0 0 [--- ] p1 1 [ 0 ] p4 1 [ 0 ] p5 1 [ 0 ] p6 1 [ 0 ] p0 1 [ 0 ] p1 1 [ 0 ] p2 1 [ 0 ] c0 1 [ 0 ] c1 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c0 0 [--- ] c0 0 [--- ] p3 1 [ 1 ] p4 1 [ 1 ] p5 1 [ 1 ] c0 1 [ 1 ] p6 1 [ 1 ] p0 1 [ 1 ] c1 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c0 0 [--- ] c1 0 [--- ] c2 0 [--- ] c1 0 [--- ] c2 0 [--- ] p1 1 [ 2 ] p4 1 [ 2 ] p5 1 [ 2 ] p6 1 [ 2 ] p0 1 [ 2 ] c1 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c3 0 [--- ] c2 0 [--- ] c0 0 [--- ] p1 1 [ 3 ] p4 1 [ 3 ] p5 1 [ 3 ] p6 1 [ 3 ] p0 1 [ 3 ] c3 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c0 0 [--- ] c1 0 [--- ] c2 0 [--- ] c3 0 [--- ] c2 0 [--- ] p1 1 [ 4 ] p4 1 [ 4 ] p5 1 [ 4 ] p6 1 [ 4 ] p0 1 [ 4 ] c1 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c0 0 [--- ] c3 0 [--- ] c2 0 [--- ] p1 1 [ 5 ] p4 1 [ 5 ] p5 1 [ 5 ] p6 1 [ 5 ] p0 1 [ 5 ] c3 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c0 0 [--- ] c1 0 [--- ] c2 0 [--- ] c3 0 [--- ] c2 0 [--- ] p1 1 [ 6 ] p4 1 [ 6 ] p5 1 [ 6 ] p6 1 [ 6 ] p0 1 [ 6 ] c1 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c0 0 [--- ] c3 0 [--- ] c2 0 [--- ] p1 1 [ 7 ] p4 1 [ 7 ] p5 1 [ 7 ] p6 1 [ 7 ] p0 1 [ 7 ] c3 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c0 0 [--- ] c1 0 [--- ] c2 0 [--- ] c3 0 [--- ] c2 0 [--- ] p1 1 [ 8 ] p4 1 [ 8 ] p5 1 [ 8 ] p6 1 [ 8 ] p0 1 [ 8 ] c1 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c0 0 [--- ] c3 0 [--- ] c2 0 [--- ] p1 1 [ 9 ] p4 1 [ 9 ] p5 1 [ 9 ] p6 1 [ 9 ] c3 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c0 0 [--- ] c1 0 [--- ] c2 0 [--- ] c3 0 [--- ] c2 1 [EOS ] [main: added end-of-stream marker] 1 [EOS ] c1 0 [--- ] c4 0 [--- ] c5 0 [--- ] c6 0 [--- ] c3 0 [--- ] c2 0 [--- ] c3 0 [--- ] c2

It stucks on the last operation and doesn't finish.

remzi-arpacidusseau commented 4 years ago

I can't reproduce this. Could you share more details? e.g., cut+paste how you compiled it, info about your platform, etc.

laushkeen commented 4 years ago

I'm compiling it on Windows 10 using MinGW 64 because it supports ptreads on Windows. Just use this command:

C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin>gcc "E:\HW-Threads-RealCV\main-one-cv-while.c" -o main-one-cv-while

Also, I had to change int to long long in the function

void producer(void arg) { int id = (long long) arg; // make sure each producer produces unique values int base = id * loops; int i; for (i = 0; i < loops; i++) { p0; Mutex_lock(&m); p1; while (num_full == max) { p2; Cond_wait(&cv, &m); p3; } do_fill(base + i); p4; Cond_signal(&cv); p5; Mutex_unlock(&m); p6; } return NULL; }

void consumer(void arg) { int id = (long long) arg; int tmp = 0; int consumed_count = 0; while (tmp != END_OF_STREAM) { c0; Mutex_lock(&m); c1; while (num_full == 0) { c2; Cond_wait(&cv, &m); c3; } tmp = do_get(); c4; Cond_signal(&cv); c5; Mutex_unlock(&m); c6; consumed_count++; }

// return consumer_count-1 because END_OF_STREAM does not count
return (void *) (long long) (consumed_count - 1);

}

remzi-arpacidusseau commented 4 years ago

I compile with -pthread -- is that not needed on Windows? All of that said, not sure there is any guarantees on a Windows build -- you're on your own there.

Remzi

On Tue, Aug 18, 2020 at 2:56 PM laushkeen notifications@github.com wrote:

I'm compiling it on Windows 10 using MinGW 64 because it supports ptreads on Windows. Just use this command:

C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin>gcc "E:\HW-Threads-RealCV\main-one-cv-while.c" -o main-one-cv-while

Also, I had to change int to long long in the function

void producer(void arg) { int id = (long long) arg; // make sure each producer produces unique values int base = id * loops; int i; for (i = 0; i < loops; i++) { p0; Mutex_lock(&m); p1; while (num_full == max) { p2; Cond_wait(&cv, &m); p3; } do_fill(base + i); p4; Cond_signal(&cv); p5; Mutex_unlock(&m); p6; } return NULL; }

void consumer(void arg) { int id = (long long) arg; int tmp = 0; int consumed_count = 0; while (tmp != END_OF_STREAM) { c0; Mutex_lock(&m); c1; while (num_full == 0) { c2; Cond_wait(&cv, &m); c3; } tmp = do_get(); c4; Cond_signal(&cv); c5; Mutex_unlock(&m); c6; consumed_count++; }

// return consumer_count-1 because END_OF_STREAM does not count return (void *) (long long) (consumed_count - 1);

}

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/remzi-arpacidusseau/ostep-homework/issues/11#issuecomment-675655014, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADDKP5Z6RDNG3Y4YTMS5WQLSBLFG3ANCNFSM4QCGBVXQ .