145 lines
4.9 KiB
C
145 lines
4.9 KiB
C
/*************************************************************************\
|
|
* Copyright (c) 2010 Brookhaven National Laboratory.
|
|
* Copyright (c) 2010 Helmholtz-Zentrum Berlin
|
|
* fuer Materialien und Energie GmbH.
|
|
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
|
* National Laboratory.
|
|
* Copyright (c) 2002 The Regents of the University of California, as
|
|
* Operator of Los Alamos National Laboratory.
|
|
* SPDX-License-Identifier: EPICS
|
|
* EPICS BASE is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
\*************************************************************************/
|
|
/*
|
|
* Author: Jeffrey O. Hill <johill@lanl.gov>
|
|
*
|
|
* Ralph Lange <Ralph.Lange@bessy.de>
|
|
*/
|
|
|
|
#ifndef INCLdb_field_logh
|
|
#define INCLdb_field_logh
|
|
|
|
#include <epicsTime.h>
|
|
#include <epicsTypes.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
* Simple native types (anything which is not a string or an array for
|
|
* now) logged by db_post_events() for reliable interprocess communication.
|
|
* (for other types they get whatever happens to be there when the lower
|
|
* priority task pending on the event queue wakes up). Strings would slow down
|
|
* events for more reasonable size values. DB fields of native type string
|
|
* will most likely change infrequently.
|
|
*
|
|
* Strings can be added to the set of types for which updates will be queued
|
|
* by defining the macro DB_EVENT_LOG_STRINGS. The code in db_add_event()
|
|
* will adjust automatically, it just compares field sizes.
|
|
*/
|
|
union native_value {
|
|
epicsInt8 dbf_char;
|
|
epicsInt16 dbf_short;
|
|
epicsEnum16 dbf_enum;
|
|
epicsInt32 dbf_long;
|
|
epicsFloat32 dbf_float;
|
|
epicsFloat64 dbf_double;
|
|
#ifdef DB_EVENT_LOG_STRINGS
|
|
char dbf_string[MAX_STRING_SIZE];
|
|
#endif
|
|
};
|
|
|
|
/*
|
|
* structure to log the state of a data base field at the time
|
|
* an event is triggered.
|
|
*/
|
|
struct db_field_log;
|
|
typedef void (dbfl_freeFunc)(struct db_field_log *pfl);
|
|
|
|
/*
|
|
* A db_field_log has one of two types:
|
|
*
|
|
* dbfl_type_ref - Reference to value
|
|
* Used for variable size (array) data types. Meta-data
|
|
* is stored in the field log, but value data is stored externally.
|
|
* Only the dbfl_ref side of the data union is valid.
|
|
*
|
|
* dbfl_type_val - Internal value
|
|
* Used to store small scalar data. Meta-data and value are
|
|
* present in this structure and no external references are used.
|
|
* Only the dbfl_val side of the data union is valid.
|
|
*/
|
|
typedef enum dbfl_type {
|
|
dbfl_type_val,
|
|
dbfl_type_ref
|
|
} dbfl_type;
|
|
|
|
/* Context of db_field_log: event = subscription update, read = read reply */
|
|
typedef enum dbfl_context {
|
|
dbfl_context_read,
|
|
dbfl_context_event
|
|
} dbfl_context;
|
|
|
|
#define dbflTypeStr(t) (t==dbfl_type_val?"val":"ref")
|
|
|
|
struct dbfl_val {
|
|
union native_value field; /* Field value */
|
|
};
|
|
|
|
/* External data reference.
|
|
* If dtor is provided then it should be called when the referenced
|
|
* data is no longer needed. This is done automatically by
|
|
* db_delete_field_log(). Any code which changes a dbfl_type_ref
|
|
* field log to another type, or to reference different data,
|
|
* must explicitly call the dtor function.
|
|
* If the dtor is NULL and no_elements > 0, then this means the array
|
|
* data is still owned by a record. See the macro dbfl_has_copy below.
|
|
*/
|
|
struct dbfl_ref {
|
|
dbfl_freeFunc *dtor; /* Callback to free filter-allocated resources */
|
|
void *pvt; /* Private pointer */
|
|
void *field; /* Field value */
|
|
};
|
|
|
|
/*
|
|
* Note that field_size may be larger than MAX_STRING_SIZE.
|
|
*/
|
|
typedef struct db_field_log {
|
|
unsigned int type:1; /* type (union) selector */
|
|
/* ctx is used for all types */
|
|
unsigned int ctx:1; /* context (operation type) */
|
|
/* the following are used for value and reference types */
|
|
epicsTimeStamp time; /* Time stamp */
|
|
unsigned short stat; /* Alarm Status */
|
|
unsigned short sevr; /* Alarm Severity */
|
|
short field_type; /* DBF type of data */
|
|
short field_size; /* Size of a single element */
|
|
long no_elements; /* No of valid array elements */
|
|
union {
|
|
struct dbfl_val v;
|
|
struct dbfl_ref r;
|
|
} u;
|
|
} db_field_log;
|
|
|
|
/*
|
|
* Whether a db_field_log* owns the field data. If this is the case, then the
|
|
* db_field_log is fully decoupled from the record: there is no need to lock
|
|
* the record when accessing the data, nor to call any rset methods (like
|
|
* get_array_info) because this has already been done when we made the copy. A
|
|
* special case here is that of no (remaining) data (i.e. no_elements==0). In
|
|
* this case, making a copy is redundant, so we have no dtor. But conceptually
|
|
* the db_field_log still owns the (empty) data.
|
|
*/
|
|
#define dbfl_has_copy(p)\
|
|
((p) && ((p)->type==dbfl_type_val || (p)->u.r.dtor || (p)->no_elements==0))
|
|
|
|
#define dbfl_pfield(p)\
|
|
((p)->type==dbfl_type_val ? &p->u.v.field : p->u.r.field)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /*INCLdb_field_logh*/
|