#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#ifdef __cplusplus
};
#endif
#include "timer.hh"
#include "memsem.hh"
#include "rcs_print.hh"
#define TIMEOUT_MIN ((double) 1.0E-6)
#if 0#endif
int mem_get_access(struct mem_access_object *mo)
{
char *mylock;
char current_lock;
char *plock;
char *lastlock;
int semaphores_clear;
double start_time, time;
int split_buffer = 0;
int read_only;
int total_connections;
int connection_number;
double timeout;
#ifdef DEBUG
rcs_print("mem_get_access: - Time = %lf\n", etime());
static int count = 0;
count++;
#endif
if ((total_connections = mo->total_connections) <=
(connection_number = mo->connection_number) || connection_number < 0)
{
return -1;
}
if (NULL == mo->data) {
return -1;
}
int wait_requested = 1;
lastlock = ((char *) mo->data) + total_connections;
mylock = ((char *) mo->data) + connection_number;
time = start_time = etime();
while (wait_requested
&& (time - start_time < mo->timeout / 2 || mo->timeout < 0)) {
wait_requested = 0;
for (plock = (char *) mo->data; plock < lastlock; plock++) {
if (5 == (current_lock = *plock) && plock != mylock) {
wait_requested = 1;
}
}
if (wait_requested) {
esleep(mo->sem_delay);
}
}
*mylock = 4;
mo->toggle_bit = ((char *) mo->data)[total_connections];
read_only = mo->read_only;
#ifdef DEBUG
if (read_only) {
rcs_print("added sleep: %d - Time = %lf\n", __LINE__, etime());
esleep(0.02);
}
#endif
if (read_only) {
split_buffer = mo->split_buffer;
if (split_buffer) {
*mylock = 2 + mo->toggle_bit;
return 0;
}
*mylock = 2;
} else {
*mylock = 1;
}
#ifdef debug
if (read_only) {
rcs_print("added sleep: %d - time = %lf\n", __line__, etime());
esleep(0.01);
}
#endif
semaphores_clear = 1;
lastlock = ((char *) mo->data) + total_connections;
mo->toggle_bit = ((char *) mo->data)[total_connections];
for (plock = (char *) mo->data; plock < lastlock; plock++) {
if (0 != (current_lock = *plock)) {
if (plock != mylock) {
if (!(read_only && current_lock > 1) &&
!(split_buffer && current_lock == 2 + mo->toggle_bit)
&& (current_lock != 5)) {
semaphores_clear = 0;
}
}
}
}
#ifdef debug
if (0) {
rcs_print("added sleep: %d - time = %lf\n", __line__, etime());
esleep(0.01);
}
#endif
if (semaphores_clear) {
return 0;
}
timeout = mo->timeout;
if (timeout < TIMEOUT_MIN && timeout > 0) {
*mylock = 0;
return (-2);
}
*mylock = 5;
if (NULL != mo->sem) {
if (-1 == mo->sem->wait()) {
*mylock = 0;
return -1;
}
} else {
esleep(mo->sem_delay);
}
if (read_only) {
*mylock = 2;
} else {
*mylock = 1;
}
#ifdef debug
if (0) {
rcs_print("added sleep: %d - time = %lf\n", __line__, etime());
esleep(0.01);
}
#endif
while ((timeout >= 0) ? ((time - start_time) < timeout) : 1) {
if (split_buffer) {
mo->toggle_bit = ((char *) mo->data)[total_connections];
}
semaphores_clear = 1;
plock = (char *) mo->data;
mo->toggle_bit = ((char *) mo->data)[total_connections];
for (; plock < lastlock; plock++) {
current_lock = *plock;
if (0 != current_lock) {
if (plock != mylock &&
!(read_only && current_lock > 1) &&
!(split_buffer && current_lock == 2 + mo->toggle_bit)
&& (current_lock != 5)) {
semaphores_clear = 0;
}
}
}
if (semaphores_clear) {
return 0;
}
if (NULL != mo->sem) {
*mylock = 5;
mo->sem->wait();
} else {
*mylock = 5;
esleep(mo->sem_delay);
}
if (read_only) {
*mylock = 2;
} else {
*mylock = 1;
}
#ifdef DEBUG
if (0) {
rcs_print("added sleep: %d - Time = %lf\n", __LINE__, etime());
esleep(0.01);
}
#endif
time = etime();
}
*mylock = 0;
return (-2);
}
int mem_release_access(struct mem_access_object *mo)
{
int i;
int process_waiting = 0;
#ifdef DEBUG
rcs_print("mem_release_access: - Time = %lf\n", etime());
static int count = 0;
count++;
#endif
if (NULL == mo) {
rcs_print_error("mem_release_access: Invalid memory object.\n");
return -1;
}
if (NULL == mo->data || mo->connection_number < 0) {
rcs_print_error("mem_release_access: Invalid memory object.\n");
return -1;
}
if (mo->sem != NULL) {
process_waiting = 0;
for (i = 0; i < mo->total_connections; i++) {
if (((char *) mo->data)[i] == 5) {
process_waiting = 1;
break;
}
}
}
#ifdef DEBUG
if (0) {
rcs_print("added sleep: %d - Time = %lf\n", __LINE__, etime());
esleep(0.01);
}
#endif
if (mo->split_buffer && ((char *) mo->data)[mo->connection_number] == 1) {
((char *) mo->data)[mo->total_connections] = !(mo->toggle_bit);
}
#ifdef DEBUG
if (0) {
rcs_print("added sleep: %d - Time = %lf\n", __LINE__, etime());
esleep(0.01);
}
#endif
((char *) mo->data)[mo->connection_number] = 0;
#ifdef DEBUG
if (0) {
rcs_print("added sleep: %d - Time = %lf\n", __LINE__, etime());
esleep(0.01);
}
#endif
if (mo->sem != NULL) {
if (process_waiting) {
mo->sem->post();
}
}
return (0);
}