blob: b10c6f19404d230d7fdf816dc20ee1ce8498a13c [file] [log] [blame]
/** @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 "ink_config.h"
#include "Stats.h"
#include "P_EventSystem.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, int64_t 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, int64_t 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;
if (RecRegisterStatInt(RECT_PLUGIN, ref.m_name, init_value, RECP_NON_PERSISTENT) == 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 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;
if (RecRegisterStatFloat(RECT_PLUGIN, ref.m_name, init_value, RECP_NON_PERSISTENT) == REC_ERR_FAIL) {
ref.m_magic = IN_ERROR;
}
return &all_stats[n_stat];
}
}
void
StatDescriptor::set(int64_t 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 {
if (RecSetRecordInt(m_name, val) == 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 {
if (RecSetRecordFloat(m_name, val) == REC_ERR_FAIL) {
m_magic = IN_ERROR;
}
}
}
void
StatDescriptor::add(int64_t 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) {
if (RecSetRecordInt(m_name, m_value.rec_int) == REC_ERR_FAIL) {
m_magic = IN_ERROR;
}
} else {
if (RecSetRecordFloat(m_name, m_value.rec_float) == REC_ERR_FAIL) {
m_magic = IN_ERROR;
}
}
} else {
// Warning ("Stat update failed");
ink_debug_assert(!"broken");
return;
}
}