blob: 6e1738f48b598a6753bddc676ebd9e65c88cef36 [file]
/** @file
A brief file description
@section license License
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#define _s_impl
#include "Stats.h"
#include "ink_mutex.h"
StatDescriptor
StatDescriptor::all_stats[StatDescriptor::MAX_NUM_STATS];
RecRawStatBlock *
StatDescriptor::g_stat_block;
StatDescriptor
G_NULL_STAT;
volatile int
StatDescriptor::top_stat = 0;
ink_mutex
g_flt_mux;
ink_mutex
g_cpl_mux;
// Main.cc call-in point
void
init_inkapi_stat_system()
{
StatDescriptor::initialize();
ink_mutex_init(&g_flt_mux, "proxy/stat floating pt. mutex");
ink_mutex_init(&g_cpl_mux, "proxy/stat coupled stat mutex");
}
void
StatDescriptor::initialize()
{
// g_stat_block = RecAllocateRawStatBlock(MAX_NUM_STATS);
// ink_release_assert (g_stat_block);
}
RecData StatDescriptor::update_value()
{
RecData
retv;
if (m_magic == NULL_VALUE || m_magic == SHALLOW_COPY || m_magic == IN_ERROR) {
return m_value;;
}
ink_release_assert(m_id >= 0 && m_id < MAX_NUM_STATS);
int
rc = REC_ERR_OKAY;
switch (m_type) {
case RECD_INT:
rc = RecGetRecordInt(m_name, &retv.rec_int);
m_value = retv;
break;
case RECD_FLOAT:
rc = RecGetRecordFloat(m_name, &retv.rec_float);
m_value = retv;
break;
default:
m_magic = IN_ERROR;
ink_release_assert(!"Impossible type");
return m_value;
}
if (rc != REC_ERR_OKAY) {
m_magic = IN_ERROR;
}
return retv;
}
StatDescriptor *
StatDescriptor::CreateDescriptor(const char *prefix, char *name, size_t name_len, ink64 init_value)
{
char *t = name;
char tv[128];
ink_debug_assert(prefix && name);
if (!name || !prefix)
// return &G_NULL_STAT;
return NULL;
if (prefix) {
t = &tv[0];
int pln = strlen(prefix);
int nln = strlen(name);
if (pln + nln > 126)
return NULL; // return &G_NULL_STAT;
ink_strncpy(t, prefix, name_len);
t[pln] = '.';
ink_strncpy(t + pln + 1, name, name_len - pln - 1);
}
return CreateDescriptor(t, init_value);
}
StatDescriptor *
StatDescriptor::CreateDescriptor(const char *prefix, char *name, size_t name_len, float init_value)
{
char *t = name;
char tv[128];
ink_debug_assert(prefix && name);
if (!name || !prefix)
return NULL;
// return &G_NULL_STAT;
if (prefix) {
t = &tv[0];
int pln = strlen(prefix);
int nln = strlen(name);
if (pln + nln > 126)
return NULL; // return &G_NULL_STAT;
ink_strncpy(t, prefix, name_len);
t[pln] = '.';
ink_strncpy(t + pln + 1, name, name_len - pln - 1);
}
return CreateDescriptor(t, init_value);
}
StatDescriptor *
StatDescriptor::CreateDescriptor(const char *name, ink64 init_value)
{
int n_stat = ink_atomic_increment(&top_stat, 1);
RecDataT dt;
if (n_stat >= StatDescriptor::MAX_NUM_STATS) {
Warning("Plugin stat space exhausted");
// return &G_NULL_STAT;
return NULL;
}
else if (RecGetRecordDataType((char *) name, &dt) == REC_ERR_OKAY) {
Debug("sdk_stats", "Attempt to re-register statistic '%s'", name);
// return &G_NULL_STAT;
return NULL;
}
else {
StatDescriptor & ref = all_stats[n_stat];
ref.m_id = n_stat;
ink_assert(ref.m_name == NULL);
size_t len = strlen(name) + 1;
ref.m_name = new char[len];
ink_strncpy(ref.m_name, name, len);
ref.m_type = RECD_INT;
ref.m_value.rec_int = init_value;
ref.m_magic = ALIVE;
int rc = RecRegisterStatInt(RECT_PLUGIN, ref.m_name,
init_value, RECP_NON_PERSISTENT);
if (rc == REC_ERR_FAIL) {
ref.m_magic = IN_ERROR;
}
return &all_stats[n_stat];
}
}
StatDescriptor *
StatDescriptor::CreateDescriptor(const char *name, float init_value)
{
int n_stat = ink_atomic_increment(&top_stat, 1);
RecDataT dt;
if (n_stat >= StatDescriptor::MAX_NUM_STATS) {
Warning("Plugin stat space exhausted");
// return &G_NULL_STAT;
return NULL;
}
else if (RecGetRecordDataType((char *) name, &dt) == REC_ERR_OKAY) {
Debug("sdk_stats", "Attempt to re-register statistic '%s'", name);
// return &G_NULL_STAT;
return NULL;
}
else {
StatDescriptor & ref = all_stats[n_stat];
ref.m_id = n_stat;
ink_assert(ref.m_name == NULL);
size_t len = strlen(name) + 1;
ref.m_name = new char[len];
ink_strncpy(ref.m_name, name, len);
ref.m_type = RECD_FLOAT;
ref.m_value.rec_float = init_value;
ref.m_magic = ALIVE;
int rc = RecRegisterStatFloat(RECT_PLUGIN, ref.m_name,
init_value, RECP_NON_PERSISTENT);
if (rc == REC_ERR_FAIL) {
ref.m_magic = IN_ERROR;
}
return &all_stats[n_stat];
}
}
void
StatDescriptor::set(ink64 val)
{
if (m_magic == SHALLOW_COPY) {
ink_atomic_swap64(&m_value.rec_int, val);
} else if (m_magic == NULL_VALUE || m_magic == IN_ERROR) {
m_magic = IN_ERROR;
} else {
int rc = RecSetRecordInt(m_name, val);
if (rc == REC_ERR_FAIL) {
m_magic = IN_ERROR;
}
}
}
void
StatDescriptor::set(float val)
{
if (m_magic == SHALLOW_COPY) {
ink_mutex_acquire(&g_flt_mux);
m_value.rec_float = val;
ink_mutex_release(&g_flt_mux);
} else if (m_magic == NULL_VALUE || m_magic == IN_ERROR) {
m_magic = IN_ERROR;
} else {
int rc = RecSetRecordFloat(m_name, val);
if (rc == REC_ERR_FAIL) {
m_magic = IN_ERROR;
}
}
}
void
StatDescriptor::add(ink64 val)
{
if (m_magic == SHALLOW_COPY) {
ink_atomic_increment64(&m_value.rec_int, val);
} else if (m_magic == NULL_VALUE || m_magic == IN_ERROR) {
m_magic = IN_ERROR;
} else {
RecInt v;
ink_mutex_acquire(&g_flt_mux);
int rc = RecGetRecordInt(m_name, &v);
if (rc == REC_ERR_OKAY) {
rc = RecSetRecordInt(m_name, v + val);
}
ink_mutex_release(&g_flt_mux);
if (rc == REC_ERR_FAIL) {
m_magic = IN_ERROR;
}
}
}
void
StatDescriptor::add(float val)
{
if (m_magic == SHALLOW_COPY) {
ink_mutex_acquire(&g_flt_mux);
m_value.rec_float += val;
ink_mutex_release(&g_flt_mux);
} else if (m_magic == NULL_VALUE || m_magic == IN_ERROR) {
m_magic = IN_ERROR;
} else {
RecFloat v;
ink_mutex_acquire(&g_flt_mux);
int rc = RecGetRecordFloat(m_name, &v);
if (rc == REC_ERR_OKAY) {
rc = RecSetRecordFloat(m_name, v + val);
}
ink_mutex_release(&g_flt_mux);
if (rc == REC_ERR_FAIL) {
m_magic = IN_ERROR;
}
}
}
void
StatDescriptor::commit()
{
if (m_magic == SHALLOW_COPY) {
if (m_type == RECD_INT) {
int rc = RecSetRecordInt(m_name, m_value.rec_int);
if (rc == REC_ERR_FAIL) {
m_magic = IN_ERROR;
}
} else {
int rc = RecSetRecordFloat(m_name, m_value.rec_float);
if (rc == REC_ERR_FAIL) {
m_magic = IN_ERROR;
}
}
} else {
// Warning ("Stat update failed");
ink_debug_assert(!"broken");
return;
}
}