Shared Variables: freelist, list-1, list-2: block Semaphores: sem_freelist = N, mut_freelist = 1, sem_freelist_minus_1 = N-1, sem_list1 = 0, mut_list1 = 1, sem_list2 = 0, mut_list2 = 1; Thread-1: var b: pointer to type block; while (1) { // 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 (1) { // 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 (1) { // 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); }