introspection major optimization

This commit is contained in:
2022-04-15 01:31:22 +03:00
parent 6abec38856
commit 4b32101de6
7 changed files with 145 additions and 103 deletions

View File

@@ -17,13 +17,49 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piintrospection_containers.h"
PIIntrospectionContainersType::~PIIntrospectionContainersType() {
if (has_demangled) {
//free((void*)demangled);
has_demangled = false;
}
}
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
#include "piintrospection_containers.h"
#include "piintrospection_containers_p.h"
__PIINTROSPECTION_SINGLETON_CPP__(Containers)
#ifdef CC_GCC
# include <cxxabi.h>
const char * demangle(const char * name) {
int status = -4;
char * res = abi::__cxa_demangle(name, NULL, NULL, &status);
if (status == 0) return res;
return name;
}
#else
const char * demangle(const char * name) {return name;}
#endif
void PIIntrospectionContainersType::finish() {
inited = true;
if (!name) {
printf("[PIIntrospectionContainersType::finish] Null name!\n");
return;
}
size_t l = strlen(name);
if (l > 0)
id = piHashData((const uchar*)name, int(l));
demangled = demangle(name);
has_demangled = name != demangled;
//printf("create typeinfo for %s -> %s\n", name, demangled);
}
PIIntrospectionContainersInterface::PIIntrospectionContainersInterface() {
p = new PIIntrospectionContainers();
@@ -35,33 +71,33 @@ PIIntrospectionContainersInterface::~PIIntrospectionContainersInterface() {
}
void PIIntrospectionContainersInterface::containerNew(const char * tn, uint isz) {
p->containerNew(tn, isz);
void PIIntrospectionContainersInterface::containerNew(const PIIntrospectionContainersType & ti, uint isz) {
p->containerNew(ti, isz);
}
void PIIntrospectionContainersInterface::containerDelete(const char * tn) {
p->containerDelete(tn);
void PIIntrospectionContainersInterface::containerDelete(const PIIntrospectionContainersType & ti) {
p->containerDelete(ti);
}
void PIIntrospectionContainersInterface::containerAlloc(const char * tn, ullong cnt) {
p->containerAlloc(tn, cnt);
void PIIntrospectionContainersInterface::containerAlloc(const PIIntrospectionContainersType & ti, ullong cnt) {
p->containerAlloc(ti, cnt);
}
void PIIntrospectionContainersInterface::containerFree(const char * tn, ullong cnt) {
p->containerFree(tn, cnt);
void PIIntrospectionContainersInterface::containerFree(const PIIntrospectionContainersType & ti, ullong cnt) {
p->containerFree(ti, cnt);
}
void PIIntrospectionContainersInterface::containerUsed(const char * tn, ullong cnt) {
p->containerUsed(tn, cnt);
void PIIntrospectionContainersInterface::containerUsed(const PIIntrospectionContainersType & ti, ullong cnt) {
p->containerUsed(ti, cnt);
}
void PIIntrospectionContainersInterface::containerUnused(const char * tn, ullong cnt) {
p->containerUnused(tn, cnt);
void PIIntrospectionContainersInterface::containerUnused(const PIIntrospectionContainersType & ti, ullong cnt) {
p->containerUnused(ti, cnt);
}
#endif

View File

@@ -20,27 +20,48 @@
#ifndef PIINTROSPECTION_CONTAINERS_H
#define PIINTROSPECTION_CONTAINERS_H
#include "pibase.h"
struct PIP_EXPORT PIIntrospectionContainersType {
~PIIntrospectionContainersType();
void finish();
uint id = 0;
const char * name = nullptr;
const char * demangled = "?";
bool inited = false;
bool has_demangled = false;
};
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
#include "piintrospection_base.h"
class PIIntrospectionContainers;
#define PIINTROSPECTION_CONTAINERS (PIIntrospectionContainersInterface::instance())//(PIIntrospectionContainersInterface::instance())
template<typename T>
class PIIntrospectionContainersTypeInfo {
public:
static const PIIntrospectionContainersType & get() {
static PIIntrospectionContainersType ret = create();
return ret;
}
private:
static PIIntrospectionContainersType create() {
PIIntrospectionContainersType ret;
ret.name = __PIP_TYPENAME__(T);
ret.finish();
return ret;
}
};
#ifdef CC_GCC
# include <typeinfo>
# define _PIIS_TYPENAME_(t) typeid(t).name()
#else
# define _PIIS_TYPENAME_(t) ""
#endif
#define PIINTROSPECTION_CONTAINERS (PIIntrospectionContainersInterface::instance())
# define PIINTROSPECTION_CONTAINER_NEW(t, isz) PIINTROSPECTION_CONTAINERS->containerNew (_PIIS_TYPENAME_(t), isz);
# define PIINTROSPECTION_CONTAINER_DELETE(t) PIINTROSPECTION_CONTAINERS->containerDelete(_PIIS_TYPENAME_(t));
# define PIINTROSPECTION_CONTAINER_ALLOC(t, cnt) PIINTROSPECTION_CONTAINERS->containerAlloc (_PIIS_TYPENAME_(t), cnt);
# define PIINTROSPECTION_CONTAINER_FREE(t, cnt) PIINTROSPECTION_CONTAINERS->containerFree (_PIIS_TYPENAME_(t), cnt);
# define PIINTROSPECTION_CONTAINER_USED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUsed (_PIIS_TYPENAME_(t), cnt);
# define PIINTROSPECTION_CONTAINER_UNUSED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUnused(_PIIS_TYPENAME_(t), cnt);
# define PIINTROSPECTION_CONTAINER_NEW(t, isz) PIINTROSPECTION_CONTAINERS->containerNew (PIIntrospectionContainersTypeInfo<t>::get(), isz);
# define PIINTROSPECTION_CONTAINER_DELETE(t) PIINTROSPECTION_CONTAINERS->containerDelete(PIIntrospectionContainersTypeInfo<t>::get());
# define PIINTROSPECTION_CONTAINER_ALLOC(t, cnt) PIINTROSPECTION_CONTAINERS->containerAlloc (PIIntrospectionContainersTypeInfo<t>::get(), cnt);
# define PIINTROSPECTION_CONTAINER_FREE(t, cnt) PIINTROSPECTION_CONTAINERS->containerFree (PIIntrospectionContainersTypeInfo<t>::get(), cnt);
# define PIINTROSPECTION_CONTAINER_USED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUsed (PIIntrospectionContainersTypeInfo<t>::get(), cnt);
# define PIINTROSPECTION_CONTAINER_UNUSED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUnused(PIIntrospectionContainersTypeInfo<t>::get(), cnt);
class PIP_EXPORT PIIntrospectionContainersInterface {
@@ -49,12 +70,12 @@ class PIP_EXPORT PIIntrospectionContainersInterface {
public:
__PIINTROSPECTION_SINGLETON_H__(Containers)
void containerNew (const char * tn, uint isz);
void containerDelete(const char * tn);
void containerAlloc (const char * tn, ullong cnt);
void containerFree (const char * tn, ullong cnt);
void containerUsed (const char * tn, ullong cnt);
void containerUnused(const char * tn, ullong cnt);
void containerNew (const PIIntrospectionContainersType & ti, uint isz);
void containerDelete(const PIIntrospectionContainersType & ti);
void containerAlloc (const PIIntrospectionContainersType & ti, ullong cnt);
void containerFree (const PIIntrospectionContainersType & ti, ullong cnt);
void containerUsed (const PIIntrospectionContainersType & ti, ullong cnt);
void containerUnused(const PIIntrospectionContainersType & ti, ullong cnt);
PIIntrospectionContainers * p;
private:

View File

@@ -18,38 +18,23 @@
*/
#include "piintrospection_containers_p.h"
#include "piintrospection_containers.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::PIIntrospectionContainers() {
//printf("PIIntrospectionContainers %p\n", this);
}
void PIIntrospectionContainers::containerNew(const char * tn, uint isz) {
uint id = typeID(tn);
PIMutexLocker _ml(mutex);
void PIIntrospectionContainers::containerNew(const PIIntrospectionContainersType & ti, uint isz) {
PISpinlockLocker _ml(mutex);
//printf("containerNew lock\n");
std::string & n(typenames[id]);
_Type & d(data[id]);
if (n.empty()) {
n = tn;
d.id = id;
PIIntrospectionContainersType & t(types[ti.id]);
_Type & d(data[ti.id]);
if (!t.inited) {
t = ti;
d.id = ti.id;
d.item_size = isz;
}
d.count++;
@@ -57,49 +42,41 @@ void PIIntrospectionContainers::containerNew(const char * tn, uint isz) {
}
void PIIntrospectionContainers::containerDelete(const char * tn) {
PIMutexLocker _ml(mutex);
data[typeID(tn)].count--;
void PIIntrospectionContainers::containerDelete(const PIIntrospectionContainersType & ti) {
PISpinlockLocker _ml(mutex);
data[ti.id].count--;
}
void PIIntrospectionContainers::containerAlloc(const char * tn, ullong cnt) {
void PIIntrospectionContainers::containerAlloc(const PIIntrospectionContainersType & ti, ullong cnt) {
//printf(" alloc %s %d\n", tn, cnt);
if (cnt == 0) return;
PIMutexLocker _ml(mutex);
data[typeID(tn)].allocated += cnt;
PISpinlockLocker _ml(mutex);
data[ti.id].allocated += cnt;
}
void PIIntrospectionContainers::containerFree(const char * tn, ullong cnt) {
void PIIntrospectionContainers::containerFree(const PIIntrospectionContainersType & ti, ullong cnt) {
//printf(" free %s %d\n", tn, cnt);
if (cnt == 0) return;
PIMutexLocker _ml(mutex);
data[typeID(tn)].allocated -= cnt;
PISpinlockLocker _ml(mutex);
data[ti.id].allocated -= cnt;
}
void PIIntrospectionContainers::containerUsed(const char * tn, ullong cnt) {
void PIIntrospectionContainers::containerUsed(const PIIntrospectionContainersType & ti, ullong cnt) {
//printf(" used %s %d\n", tn, cnt);
if (cnt == 0) return;
PIMutexLocker _ml(mutex);
data[typeID(tn)].used += cnt;
PISpinlockLocker _ml(mutex);
data[ti.id].used += cnt;
}
void PIIntrospectionContainers::containerUnused(const char * tn, ullong cnt) {
void PIIntrospectionContainers::containerUnused(const PIIntrospectionContainersType & ti, 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));
PISpinlockLocker _ml(mutex);
data[ti.id].used -= cnt;
}
@@ -107,15 +84,15 @@ PIVector<PIIntrospectionContainers::TypeInfo> PIIntrospectionContainers::getInfo
PIVector<PIIntrospectionContainers::TypeInfo> ret;
mutex.lock();
std::map<uint, PIIntrospectionContainers::_Type> d = data;
std::map<uint, std::string> t = typenames;
std::map<uint, PIIntrospectionContainersType> t = types;
mutex.unlock();
ret.reserve(t.size());
for (typename std::map<uint, std::string>::const_iterator i = t.begin(); i != t.end(); ++i) {
for (typename std::map<uint, PIIntrospectionContainersType>::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());
ti.name = PIStringAscii(i->second.demangled);
}
return ret;
}

View File

@@ -20,7 +20,7 @@
#ifndef PIINTROSPECTION_CONTAINERS_P_H
#define PIINTROSPECTION_CONTAINERS_P_H
#include "pimutex.h"
#include "pispinlock.h"
#include <map>
#include <string>
#include "picrc.h"
@@ -32,14 +32,12 @@ public:
struct TypeInfo;
void containerNew (const char * tn, uint isz);
void containerDelete(const char * tn);
void containerAlloc (const char * tn, ullong cnt);
void containerFree (const char * tn, ullong cnt);
void containerUsed (const char * tn, ullong cnt);
void containerUnused(const char * tn, ullong cnt);
uint typeID(const char * tn);
void containerNew (const PIIntrospectionContainersType & ti, uint isz);
void containerDelete(const PIIntrospectionContainersType & ti);
void containerAlloc (const PIIntrospectionContainersType & ti, ullong cnt);
void containerFree (const PIIntrospectionContainersType & ti, ullong cnt);
void containerUsed (const PIIntrospectionContainersType & ti, ullong cnt);
void containerUnused(const PIIntrospectionContainersType & ti, ullong cnt);
PIVector<TypeInfo> getInfo() const;
@@ -63,8 +61,8 @@ public:
};
std::map<uint, _Type> data;
std::map<uint, std::string> typenames;
mutable PIMutex mutex;
std::map<uint, PIIntrospectionContainersType> types;
mutable PISpinlock mutex;
};
PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v);

View File

@@ -20,15 +20,24 @@
#ifndef PIINTROSPECTION_SERVER_H
#define PIINTROSPECTION_SERVER_H
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
#ifdef DOXYGEN
//! \~\ingroup Introspection
//! \~english Start introspection server with name "name"
//! \~russian Запускает сервер интроспекции с именем "name"
# define PIINTROSPECTION_START(name)
#else
# if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
#include "pipeer.h"
class PIIntrospectionServer;
class PISystemMonitor;
# define PIINTROSPECTION_SERVER (PIIntrospectionServer::instance())
# define PIINTROSPECTION_START(name) PIINTROSPECTION_SERVER->start(#name);
# define PIINTROSPECTION_SERVER (PIIntrospectionServer::instance())
# define PIINTROSPECTION_START(name) PIINTROSPECTION_SERVER->start(#name);
class PIP_EXPORT PIIntrospectionServer: public PIPeer {
PIOBJECT_SUBCLASS(PIIntrospectionServer, PIPeer)
@@ -53,8 +62,10 @@ private:
};
#else
# define PIINTROSPECTION_START(name)
#endif
# else
# define PIINTROSPECTION_START(name)
# endif
#endif // DOXYGEN
#endif // PIINTROSPECTION_SERVER_H

View File

@@ -144,9 +144,8 @@ PIResourcesStorage * PIResourcesStorage::instance() {
PIByteArray & operator <<(PIByteArray & b, const PIResourcesStorage::__RCEntry & v) {
PIChunkStream cs;
cs << cs.chunk(1, v.section) << cs.chunk(2, v.name) << cs.chunk(3, v.file)
<< cs.chunk(4, v.size) << cs.chunk(5, v.offset) << cs.chunk(6, v.flags)
<< cs.chunk(7, v.alias);
cs.add(1, v.section).add(2, v.name).add(3, v.file).add(4, v.size)
.add(5, v.offset).add(6, v.flags).add(7, v.alias);
b << cs.data();
return b;
}

View File

@@ -18,8 +18,8 @@
*/
//! \defgroup Thread
//! \~\brief
//! \~english Multithreading support.
//! \~russian Поддержка многопоточности.
//! \~english Multithreading support
//! \~russian Поддержка многопоточности
//!
//! \~\details
//! \~english \section cmake_module Building with CMake