Commit c1d7ef4a authored by Éric Thiébaut's avatar Éric Thiébaut
Browse files

Remove "inline-funcs.h" file

parent c7a33d2d
......@@ -125,7 +125,7 @@ libtao_xpa_la_CPPFLAGS = $(XPA_DEFS)
libtao_xpa_la_LIBADD = $(XPA_LIBS) $(TAO_LIBS)
libtao_xpa_la_LDFLAGS = -version-info @version_info@
EXTRA_DIST = shared-methods.c inline-funcs.h intro.txt
EXTRA_DIST = shared-methods.c intro.txt
bin_PROGRAMS = \
tao-fake-mirror-server
......
// inline-funcs.c -
//
// Definitions of in-line functions for shared objects in TAO library.
//
//-----------------------------------------------------------------------------
//
// This file if part of TAO real-time software licensed under the MIT license
// (https://git-cral.univ-lyon1.fr/tao/tao-rt).
//
// Copyright (C) 2018-2022, Éric Thiébaut.
#ifndef TAO_INLINE_FUNCS_H
#define TAO_INLINE_FUNCS_H 1
#include <math.h>
#include <time.h>
#include <pthread.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdatomic.h>
#include "tao-basics.h"
#include "tao-locks.h"
#include "tao-errors.h"
#include "tao-generic.h"
#include "tao-shared-objects-private.h"
#include "tao-remote-objects-private.h"
#include "tao-rwlocked-objects-private.h"
//-----------------------------------------------------------------------------
// READ/WRITE LOCKED OBJECTS
static inline bool rwlocked_object_is_readable(
tao_rwlocked_object* obj)
{
return obj->users >= 0 && obj->writers == 0;
}
static inline bool rwlocked_object_is_writable(
tao_rwlocked_object* obj)
{
return obj->users == 0;
}
static inline tao_status rwlocked_object_unlock(
const char* func,
tao_rwlocked_object* obj)
{
tao_status status = tao_mutex_lock(&obj->base.mutex);
if (status == TAO_OK) {
// Object has been locked.
bool notify = false;
int errcode = TAO_SUCCESS;
if (obj->users == -1) {
// Remove the write lock and notify others.
obj->users = 0;
notify = true;
} else if (obj->users > 0) {
// Remove one read lock and notify others if are there no remaining
// readers.
obj->users -= 1;
notify = (obj->users == 0);
} else {
// Something wrong has been done.
errcode = (obj->users == 0 ? TAO_NOT_LOCKED : TAO_CORRUPTED);
}
if (notify) {
status = tao_condition_broadcast(&obj->base.cond);
}
if (tao_mutex_unlock(&obj->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
if (errcode != TAO_SUCCESS) {
tao_store_error(func, errcode);
status = TAO_ERROR;
}
}
return status;
}
// Lock for read-only access.
static inline tao_status rwlocked_object_rdlock(
const char* func,
tao_rwlocked_object* obj)
{
tao_status status = tao_mutex_lock(&obj->base.mutex);
if (status == TAO_OK) {
// Object has been locked.
while (status == TAO_OK && ! rwlocked_object_is_readable(obj)) {
status = tao_condition_wait(&obj->base.cond, &obj->base.mutex);
}
if (status == TAO_OK) {
obj->users += 1;
}
if (tao_mutex_unlock(&obj->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
static inline tao_status rwlocked_object_try_rdlock(
const char* func,
tao_rwlocked_object* obj)
{
tao_status status = tao_mutex_try_lock(&obj->base.mutex);
if (status == TAO_OK) {
// Object has been locked.
if (rwlocked_object_is_readable(obj)) {
obj->users += 1;
} else {
status = TAO_TIMEOUT;
}
if (tao_mutex_unlock(&obj->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
static inline tao_status rwlocked_object_abstimed_rdlock(
const char* func,
tao_rwlocked_object* obj,
const tao_time* abstime)
{
tao_status status = tao_mutex_abstimed_lock(&obj->base.mutex, abstime);
if (status == TAO_OK) {
// Object has been locked.
while (status == TAO_OK && ! rwlocked_object_is_readable(obj)) {
status = tao_condition_abstimed_wait(
&obj->base.cond, &obj->base.mutex, abstime);
}
if (status == TAO_OK) {
obj->users += 1;
}
if (tao_mutex_unlock(&obj->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
static inline tao_status rwlocked_object_timed_rdlock(
const char* func,
tao_rwlocked_object* obj,
double secs)
{
tao_time abstime;
switch (tao_get_absolute_timeout(&abstime, secs)) {
case TAO_TIMEOUT_PAST:
return TAO_TIMEOUT;
case TAO_TIMEOUT_NOW:
return rwlocked_object_try_rdlock(func, obj);
case TAO_TIMEOUT_FUTURE:
return rwlocked_object_abstimed_rdlock(func, obj, &abstime);
case TAO_TIMEOUT_NEVER:
return rwlocked_object_rdlock(func, obj);
default:
return TAO_ERROR;
}
}
// Lock for read-write access.
static inline tao_status rwlocked_object_wrlock(
const char* func,
tao_rwlocked_object* obj)
{
tao_status status = tao_mutex_lock(&obj->base.mutex);
if (status == TAO_OK) {
// Object has been locked.
obj->writers += 1; // one more pending writer
while (status == TAO_OK && ! rwlocked_object_is_writable(obj)) {
status = tao_condition_wait(&obj->base.cond, &obj->base.mutex);
}
obj->writers -= 1; // one less pending writer
if (status == TAO_OK) {
obj->users = -1;
}
if (tao_mutex_unlock(&obj->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
static inline tao_status rwlocked_object_try_wrlock(
const char* func,
tao_rwlocked_object* obj)
{
tao_status status = tao_mutex_try_lock(&obj->base.mutex);
if (status == TAO_OK) {
// Object has been locked.
if (rwlocked_object_is_writable(obj)) {
obj->users = -1;
} else {
status = TAO_TIMEOUT;
}
if (tao_mutex_unlock(&obj->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
static inline tao_status rwlocked_object_abstimed_wrlock(
const char* func,
tao_rwlocked_object* obj,
const tao_time* abstime)
{
tao_status status = tao_mutex_abstimed_lock(&obj->base.mutex, abstime);
if (status == TAO_OK) {
// Object has been locked.
obj->writers += 1; // one more pending writer
while (status == TAO_OK && ! rwlocked_object_is_writable(obj)) {
status = tao_condition_abstimed_wait(
&obj->base.cond, &obj->base.mutex, abstime);
}
obj->writers -= 1; // one less pending writer
if (status == TAO_OK) {
obj->users = -1;
}
if (tao_mutex_unlock(&obj->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
static inline tao_status rwlocked_object_timed_wrlock(
const char* func,
tao_rwlocked_object* obj,
double secs)
{
tao_time abstime;
switch (tao_get_absolute_timeout(&abstime, secs)) {
case TAO_TIMEOUT_PAST:
return TAO_TIMEOUT;
case TAO_TIMEOUT_NOW:
return rwlocked_object_try_wrlock(func, obj);
case TAO_TIMEOUT_FUTURE:
return rwlocked_object_abstimed_wrlock(func, obj, &abstime);
case TAO_TIMEOUT_NEVER:
return rwlocked_object_wrlock(func, obj);
default:
return TAO_ERROR;
}
}
#endif /* TAO_INLINE_FUNCS_H */
......@@ -9,14 +9,16 @@
//
// Copyright (C) 2019-2022, Éric Thiébaut.
#include "tao-remote-mirrors-private.h"
#include "tao-config.h"
#include "tao-errors.h"
#include "tao-generic.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdatomic.h>
#include "tao-basics.h"
#include "tao-config.h"
#include "tao-errors.h"
#include "tao-generic.h"
#include "tao-remote-mirrors-private.h"
// Offset of the layout indices in a remote mirror.
#define LAYOUT_OFFSET_IN_REMOTE_MIRROR \
......
......@@ -30,8 +30,6 @@
//
// Copyright (C) 2018-2021, Éric Thiébaut.
#include "./inline-funcs.h"
#ifndef TYPE
# error Macro TYPE must be defined
#endif
......@@ -244,6 +242,24 @@ tao_status TAO_XJOIN3(tao_,TYPE,_abstimed_wait_condition)(
#if IS_RWLOCKED_OBJECT
#ifndef RWLOCKED_OBJECT_IS_READABLE
#define RWLOCKED_OBJECT_IS_READABLE
static inline bool rwlocked_object_is_readable(
tao_rwlocked_object* obj)
{
return obj->users >= 0 && obj->writers == 0;
}
#endif
#ifndef RWLOCKED_OBJECT_IS_WRITABLE
#define RWLOCKED_OBJECT_IS_WRITABLE
static inline bool rwlocked_object_is_writable(
tao_rwlocked_object* obj)
{
return obj->users == 0;
}
#endif
tao_status TAO_XJOIN3(tao_,TYPE,_unlock)(
TAO_XJOIN2(tao_,TYPE)* obj)
{
......@@ -251,11 +267,40 @@ tao_status TAO_XJOIN3(tao_,TYPE,_unlock)(
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_ERROR;
}
return rwlocked_object_unlock(
__func__,
tao_rwlocked_object_cast(obj));
tao_rwlocked_object* root = tao_rwlocked_object_cast(obj);
tao_status status = tao_mutex_lock(&root->base.mutex);
if (status == TAO_OK) {
// Object has been locked.
bool notify = false;
int errcode = TAO_SUCCESS;
if (root->users == -1) {
// Remove the write lock and notify others.
root->users = 0;
notify = true;
} else if (root->users > 0) {
// Remove one read lock and notify others if are there no remaining
// readers.
root->users -= 1;
notify = (root->users == 0);
} else {
// Something wrong has been done.
errcode = (root->users == 0 ? TAO_NOT_LOCKED : TAO_CORRUPTED);
}
if (notify) {
status = tao_condition_broadcast(&root->base.cond);
}
if (tao_mutex_unlock(&root->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
if (errcode != TAO_SUCCESS) {
tao_store_error(__func__, errcode);
status = TAO_ERROR;
}
}
return status;
}
// Lock r/w object for read-only access.
tao_status TAO_XJOIN3(tao_,TYPE,_rdlock)(
TAO_XJOIN2(tao_,TYPE)* obj)
{
......@@ -263,64 +308,146 @@ tao_status TAO_XJOIN3(tao_,TYPE,_rdlock)(
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_ERROR;
}
return rwlocked_object_rdlock(__func__, tao_rwlocked_object_cast(obj));
tao_rwlocked_object* root = tao_rwlocked_object_cast(obj);
tao_status status = tao_mutex_lock(&root->base.mutex);
if (status == TAO_OK) {
// Object has been locked.
while (status == TAO_OK && ! rwlocked_object_is_readable(root)) {
status = tao_condition_wait(&root->base.cond, &root->base.mutex);
}
if (status == TAO_OK) {
root->users += 1;
}
if (tao_mutex_unlock(&root->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
tao_status TAO_XJOIN3(tao_,TYPE,_wrlock)(
tao_status TAO_XJOIN3(tao_,TYPE,_try_rdlock)(
TAO_XJOIN2(tao_,TYPE)* obj)
{
if (obj == NULL) {
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_ERROR;
}
return rwlocked_object_wrlock(__func__, tao_rwlocked_object_cast(obj));
tao_rwlocked_object* root = tao_rwlocked_object_cast(obj);
tao_status status = tao_mutex_try_lock(&root->base.mutex);
if (status == TAO_OK) {
// Object has been locked.
if (rwlocked_object_is_readable(root)) {
root->users += 1;
} else {
status = TAO_TIMEOUT;
}
if (tao_mutex_unlock(&root->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
tao_status TAO_XJOIN3(tao_,TYPE,_try_rdlock)(
TAO_XJOIN2(tao_,TYPE)* obj)
tao_status TAO_XJOIN3(tao_,TYPE,_abstimed_rdlock)(
TAO_XJOIN2(tao_,TYPE)* obj,
const tao_time* abstime)
{
if (obj == NULL) {
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_ERROR;
}
return rwlocked_object_try_rdlock(__func__, tao_rwlocked_object_cast(obj));
tao_rwlocked_object* root = tao_rwlocked_object_cast(obj);
tao_status status = tao_mutex_abstimed_lock(&root->base.mutex, abstime);
if (status == TAO_OK) {
// Object has been locked.
while (status == TAO_OK && ! rwlocked_object_is_readable(root)) {
status = tao_condition_abstimed_wait(
&root->base.cond, &root->base.mutex, abstime);
}
if (status == TAO_OK) {
root->users += 1;
}
if (tao_mutex_unlock(&root->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
tao_status TAO_XJOIN3(tao_,TYPE,_try_wrlock)(
TAO_XJOIN2(tao_,TYPE)* obj)
tao_status TAO_XJOIN3(tao_,TYPE,_timed_rdlock)(
TAO_XJOIN2(tao_,TYPE)* obj,
double secs)
{
if (obj == NULL) {
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_ERROR;
}
return rwlocked_object_try_wrlock(__func__, tao_rwlocked_object_cast(obj));
tao_time abstime;
switch (tao_get_absolute_timeout(&abstime, secs)) {
case TAO_TIMEOUT_PAST:
return TAO_TIMEOUT;
case TAO_TIMEOUT_NOW:
return TAO_XJOIN3(tao_,TYPE,_try_rdlock)(obj);
case TAO_TIMEOUT_FUTURE:
return TAO_XJOIN3(tao_,TYPE,_abstimed_rdlock)(obj, &abstime);
case TAO_TIMEOUT_NEVER:
return TAO_XJOIN3(tao_,TYPE,_rdlock)(obj);
default:
return TAO_ERROR;
}
}
tao_status TAO_XJOIN3(tao_,TYPE,_timed_rdlock)(
TAO_XJOIN2(tao_,TYPE)* obj,
double secs)
// Lock r/w object for read-write access.
tao_status TAO_XJOIN3(tao_,TYPE,_wrlock)(
TAO_XJOIN2(tao_,TYPE)* obj)
{
if (obj == NULL) {
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_ERROR;
}
return rwlocked_object_timed_rdlock(
__func__, tao_rwlocked_object_cast(obj), secs);
tao_rwlocked_object* root = tao_rwlocked_object_cast(obj);
tao_status status = tao_mutex_lock(&root->base.mutex);
if (status == TAO_OK) {
// Object has been locked.
root->writers += 1; // one more pending writer
while (status == TAO_OK && ! rwlocked_object_is_writable(root)) {
status = tao_condition_wait(&root->base.cond, &root->base.mutex);
}
root->writers -= 1; // one less pending writer
if (status == TAO_OK) {
root->users = -1;
}
if (tao_mutex_unlock(&root->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
tao_status TAO_XJOIN3(tao_,TYPE,_timed_wrlock)(
TAO_XJOIN2(tao_,TYPE)* obj,
double secs)
tao_status TAO_XJOIN3(tao_,TYPE,_try_wrlock)(
TAO_XJOIN2(tao_,TYPE)* obj)
{
if (obj == NULL) {
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_ERROR;
}
return rwlocked_object_timed_wrlock(
__func__, tao_rwlocked_object_cast(obj), secs);
tao_rwlocked_object* root = tao_rwlocked_object_cast(obj);
tao_status status = tao_mutex_try_lock(&root->base.mutex);
if (status == TAO_OK) {
// Object has been locked.
if (rwlocked_object_is_writable(root)) {
root->users = -1;
} else {
status = TAO_TIMEOUT;
}
if (tao_mutex_unlock(&root->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
tao_status TAO_XJOIN3(tao_,TYPE,_abstimed_rdlock)(
tao_status TAO_XJOIN3(tao_,TYPE,_abstimed_wrlock)(
TAO_XJOIN2(tao_,TYPE)* obj,
const tao_time* abstime)
{
......@@ -328,20 +455,47 @@ tao_status TAO_XJOIN3(tao_,TYPE,_abstimed_rdlock)(
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_ERROR;
}
return rwlocked_object_abstimed_rdlock(
__func__, tao_rwlocked_object_cast(obj), abstime);
tao_rwlocked_object* root = tao_rwlocked_object_cast(obj);
tao_status status = tao_mutex_abstimed_lock(&root->base.mutex, abstime);
if (status == TAO_OK) {
// Object has been locked.
root->writers += 1; // one more pending writer
while (status == TAO_OK && ! rwlocked_object_is_writable(root)) {
status = tao_condition_abstimed_wait(
&root->base.cond, &root->base.mutex, abstime);
}
root->writers -= 1; // one less pending writer
if (status == TAO_OK) {
root->users = -1;
}
if (tao_mutex_unlock(&root->base.mutex) != TAO_OK) {
status = TAO_ERROR;
}
}
return status;
}
tao_status TAO_XJOIN3(tao_,TYPE,_abstimed_wrlock)(
tao_status TAO_XJOIN3(tao_,TYPE,_timed_wrlock)(
TAO_XJOIN2(tao_,TYPE)* obj,
const tao_time* abstime)
double secs)
{
if (obj == NULL) {
tao_store_error(__func__, TAO_BAD_ADDRESS);
return TAO_ERROR;
}
return rwlocked_object_abstimed_wrlock(
__func__, tao_rwlocked_object_cast(obj), abstime);
tao_time abstime;
switch (tao_get_absolute_timeout(&abstime, secs)) {
case TAO_TIMEOUT_PAST:
return TAO_TIMEOUT;
case TAO_TIMEOUT_NOW:
return TAO_XJOIN3(tao_,TYPE,_try_wrlock)(obj);
case TAO_TIMEOUT_FUTURE:
return TAO_XJOIN3(tao_,TYPE,_abstimed_wrlock)(obj, &abstime);
case TAO_TIMEOUT_NEVER:
return TAO_XJOIN3(tao_,TYPE,_wrlock)(obj);
default:
return TAO_ERROR;
}
}
#endif /* IS_RWLOCKED_OBJECT */
......
......@@ -10,23 +10,25 @@
//
// Copyright (C) 2018-2022, Éric Thiébaut.
#include "tao-locks.h"
#include "tao-shared-memory.h"
#include "tao-shared-objects-private.h"
#include "tao-remote-objects-private.h"
#include "tao-rwlocked-objects-private.h"
#include "tao-generic.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include "./inline-funcs.h"
#include "tao-basics.h"
#include "tao-errors.h"
#include "tao-locks.h"
#include "tao-macros.h"
#include "tao-generic.h"
#include "tao-shared-memory.h"
#include "tao-shared-objects-private.h"
#include "tao-remote-objects-private.h"
#include "tao-rwlocked-objects-private.h"
//-----------------------------------------------------------------------------
// SHARED MEMORY
......
Supports Markdown
0% or .