Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added initial a, b values, and commenting results

...

Code Block
bgColor#ffcccc
volatile int a, b;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t mut_sig = PTHREAD_COND_INITIALIZER;

void main(void) {
  int j;
  a = 5;
  b = 10;

  pthread_mutex_lock(&mut);
  pthread_create(&thread_identifier,NULL,(void*)thread, NULL);

  /* wait until canceltype is set */
  pthread_cond_wait(&mut_sig, &mut);
  pthread_mutex_unlock(&mut);

  /* do stuff, like data input */
  j = getc(STDIN);
  /* since we don't know when the character is read in, the program could continue at any time */
  pthread_cancel(thread_identifier);

  printf("a: %i | b: %i", a, b);
  /* this could potentially print "a: 10 | b: 10" or "a: 5 | b: 5", both demonstrating data corruption */

  /* clean up */
  pthread_mutex_destroy(&mut);
  pthread_cond_destroy(&mut_sig);
}

void thread(void) {
  int i, c;

  /* set the cancelability flag during mutex. */
  /* this guarantees this block calls after pthread_cond_wait() and, more importantly, before pthread_cancel() */
  pthread_mutex_lock(&mut);
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&i);
  pthread_cond_signal(&mut_sig);
  pthread_mutex_unlock(&mut);

  while (1) {
    c = b;
    b = a;
    a = c;
  }
}

...

Code Block
bgColor#ccccff
volatile int a, b;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t mut_sig = PTHREAD_COND_INITIALIZER;

void main(void) {
  int j;
  a = 5;
  b = 10;

  pthread_mutex_lock(&mut);
  pthread_create(&thread_identifier,NULL,(void*)thread, NULL);

  /* wait until canceltype is set */
  pthread_cond_wait(&mut_sig, &mut);
  pthread_mutex_unlock(&mut);

  /* do stuff, like data input */
  j = getc(STDIN);
  /* since we don't know when the character is read in, the program could continue at any time */
  pthread_cancel(thread_identifier);

  /* pthread_join waits for the thread to finish up before continuing */
  pthread_join(thread_identifier, 0);

  printf("a: %i | b: %i", a, b);
  /* this will always print either "a: 5 | b: 10" or "a: 10 | b: 5" */

  /* clean up */
  pthread_mutex_destroy(&mut);
  pthread_cond_destroy(&mut_sig);
}
void thread(void) {
  int i, c;

  /* set the cancelability flag during mutex. */
  /* this guarantees this block calls after pthread_cond_wait() and, more importantly, before pthread_cancel() */
  pthread_mutex_lock(&mut);
  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,&i);
  pthread_cond_signal(&mut_sig);
  pthread_mutex_unlock(&mut);

  while (1) {
    c = b;
    b = a;
    a = c;
    /* now we're safe to cancel, creating cancel point */
    pthread_testcancel();
  }
}

...