140 lines
3.7 KiB
C++
140 lines
3.7 KiB
C++
/*
|
|
PIP - Platform Independent Primitives
|
|
Introspection module - implementation of containers
|
|
Ivan Pelipenko peri4ko@yandex.ru
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "piintrospection_containers_p.h"
|
|
#include <stdio.h>
|
|
|
|
#ifdef CC_GCC
|
|
# include <cxxabi.h>
|
|
const PIString demangle(const char * name) {
|
|
int status = -4;
|
|
char * res = abi::__cxa_demangle(name, NULL, NULL, &status);
|
|
PIString ret((status == 0) ? res : name);
|
|
free(res);
|
|
return ret;
|
|
}
|
|
#else
|
|
const PIString demangle(const char * name) {return PIString(name);}
|
|
#endif
|
|
|
|
|
|
PIIntrospectionContainers::_Type::_Type() {
|
|
id = count = item_size = 0u;
|
|
allocated = used = 0U;
|
|
}
|
|
|
|
|
|
|
|
|
|
PIIntrospectionContainers::PIIntrospectionContainers() {
|
|
//printf("PIIntrospectionContainers %p\n", this);
|
|
}
|
|
|
|
|
|
void PIIntrospectionContainers::containerNew(const char * tn, uint isz) {
|
|
uint id = typeID(tn);
|
|
PIMutexLocker _ml(mutex);
|
|
//printf("containerNew lock\n");
|
|
std::string & n(typenames[id]);
|
|
_Type & d(data[id]);
|
|
if (n.empty()) {
|
|
n = tn;
|
|
d.id = id;
|
|
d.item_size = isz;
|
|
}
|
|
d.count++;
|
|
//printf("containerNew unlock\n");
|
|
}
|
|
|
|
|
|
void PIIntrospectionContainers::containerDelete(const char * tn) {
|
|
PIMutexLocker _ml(mutex);
|
|
data[typeID(tn)].count--;
|
|
}
|
|
|
|
|
|
void PIIntrospectionContainers::containerAlloc(const char * tn, ullong cnt) {
|
|
//printf(" alloc %s %d\n", tn, cnt);
|
|
if (cnt == 0) return;
|
|
PIMutexLocker _ml(mutex);
|
|
data[typeID(tn)].allocated += cnt;
|
|
}
|
|
|
|
|
|
void PIIntrospectionContainers::containerFree(const char * tn, ullong cnt) {
|
|
//printf(" free %s %d\n", tn, cnt);
|
|
if (cnt == 0) return;
|
|
PIMutexLocker _ml(mutex);
|
|
data[typeID(tn)].allocated -= cnt;
|
|
}
|
|
|
|
|
|
void PIIntrospectionContainers::containerUsed(const char * tn, ullong cnt) {
|
|
//printf(" used %s %d\n", tn, cnt);
|
|
if (cnt == 0) return;
|
|
PIMutexLocker _ml(mutex);
|
|
data[typeID(tn)].used += cnt;
|
|
}
|
|
|
|
|
|
void PIIntrospectionContainers::containerUnused(const char * tn, ullong cnt) {
|
|
//printf("unused %s %d\n", tn, cnt);
|
|
if (cnt == 0) return;
|
|
PIMutexLocker _ml(mutex);
|
|
data[typeID(tn)].used -= cnt;
|
|
}
|
|
|
|
|
|
uint PIIntrospectionContainers::typeID(const char * tn) {
|
|
if (!tn) return 0u;
|
|
size_t l = strlen(tn);
|
|
if (l == 0) return 0u;
|
|
return piHashData((const uchar*)tn, int(l));
|
|
}
|
|
|
|
|
|
PIVector<PIIntrospectionContainers::TypeInfo> PIIntrospectionContainers::getInfo() const {
|
|
PIVector<PIIntrospectionContainers::TypeInfo> ret;
|
|
mutex.lock();
|
|
std::map<uint, PIIntrospectionContainers::_Type> d = data;
|
|
std::map<uint, std::string> t = typenames;
|
|
mutex.unlock();
|
|
ret.reserve(t.size());
|
|
for (typename std::map<uint, std::string>::const_iterator i = t.begin(); i != t.end(); ++i) {
|
|
ret.push_back(TypeInfo());
|
|
TypeInfo & ti(ret.back());
|
|
_Type & _t(d[i->first]);
|
|
memcpy((void*)&ti, (const void*)&_t, sizeof(_t));
|
|
ti.name = demangle(i->second.c_str());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
|
|
PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v) {
|
|
s << PIByteArray::RawData(&v, sizeof(PIIntrospectionContainers::_Type)) << v.name;
|
|
return s;
|
|
}
|
|
PIByteArray & operator >>(PIByteArray & s, PIIntrospectionContainers::TypeInfo & v) {
|
|
s >> PIByteArray::RawData(&v, sizeof(PIIntrospectionContainers::_Type)) >> v.name;
|
|
return s;
|
|
}
|