// Sample code that demonstrates the use of pthread_create and pthread_join.
// Multiple threads print out a sequence of numbers using printf.
// Although created in order, execution order will vary.
// For small LOOP_NUM, likely won't get interleaving of threads.
//
// Remember to compile with -pthread

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 4
#define LOOP_NUM 10


// print out a sequence of LOOP_NUM numbers with thread identifying number
void* thread_main(void* arg) {
  int* num = (int*) arg;  // read void* argument as intended

  for (int i = 0; i < LOOP_NUM; i++) {
    printf("[thread %d] %d\n", *num, i);
  }

  free(num);  // child thread cleans up the memory allocated for its argument
  return NULL;  // return type is a pointer
}


int main(int argc, char** argv) {
  pthread_t thds[NUM_THREADS];  // array of thread ids

  // create threads to run thread_main()
  for (int i = 0; i < NUM_THREADS; i++) {
    int* num = (int*) malloc(sizeof(int));
    *num = i;
    if (pthread_create(&thds[i], NULL, &thread_main, num) != 0) {
      fprintf(stderr, "pthread_create failed\n");
    }
  }

  // wait for all child threads to finish
  // (children may terminate out of order, but cleans up in order)
  for (int i = 0; i < NUM_THREADS; i++) {
    if (pthread_join(thds[i], NULL) != 0) {
      fprintf(stderr, "pthread_join failed\n");
    }
  }

  return EXIT_SUCCESS;
}