#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
 
 
#define PID_MIN  	0
#define PID_MAX 	3
 
#define NUM_THREADS 100
#define ITERATIONS	10
#define SLEEP		5
 
 
 
 
int S;
 
/* mutex lock for accessing pid_map */
pthread_mutex_t mutex;
 
int pid_map[PID_MAX-PID_MIN+1];
int thread_counter =0;
 
 
int allocate_map(void);
int allocate_pid(void);
void release_pid(int pid);
 
 
 // Allocates the pid map.
 
int allocate_map(void) 
{
	/*initilize to zero explicitly just to make sure*/
	int i;
	for (i =0;i<PID_MAX-PID_MIN+1;i++)
	{
		pid_map[i] = 0;
		S++;
 
	}
	printf("map allocated!S=%d\n",S
); 	return 1;
}
 
/**
 * Allocates a pid
 */
int allocate_pid(void)
{
	int next_pid;
	int i;
	while (S<=0)
	{}
 
	pthread_mutex_lock(&mutex);
	S--;
	for (i =0;i<PID_MAX-PID_MIN;i++)
		{
			if (pid_map[i] == 0)
				{
					pid_map[i] = 1;
					next_pid=i;
					pthread_mutex_unlock(&mutex);
					return next_pid+PID_MIN;
 
 
 
				}
		}
 
 
}
/**
 * Releases a pid
 */
void release_pid(int pid)
{
	pid = pid-PID_MIN;
	pid_map[pid] = 0;
	S++;
}
 
void *do_something(void *threadid)
	{
		int  my_pid;
		long thread_id;
		int i;
		double r;
		thread_id= (long)threadid;
 
		for (i=0;i<ITERATIONS;i++)
		{
			r=r/10;
			//r=0.1;
			//printf("thread %d trying to allocate PID..., S=%d\n",thread_id,S);
			my_pid=allocate_pid();
 
			printf("Thread number %d got PID %d S=%d\n", thread_id
, my_pid
,S
); 			sleep(r);
			release_pid(my_pid);
			printf("Thread number %d released PID %d S=%d \n", thread_id
, my_pid
,S
); 		}
		thread_counter--;
		pthread_exit(NULL);
	}
 
 
void main()
{
	int i,rc;
	time_t t;
	pthread_t tid[NUM_THREADS];
	allocate_map();
	for (i =0;i<10;i++)
	{
		//printf("In main: creating thread %d S=%d\n", i,S);
		thread_counter++;
		rc=pthread_create(&tid[i], NULL, do_something, (void *)i);
 
	}
	while (thread_counter >0)
	{
		sleep(1);
	}
}
 
 
 
 
				I2luY2x1ZGUgPHB0aHJlYWQuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHRpbWUuaD4KCgojZGVmaW5lIFBJRF9NSU4gIAkwCiNkZWZpbmUgUElEX01BWCAJMwoKI2RlZmluZSBOVU1fVEhSRUFEUyAxMDAKI2RlZmluZSBJVEVSQVRJT05TCTEwCiNkZWZpbmUgU0xFRVAJCTUKCgoKCmludCBTOwoKLyogbXV0ZXggbG9jayBmb3IgYWNjZXNzaW5nIHBpZF9tYXAgKi8KcHRocmVhZF9tdXRleF90IG11dGV4OwoKaW50IHBpZF9tYXBbUElEX01BWC1QSURfTUlOKzFdOwppbnQgdGhyZWFkX2NvdW50ZXIgPTA7CgoKaW50IGFsbG9jYXRlX21hcCh2b2lkKTsKaW50IGFsbG9jYXRlX3BpZCh2b2lkKTsKdm9pZCByZWxlYXNlX3BpZChpbnQgcGlkKTsKCgogLy8gQWxsb2NhdGVzIHRoZSBwaWQgbWFwLgogCmludCBhbGxvY2F0ZV9tYXAodm9pZCkgCnsKCS8qaW5pdGlsaXplIHRvIHplcm8gZXhwbGljaXRseSBqdXN0IHRvIG1ha2Ugc3VyZSovCglpbnQgaTsKCWZvciAoaSA9MDtpPFBJRF9NQVgtUElEX01JTisxO2krKykKCXsKCQlwaWRfbWFwW2ldID0gMDsKCQlTKys7CgkJCgl9CglwcmludGYoIm1hcCBhbGxvY2F0ZWQhUz0lZFxuIixTKTsKCXJldHVybiAxOwp9CgovKioKICogQWxsb2NhdGVzIGEgcGlkCiAqLwppbnQgYWxsb2NhdGVfcGlkKHZvaWQpCnsKCWludCBuZXh0X3BpZDsKCWludCBpOwoJd2hpbGUgKFM8PTApCgl7fQoJCglwdGhyZWFkX211dGV4X2xvY2soJm11dGV4KTsKCVMtLTsKCWZvciAoaSA9MDtpPFBJRF9NQVgtUElEX01JTjtpKyspCgkJewoJCQlpZiAocGlkX21hcFtpXSA9PSAwKQoJCQkJewoJCQkJCXBpZF9tYXBbaV0gPSAxOwoJCQkJCW5leHRfcGlkPWk7CgkJCQkJcHRocmVhZF9tdXRleF91bmxvY2soJm11dGV4KTsKCQkJCQlyZXR1cm4gbmV4dF9waWQrUElEX01JTjsKCQkJCQkJCgkJCQkKCQkJCQkKCQkJCX0KCQl9CgkKCSAKfQovKioKICogUmVsZWFzZXMgYSBwaWQKICovCnZvaWQgcmVsZWFzZV9waWQoaW50IHBpZCkKewoJcGlkID0gcGlkLVBJRF9NSU47CglwaWRfbWFwW3BpZF0gPSAwOwoJUysrOwp9Cgp2b2lkICpkb19zb21ldGhpbmcodm9pZCAqdGhyZWFkaWQpCgl7CgkJaW50ICBteV9waWQ7CgkJbG9uZyB0aHJlYWRfaWQ7CgkJaW50IGk7CgkJZG91YmxlIHI7CgkJdGhyZWFkX2lkPSAobG9uZyl0aHJlYWRpZDsKCQkKCQlmb3IgKGk9MDtpPElURVJBVElPTlM7aSsrKQoJCXsKCQkJciA9IHJhbmQoKSU1MDsgLy8gMC01MAoJCQlyPXIvMTA7CgkJCS8vcj0wLjE7CgkJCS8vcHJpbnRmKCJ0aHJlYWQgJWQgdHJ5aW5nIHRvIGFsbG9jYXRlIFBJRC4uLiwgUz0lZFxuIix0aHJlYWRfaWQsUyk7CgkJCW15X3BpZD1hbGxvY2F0ZV9waWQoKTsKCgkJCXByaW50ZigiVGhyZWFkIG51bWJlciAlZCBnb3QgUElEICVkIFM9JWRcbiIsIHRocmVhZF9pZCwgbXlfcGlkLFMpOwoJCQlzbGVlcChyKTsKCQkJcmVsZWFzZV9waWQobXlfcGlkKTsKCQkJcHJpbnRmKCJUaHJlYWQgbnVtYmVyICVkIHJlbGVhc2VkIFBJRCAlZCBTPSVkIFxuIiwgdGhyZWFkX2lkLCBteV9waWQsUyk7CgkJfQoJCXRocmVhZF9jb3VudGVyLS07CgkJcHRocmVhZF9leGl0KE5VTEwpOwoJfQoKCQp2b2lkIG1haW4oKQp7CglpbnQgaSxyYzsKCXRpbWVfdCB0OwoJcHRocmVhZF90IHRpZFtOVU1fVEhSRUFEU107CglzcmFuZCgodW5zaWduZWQpIHRpbWUoJnQpKTsKCWFsbG9jYXRlX21hcCgpOwoJZm9yIChpID0wO2k8MTA7aSsrKQoJewoJCS8vcHJpbnRmKCJJbiBtYWluOiBjcmVhdGluZyB0aHJlYWQgJWQgUz0lZFxuIiwgaSxTKTsKCQl0aHJlYWRfY291bnRlcisrOwoJCXJjPXB0aHJlYWRfY3JlYXRlKCZ0aWRbaV0sIE5VTEwsIGRvX3NvbWV0aGluZywgKHZvaWQgKilpKTsKCQkKCX0KCXdoaWxlICh0aHJlYWRfY291bnRlciA+MCkKCXsKCQlzbGVlcCgxKTsKCX0KCXByaW50ZigiRE9ORSFcbiIpOwp9CgoKCg==