* Bacula Semaphore code. This code permits setting up
* a semaphore that lets through a specified number
* of callers simultaneously. Once the number of callers
- * exceed the limit, they block.
+ * exceed the limit, they block.
*
* Kern Sibbald, March MMIII
*
#include "bacula.h"
-/*
+/*
* Initialize a semaphore
*
* Returns: 0 on success
int sem_init(semlock_t *sem, int max_active)
{
int stat;
-
+
sem->active = sem->waiting = 0;
sem->max_active = max_active;
if ((stat = pthread_mutex_init(&sem->mutex, NULL)) != 0) {
*/
int sem_destroy(semlock_t *sem)
{
- int stat, stat1;
+ int stat, stat1;
if (sem->valid != SEMLOCK_VALID) {
return EINVAL;
return stat;
}
- /*
+ /*
* If any threads are active, report EBUSY
*/
if (sem->active > 0) {
int sem_lock(semlock_t *sem)
{
int stat;
-
+
if (sem->valid != SEMLOCK_VALID) {
return EINVAL;
}
return stat;
}
-/*
+/*
* Attempt to lock semaphore, don't wait
*/
int sem_trylock(semlock_t *sem)
{
int stat, stat1;
-
+
if (sem->valid != SEMLOCK_VALID) {
return EINVAL;
}
stat1 = pthread_mutex_unlock(&sem->mutex);
return (stat == 0 ? stat1 : stat);
}
-
-/*
+
+/*
* Unlock semaphore
* Start any waiting callers
*/
int sem_unlock(semlock_t *sem)
{
int stat, stat1;
-
+
if (sem->valid != SEMLOCK_VALID) {
return EINVAL;
}
int interval;
} thread_t;
-/*
+/*
* Semaphore lock and shared data.
*/
typedef struct data_tag {
thread_t threads[THREADS];
data_t data[DATASIZE];
-/*
+/*
* Thread start routine that uses semaphores locks.
*/
void *thread_routine(void *arg)
if ((iteration % self->interval) == 0) {
status = sem_writelock(&data[element].lock);
if (status != 0) {
- Emsg1(M_ABORT, 0, "Write lock failed. ERR=%s\n", strerror(status));
+ Emsg1(M_ABORT, 0, "Write lock failed. ERR=%s\n", strerror(status));
}
data[element].data = self->thread_num;
data[element].writes++;
self->writes++;
status = sem_writeunlock(&data[element].lock);
if (status != 0) {
- Emsg1(M_ABORT, 0, "Write unlock failed. ERR=%s\n", strerror(status));
+ Emsg1(M_ABORT, 0, "Write unlock failed. ERR=%s\n", strerror(status));
}
} else {
/*
*/
status = sem_readlock(&data[element].lock);
if (status != 0) {
- Emsg1(M_ABORT, 0, "Read lock failed. ERR=%s\n", strerror(status));
+ Emsg1(M_ABORT, 0, "Read lock failed. ERR=%s\n", strerror(status));
}
self->reads++;
if (data[element].data == self->thread_num)
repeats++;
status = sem_readunlock(&data[element].lock);
if (status != 0) {
- Emsg1(M_ABORT, 0, "Read unlock failed. ERR=%s\n", strerror(status));
+ Emsg1(M_ABORT, 0, "Read unlock failed. ERR=%s\n", strerror(status));
}
}
element++;
data[data_count].writes = 0;
status = sem_init (&data[data_count].lock);
if (status != 0) {
- Emsg1(M_ABORT, 0, "Init rwlock failed. ERR=%s\n", strerror(status));
+ Emsg1(M_ABORT, 0, "Init rwlock failed. ERR=%s\n", strerror(status));
}
}
status = pthread_create(&threads[count].thread_id,
NULL, thread_routine, (void*)&threads[count]);
if (status != 0) {
- Emsg1(M_ABORT, 0, "Create thread failed. ERR=%s\n", strerror(status));
+ Emsg1(M_ABORT, 0, "Create thread failed. ERR=%s\n", strerror(status));
}
}
for (count = 0; count < THREADS; count++) {
status = pthread_join (threads[count].thread_id, NULL);
if (status != 0) {
- Emsg1(M_ABORT, 0, "Join thread failed. ERR=%s\n", strerror(status));
+ Emsg1(M_ABORT, 0, "Join thread failed. ERR=%s\n", strerror(status));
}
thread_writes += threads[count].writes;
- printf ("%02d: interval %d, writes %d, reads %d\n",
+ printf ("%02d: interval %d, writes %d, reads %d\n",
count, threads[count].interval,
threads[count].writes, threads[count].reads);
}
*/
for (data_count = 0; data_count < DATASIZE; data_count++) {
data_writes += data[data_count].writes;
- printf ("data %02d: value %d, %d writes\n",
+ printf ("data %02d: value %d, %d writes\n",
data_count, data[data_count].data, data[data_count].writes);
sem_destroy (&data[data_count].lock);
}
self->updates++;
sem_writeunlock (&data[element].lock);
} else
- err_abort (status, "Try write lock");
+ err_abort (status, "Try write lock");
} else {
status = sem_readtrylock (&data[element].lock);
if (status == EBUSY)
self->r_collisions++;
else if (status != 0) {
- err_abort (status, "Try read lock");
+ err_abort (status, "Try read lock");
} else {
if (data[element].data != data[element].updates)
- printf ("%d: data[%d] %d != %d\n",
+ printf ("%d: data[%d] %d != %d\n",
self->thread_num, element,
data[element].data, data[element].updates);
sem_readunlock (&data[element].lock);
status = pthread_create (&threads[count].thread_id,
NULL, thread_routine, (void*)&threads[count]);
if (status != 0)
- err_abort (status, "Create thread");
+ err_abort (status, "Create thread");
}
/*
for (count = 0; count < THREADS; count++) {
status = pthread_join(threads[count].thread_id, NULL);
if (status != 0)
- err_abort(status, "Join thread");
+ err_abort(status, "Join thread");
thread_updates += threads[count].updates;
- printf ("%02d: interval %d, updates %d, "
- "r_collisions %d, w_collisions %d\n",
+ printf ("%02d: interval %d, updates %d, "
+ "r_collisions %d, w_collisions %d\n",
count, threads[count].interval,
threads[count].updates,
threads[count].r_collisions, threads[count].w_collisions);
*/
for (data_count = 0; data_count < DATASIZE; data_count++) {
data_updates += data[data_count].updates;
- printf ("data %02d: value %d, %d updates\n",
+ printf ("data %02d: value %d, %d updates\n",
data_count, data[data_count].data, data[data_count].updates);
sem_destroy(&data[data_count].lock);
}