#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#define PID_MIN 300
#define PID_MAX 350
#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;
int thread_counter =0;
int allocate_map(void);
int allocate_PID(int thread_id); //not (void) purely for a nicer output, it shows therad id
void release_pid(int pid);
// Allocates the pid map.
int allocate_map(void)
{
/*initilize to zero explicitly just to make sure*/
int i;
pid_map
=(int*)malloc((PID_MAX
-PID_MIN
+1)*sizeof(int)); if (pid_map == NULL)
return -1;
// the structure is a bitmap:
//0 - available,
//1 - taken
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(int t_id)
{
int next_pid;
int i,j;
int err;
if (S<=0)
return -1; //NOT thread SAFE
pthread_mutex_lock(&mutex);
while (S<=0)
{}
for (i =0;i<PID_MAX-PID_MIN+1;i++)
{
if (pid_map[i] == 0)
{
S--;
printf("Thread number %d got PID %d S=%d\n", t_id
, i
+PID_MIN
,S
); pid_map[i] = 1;
next_pid=i;
pthread_mutex_unlock(&mutex);
return (next_pid+PID_MIN);
}
}
//for debug purposes:
//if a thread will pass mutex and S-semaphore
//but won't find a PID then -999 will be returned
return -999;
}
/**
* 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;
//printf("\nthread %d launched do_something\n", thread_id);
//for (i=0;i<10;i++)
while(2>1)
{
r=r/10;
sleep(r/100);
my_pid=allocate_PID(thread_id); //will return PID or "-1" if unsucessfull
if (my_pid==-1)
{
printf("thread %d was NOT able allocate PID\n",thread_id
);
}
else
{
sleep(r);
release_pid(my_pid);
printf("Thread number %d released PID %d \tPIDs available: %d \n", thread_id
, my_pid
,S
); thread_counter--;
return;
}
}
}
int main()
{
int i,err;
time_t t;
pthread_t tid[NUM_THREADS];
if (pthread_mutex_init(&mutex, NULL) != 0)
{
printf("\n mutex init failed\n"); return 1;
}
allocate_map();
while(i < NUM_THREADS)
{
err = pthread_create(&(tid[i]), NULL, &do_something, (void*)i);
if (err != 0)
i++;
thread_counter++;
//printf("\nthread %d created\n", i);
}
while (thread_counter >0)
{
sleep(1);
}
pthread_mutex_destroy(&mutex);
}
I2luY2x1ZGUgPHB0aHJlYWQuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHRpbWUuaD4KCgojZGVmaW5lIFBJRF9NSU4gIAkzMDAKI2RlZmluZSBQSURfTUFYIAkzNTAKCiNkZWZpbmUgTlVNX1RIUkVBRFMgMTAwCiNkZWZpbmUgSVRFUkFUSU9OUwkxMAojZGVmaW5lIFNMRUVQCQk1CgoKCgppbnQgUzsKCi8qIG11dGV4IGxvY2sgZm9yIGFjY2Vzc2luZyBwaWRfbWFwICovCnB0aHJlYWRfbXV0ZXhfdCBtdXRleDsKCmludCogcGlkX21hcDsKaW50IHRocmVhZF9jb3VudGVyID0wOwoKCmludCBhbGxvY2F0ZV9tYXAodm9pZCk7CmludCBhbGxvY2F0ZV9QSUQoaW50IHRocmVhZF9pZCk7IC8vbm90ICh2b2lkKSBwdXJlbHkgZm9yIGEgbmljZXIgb3V0cHV0LCBpdCBzaG93cyB0aGVyYWQgaWQKdm9pZCByZWxlYXNlX3BpZChpbnQgcGlkKTsKCgoKIC8vIEFsbG9jYXRlcyB0aGUgcGlkIG1hcC4KIAppbnQgYWxsb2NhdGVfbWFwKHZvaWQpIAp7CgkvKmluaXRpbGl6ZSB0byB6ZXJvIGV4cGxpY2l0bHkganVzdCB0byBtYWtlIHN1cmUqLwoJaW50IGk7CgkJcGlkX21hcCA9KGludCopbWFsbG9jKChQSURfTUFYLVBJRF9NSU4rMSkqc2l6ZW9mKGludCkpOwoJCWlmIChwaWRfbWFwID09IE5VTEwpCgkJCXJldHVybiAtMTsKCQkKCQkvLyB0aGUgc3RydWN0dXJlIGlzIGEgYml0bWFwOgoJCS8vMCAtIGF2YWlsYWJsZSwKCQkvLzEgLSB0YWtlbgogICAgICAgIGZvciAoaSA9MDtpPFBJRF9NQVgtUElEX01JTisxO2krKykKICAgICAgICB7CiAgICAgICAgICAgIHBpZF9tYXBbaV0gPSAwOwogICAgICAgICAgICBTKys7CgkJCiAgICAgICAgfQogICAgICAgIHByaW50ZigibWFwIGFsbG9jYXRlZCFTPSVkXG4iLFMpOwogICAgICAgIHJldHVybiAxOwogICAgCn0KCi8qKgogKiBBbGxvY2F0ZXMgYSBwaWQKICovCmludCBhbGxvY2F0ZV9QSUQoaW50IHRfaWQpCnsKCWludCBuZXh0X3BpZDsKCWludCBpLGo7CglpbnQgZXJyOwoJCglpZiAoUzw9MCkKCQlyZXR1cm4gLTE7IC8vTk9UIHRocmVhZCBTQUZFCgkKICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmbXV0ZXgpOwoJd2hpbGUgKFM8PTApCiAgICB7fQoJCglmb3IgKGkgPTA7aTxQSURfTUFYLVBJRF9NSU4rMTtpKyspCgkJewoJCQlpZiAocGlkX21hcFtpXSA9PSAwKQoJCQkJewogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIFMtLTsKICAgICAgICAgICAgICAgICAgICBwcmludGYoIlRocmVhZCBudW1iZXIgJWQgZ290IFBJRCAlZCBTPSVkXG4iLCB0X2lkLCBpK1BJRF9NSU4sUyk7CiAgICAgICAgICAgICAgICAgICAgcGlkX21hcFtpXSA9IDE7CgkJCQkJbmV4dF9waWQ9aTsKCQkJCQlwdGhyZWFkX211dGV4X3VubG9jaygmbXV0ZXgpOwoJCQkJCXJldHVybiAobmV4dF9waWQrUElEX01JTik7CgkJCQkJCQoJCQkJCgkJCQkJCgkJCQl9CgkJfQoJLy9mb3IgZGVidWcgcHVycG9zZXM6CgkvL2lmIGEgdGhyZWFkIHdpbGwgcGFzcyBtdXRleCBhbmQgUy1zZW1hcGhvcmUKCS8vYnV0IHdvbid0IGZpbmQgYSBQSUQgdGhlbiAtOTk5IHdpbGwgYmUgcmV0dXJuZWQKCXJldHVybiAtOTk5OwoJIAp9Ci8qKgogKiBSZWxlYXNlcyBhIHBpZAogKi8Kdm9pZCByZWxlYXNlX3BpZChpbnQgcGlkKQp7CglwaWQgPSBwaWQtUElEX01JTjsKCXBpZF9tYXBbcGlkXSA9IDA7CglTKys7Cn0KCnZvaWQgKmRvX3NvbWV0aGluZyh2b2lkICp0aHJlYWRpZCkKCXsKCQlpbnQgIG15X3BpZDsKCQlsb25nIHRocmVhZF9pZDsKCQlpbnQgaTsKCQlkb3VibGUgcjsKCQl0aHJlYWRfaWQ9IChsb25nKXRocmVhZGlkOwoJCS8vcHJpbnRmKCJcbnRocmVhZCAlZCBsYXVuY2hlZCBkb19zb21ldGhpbmdcbiIsIHRocmVhZF9pZCk7CgkJCgkJCgkJCgkJLy9mb3IgKGk9MDtpPDEwO2krKykKCQl3aGlsZSgyPjEpCQoJCXsKCQkJciA9IHJhbmQoKSU1MDsgLy8gMC01MAoJCQlyPXIvMTA7CgkJCQoJCQlzbGVlcChyLzEwMCk7CgkJCW15X3BpZD1hbGxvY2F0ZV9QSUQodGhyZWFkX2lkKTsgLy93aWxsIHJldHVybiBQSUQgb3IgIi0xIiBpZiB1bnN1Y2Vzc2Z1bGwKCQkJaWYgKG15X3BpZD09LTEpCgkJCQl7CgkJCQkJcHJpbnRmKCJ0aHJlYWQgJWQgd2FzIE5PVCBhYmxlIGFsbG9jYXRlIFBJRFxuIix0aHJlYWRfaWQpOwkKCQkJCQoJCQkJfQoJCQllbHNlCgkJCQl7CgkJCQkJc2xlZXAocik7CgkJCQkJcmVsZWFzZV9waWQobXlfcGlkKTsKCQkJCQoJCQkJCXByaW50ZigiVGhyZWFkIG51bWJlciAlZCByZWxlYXNlZCBQSUQgJWQgXHRQSURzIGF2YWlsYWJsZTogJWQgXG4iLCB0aHJlYWRfaWQsIG15X3BpZCxTKTsKCQkJCQl0aHJlYWRfY291bnRlci0tOwoJCQkJCXJldHVybjsKCQkJCX0KCQl9CgkJCgkJCgl9CgoJCmludCBtYWluKCkKewoJaW50IGksZXJyOwoJdGltZV90IHQ7CgkKCXB0aHJlYWRfdCB0aWRbTlVNX1RIUkVBRFNdOwoJaWYgKHB0aHJlYWRfbXV0ZXhfaW5pdCgmbXV0ZXgsIE5VTEwpICE9IDApCiAgICB7CiAgICAgICAgcHJpbnRmKCJcbiBtdXRleCBpbml0IGZhaWxlZFxuIik7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgkKCQoJc3JhbmQoKHVuc2lnbmVkKSB0aW1lKCZ0KSk7CglhbGxvY2F0ZV9tYXAoKTsKCXdoaWxlKGkgPCBOVU1fVEhSRUFEUykKICAgIHsKICAgICAgICBlcnIgPSBwdGhyZWFkX2NyZWF0ZSgmKHRpZFtpXSksIE5VTEwsICZkb19zb21ldGhpbmcsICh2b2lkKilpKTsKICAgICAgICBpZiAoZXJyICE9IDApCiAgICAgICAgICAgIHByaW50ZigiXG5jYW4ndCBjcmVhdGUgdGhyZWFkIDpbJXNdIiwgc3RyZXJyb3IoZXJyKSk7CiAgICAgICAgaSsrOwoJCXRocmVhZF9jb3VudGVyKys7CgkJLy9wcmludGYoIlxudGhyZWFkICVkIGNyZWF0ZWRcbiIsIGkpOwogICAgfQoJCgl3aGlsZSAodGhyZWFkX2NvdW50ZXIgPjApCgl7CgkJc2xlZXAoMSk7Cgl9CgkgcHRocmVhZF9tdXRleF9kZXN0cm95KCZtdXRleCk7CglwcmludGYoIioqKkRPTkUhKioqXG4iKTsKfQoKCgo=