/* 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 . */ #include "piintrospection_containers_p.h" #include #ifdef CC_GCC # include 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::getInfo() const { PIVector ret; mutex.lock(); std::map d = data; std::map t = typenames; mutex.unlock(); ret.reserve(t.size()); for (typename std::map::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; }