104 lines
2.3 KiB
C
104 lines
2.3 KiB
C
#include <pthread.h>
|
|
#include <stdio.h>
|
|
//#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/time.h>
|
|
#include <semaphore.h>
|
|
//#include <limits.h>
|
|
#include <sched.h>
|
|
|
|
#define MAX_THREADS 50
|
|
#define MAX_REGION_ENTRIES 10
|
|
|
|
void* thread_function(void *ptr);
|
|
void enter_region(size_t id);
|
|
void leave_region(size_t id);
|
|
|
|
int cancel_threads = 0;
|
|
sem_t region_semaphore;
|
|
pthread_mutex_t region_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
size_t regionentries[MAX_REGION_ENTRIES];
|
|
|
|
int main(int argc, char *argv[]) {
|
|
pthread_attr_t attr;
|
|
pthread_t threads[MAX_THREADS];
|
|
size_t i, counter = 0;
|
|
|
|
// 0=local process, MAX_REGION_ENTRIES=initial state
|
|
if ( sem_init( ®ion_semaphore, 0, MAX_REGION_ENTRIES ) == 0 ) {
|
|
if ( pthread_attr_init( &attr ) == 0 ) {
|
|
for (i=0; i<MAX_THREADS; i++) {
|
|
if ( pthread_create( &(threads[counter]), &attr, thread_function, (void*)(i+1)) == 0 )
|
|
counter++;
|
|
}
|
|
scanf("%d", &cancel_threads); // set cancel condition
|
|
for (i=0;i<counter;i++) {
|
|
pthread_join( threads[i], 0);
|
|
}
|
|
}
|
|
sem_destroy( ®ion_semaphore);
|
|
}
|
|
printf("Main thread finished!\n");
|
|
}
|
|
|
|
void* thread_function(void *ptr)
|
|
{
|
|
size_t threadid=(size_t)ptr;
|
|
time_t t;
|
|
|
|
while( ! cancel_threads ){
|
|
enter_region(threadid);
|
|
t=time(0); // short wait (passive)
|
|
usleep((localtime(&t)->tm_sec+localtime(&t)->tm_min)*1000 );
|
|
leave_region(threadid);
|
|
sched_yield(); // yield CPU
|
|
}
|
|
printf("Thread %zu finished!\n", threadid);
|
|
return 0;
|
|
}
|
|
|
|
void print_region_entries() {
|
|
int i;
|
|
printf("Threads in region: ");
|
|
for (i=0; i<MAX_REGION_ENTRIES; i++)
|
|
printf("%zu ", regionentries[i]);
|
|
printf("\n");
|
|
|
|
for(i=0;i<1000000;i++) // short wait (active)
|
|
i;
|
|
}
|
|
|
|
|
|
void enter_region(size_t id) {
|
|
int i;
|
|
sem_wait( ®ion_semaphore );
|
|
|
|
pthread_mutex_lock(®ion_mutex);
|
|
for (i=0;i<MAX_REGION_ENTRIES;i++) {
|
|
if ( regionentries[i]==0 ) {
|
|
regionentries[i]=id;
|
|
break;
|
|
}
|
|
}
|
|
print_region_entries();
|
|
pthread_mutex_unlock(®ion_mutex);
|
|
}
|
|
|
|
|
|
void leave_region(size_t id)
|
|
{
|
|
int i;
|
|
|
|
pthread_mutex_lock(®ion_mutex);
|
|
for (i=0;i<MAX_REGION_ENTRIES;i++) {
|
|
if ( regionentries[i]==id )
|
|
{ regionentries[i]=0;
|
|
break;
|
|
}
|
|
}
|
|
print_region_entries();
|
|
pthread_mutex_unlock(®ion_mutex);
|
|
|
|
sem_post( ®ion_semaphore );
|
|
}
|