Q1: word, block Q2: The pthread primes example, pthread_mutex_lock(&nextbaselock); // old line 47 base = nextbase; nextbase += 2; pthread_mutex_unlock(&nextbaselock); We could use LOCK ADD to do the incrementing by 2 atomically, but we also need to record the orginal value, storing it in 'base', still atomically. Q3: guided Q4: Code enclosed below. Note that a key line is *whrmx = *whrmx * chunk; The reason is that 'max' returns the index of the max value WITHIN THE ARRAY IT IS GIVEN. When we call it on just a chunk of the original array, we need to convert it to an index in the original array. #include #include #include void max(int *x, int nx, int *mx, int *whrmx) { *mx = x[0]; *whrmx = 0; for (int i = 1; i < nx; i++) if (x[i] > *mx) { *mx = x[i]; *whrmx = i; } } // inputs are the array x and its length, nx; outputs are the maximum // value *mx and the index at which it occurs, whrmx void wheremax(int *x, int nx, int *mx, int *whrmx) { int nth, chunk; // the max values found in each chunk, and their indices within chunks int *maxvals, *maxivals; #pragma omp parallel { nth = omp_get_num_threads(); #pragma omp single { maxvals = malloc(nth*sizeof(int)); maxivals = malloc(nth*sizeof(int)); chunk = nx / nth; } int me = omp_get_thread_num(); // where my chunk starts int firsti = me * chunk; max(x+firsti,chunk,&maxvals[me],&maxivals[me]); } // combine the chunk info to get the overall answers int whichchunk; max(maxvals,nth, mx, &whichchunk ); *whrmx = whichchunk * chunk + maxivals[whichchunk]; } int main() { int z[8] = {5,12,13,6,2,22,15,3}; int m,wherem; omp_set_num_threads(4); wheremax(z,8,&m,&wherem); // should print out 22 and 5 printf("the max value was %d\n",m); printf("it occurred at index %d\n",wherem); }