Shared Variables: freelist, list-1, list-2: block Thread-1: var b: pointer to type block; while (true) { // wait for >1 block on freelist wait(sem_freelist_minus_1); // wait for element on freelist wait(sem_freelist); // mutual exclusion for freelist wait(mut_freelist); b := unlink(freelist); // mutual exclusion for freelist signal(mut_freelist); produce_information_in_block(b); // mutual exclusion for list1 wait(mut_list1); link(b, list1); // mutual exclusion for list1 signal(mut_list1); // signal new element on list1 signal(sem_list1); } Thread-2: var x, y: pointer to type block; while (true) { // wait for element on list1 wait(sem_list1); // mutual exclusion for list1 wait(mut_list1); x := unlink(list-1); // mutual exclusion for list1 signal(mut_list1); // wait for element on freelist wait(sem_freelist); // mutual exclusion for freelist wait(mut_freelist); y := unlink(freelist); // mutual exclusion for freelist signal(mut_freelist); use_block_x_to_produce_info_in_y(x, y); // mutual exclusion for freelist wait(mut_freelist); //* link(x, freelist); link(x, freelist); // mutual exclusion for freelist signal(mut_freelist); // signal new element on freelist signal(sem_freelist); // mutual exclusion for list2 wait(mut_list2); link(y, list-2); // mutual exclusion for list2 signal(mut_list2); // signal new element on list2 signal(sem_list2); } Thread-3: var c: pointer to type block; while (true) { // wait for element on list2 wait(sem_list2); // mutual exclusion for list2 wait(mut_list2); c := unlink(list-2); // mutual exclusion for list2 signal(mut_list2); consume_information_in_block(c); // mutual exclusion for freelist wait(mut_freelist); link(c, freelist); // mutual exclusion for freelist signal(mut_freelist); // signal Thread-1 to continue signal(sem_freelist_minus_1); // signal new element on freelist signal(sem_freelist); }