|
|
@ -20,14 +20,14 @@
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "libscp_lock.h"
|
|
|
|
#include "libscp_lock.h"
|
|
|
|
|
|
|
|
#include "thread_calls.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <semaphore.h>
|
|
|
|
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_t lock_fork; /* this lock protects the counters */
|
|
|
|
pthread_mutex_t lock_fork; /* this lock protects the counters */
|
|
|
|
pthread_mutexattr_t lock_fork_attr; /* mutex attributes */
|
|
|
|
pthread_mutexattr_t lock_fork_attr; /* mutex attributes */
|
|
|
|
sem_t lock_fork_req; /* semaphore on which the process that are going to fork suspend on */
|
|
|
|
tbus lock_fork_req; /* semaphore on which the process that are going to fork suspend on */
|
|
|
|
sem_t lock_fork_wait; /* semaphore on which the suspended process wait on */
|
|
|
|
tbus lock_fork_wait; /* semaphore on which the suspended process wait on */
|
|
|
|
int lock_fork_forkers_count; /* threads that want to fork */
|
|
|
|
int lock_fork_forkers_count; /* threads that want to fork */
|
|
|
|
int lock_fork_blockers_count; /* threads thar are blocking fork */
|
|
|
|
int lock_fork_blockers_count; /* threads thar are blocking fork */
|
|
|
|
int lock_fork_waiting_count; /* threads suspended until the fork finishes */
|
|
|
|
int lock_fork_waiting_count; /* threads suspended until the fork finishes */
|
|
|
@ -38,8 +38,8 @@ scp_lock_init(void)
|
|
|
|
/* initializing fork lock */
|
|
|
|
/* initializing fork lock */
|
|
|
|
pthread_mutexattr_init(&lock_fork_attr);
|
|
|
|
pthread_mutexattr_init(&lock_fork_attr);
|
|
|
|
pthread_mutex_init(&lock_fork, &lock_fork_attr);
|
|
|
|
pthread_mutex_init(&lock_fork, &lock_fork_attr);
|
|
|
|
sem_init(&lock_fork_req, 0, 0);
|
|
|
|
lock_fork_req = tc_sem_create(0);
|
|
|
|
sem_init(&lock_fork_wait, 0, 0);
|
|
|
|
lock_fork_wait = tc_sem_create(0);
|
|
|
|
|
|
|
|
|
|
|
|
/* here we don't use locking because lock_init() should be called BEFORE */
|
|
|
|
/* here we don't use locking because lock_init() should be called BEFORE */
|
|
|
|
/* any thread is created */
|
|
|
|
/* any thread is created */
|
|
|
@ -58,14 +58,14 @@ scp_lock_fork_request(void)
|
|
|
|
if (lock_fork_blockers_count == 0)
|
|
|
|
if (lock_fork_blockers_count == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* if no one is blocking fork(), then we're allowed to fork */
|
|
|
|
/* if no one is blocking fork(), then we're allowed to fork */
|
|
|
|
sem_post(&lock_fork_req);
|
|
|
|
tc_sem_inc(lock_fork_req);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lock_fork_forkers_count++;
|
|
|
|
lock_fork_forkers_count++;
|
|
|
|
pthread_mutex_unlock(&lock_fork);
|
|
|
|
pthread_mutex_unlock(&lock_fork);
|
|
|
|
|
|
|
|
|
|
|
|
/* we wait to be allowed to fork() */
|
|
|
|
/* we wait to be allowed to fork() */
|
|
|
|
sem_wait(&lock_fork_req);
|
|
|
|
tc_sem_dec(lock_fork_req);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
|
@ -78,13 +78,13 @@ scp_lock_fork_release(void)
|
|
|
|
/* if there's someone else that want to fork, we let him fork() */
|
|
|
|
/* if there's someone else that want to fork, we let him fork() */
|
|
|
|
if (lock_fork_forkers_count > 0)
|
|
|
|
if (lock_fork_forkers_count > 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sem_post(&lock_fork_req);
|
|
|
|
tc_sem_inc(lock_fork_req);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (; lock_fork_waiting_count > 0; lock_fork_waiting_count--)
|
|
|
|
for (; lock_fork_waiting_count > 0; lock_fork_waiting_count--)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* waking up the other processes */
|
|
|
|
/* waking up the other processes */
|
|
|
|
sem_post(&lock_fork_wait);
|
|
|
|
tc_sem_inc(lock_fork_wait);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&lock_fork);
|
|
|
|
pthread_mutex_unlock(&lock_fork);
|
|
|
@ -107,7 +107,7 @@ scp_lock_fork_critical_section_end(int blocking)
|
|
|
|
/* then we let him go */
|
|
|
|
/* then we let him go */
|
|
|
|
if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count > 0))
|
|
|
|
if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count > 0))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sem_post(&lock_fork_req);
|
|
|
|
tc_sem_inc(lock_fork_req);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&lock_fork);
|
|
|
|
pthread_mutex_unlock(&lock_fork);
|
|
|
@ -129,7 +129,7 @@ scp_lock_fork_critical_section_start(void)
|
|
|
|
pthread_mutex_unlock(&lock_fork);
|
|
|
|
pthread_mutex_unlock(&lock_fork);
|
|
|
|
|
|
|
|
|
|
|
|
/* we wait until the fork finishes */
|
|
|
|
/* we wait until the fork finishes */
|
|
|
|
sem_wait(&lock_fork_wait);
|
|
|
|
tc_sem_dec(lock_fork_wait);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|