#include <stdio.h>   
#include <stdlib.h>   
#include <sched.h>   
#include <sys/wait.h>   
#include <pthread.h>

#define N_THREADS 8

struct qnode {
  volatile struct qnode * next;
  volatile int locked;
};

int    maximum = 250000;    // default number of iterations
int    counter = 0;        // the shared counter is global


typedef struct qnode * qnode_ptr;
qnode_ptr lock = NULL;
struct qnode nodes[N_THREADS];


extern void enter_critical(qnode_ptr * l, qnode_ptr i);

extern void leave_critical(qnode_ptr * l, qnode_ptr i);

void *my_thread( void * data ) {
    int x = *(int *)data;
    int i;
    
    for(i = 0;i< maximum;i++) {
        enter_critical(&lock,&(nodes[x]));
        counter++;
        leave_critical(&lock,&(nodes[x]));
    }
   
   return 0;
}

int main( int argc, char **argv ) {
  pthread_t             	  threadid[N_THREADS];
  int                         loop=0;
  pthread_attr_t     		  pta;  
 
  pthread_attr_init(&pta);
  pthread_attr_setdetachstate(&pta, PTHREAD_CREATE_JOINABLE);
 
   for (loop=0; loop<N_THREADS; ++loop) {
    nodes[loop].locked = 0;
    nodes[loop].next = NULL;
    pthread_create(&threadid[loop], &pta, *my_thread, &loop);
  }
 
  for (loop=0; loop<N_THREADS; ++loop) {
    pthread_join(threadid[loop], NULL);
  } 

 
  printf( "%d \n", counter);
 
    return    0;
}




