diff --git a/libs/main/introspection/piintrospection_containers.cpp b/libs/main/introspection/piintrospection_containers.cpp index 3d3f9aa3..01eb148c 100644 --- a/libs/main/introspection/piintrospection_containers.cpp +++ b/libs/main/introspection/piintrospection_containers.cpp @@ -17,13 +17,49 @@ along with this program. If not, see . */ +#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 +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 diff --git a/libs/main/introspection/piintrospection_containers.h b/libs/main/introspection/piintrospection_containers.h index 7af41f50..8151c072 100644 --- a/libs/main/introspection/piintrospection_containers.h +++ b/libs/main/introspection/piintrospection_containers.h @@ -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 +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 -# 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::get(), isz); +# define PIINTROSPECTION_CONTAINER_DELETE(t) PIINTROSPECTION_CONTAINERS->containerDelete(PIIntrospectionContainersTypeInfo::get()); +# define PIINTROSPECTION_CONTAINER_ALLOC(t, cnt) PIINTROSPECTION_CONTAINERS->containerAlloc (PIIntrospectionContainersTypeInfo::get(), cnt); +# define PIINTROSPECTION_CONTAINER_FREE(t, cnt) PIINTROSPECTION_CONTAINERS->containerFree (PIIntrospectionContainersTypeInfo::get(), cnt); +# define PIINTROSPECTION_CONTAINER_USED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUsed (PIIntrospectionContainersTypeInfo::get(), cnt); +# define PIINTROSPECTION_CONTAINER_UNUSED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUnused(PIIntrospectionContainersTypeInfo::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: diff --git a/libs/main/introspection/piintrospection_containers_p.cpp b/libs/main/introspection/piintrospection_containers_p.cpp index a122592b..039e461b 100644 --- a/libs/main/introspection/piintrospection_containers_p.cpp +++ b/libs/main/introspection/piintrospection_containers_p.cpp @@ -18,38 +18,23 @@ */ #include "piintrospection_containers_p.h" +#include "piintrospection_containers.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::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::getInfo PIVector ret; mutex.lock(); std::map d = data; - std::map t = typenames; + std::map t = types; mutex.unlock(); ret.reserve(t.size()); - for (typename std::map::const_iterator i = t.begin(); i != t.end(); ++i) { + 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()); + ti.name = PIStringAscii(i->second.demangled); } return ret; } diff --git a/libs/main/introspection/piintrospection_containers_p.h b/libs/main/introspection/piintrospection_containers_p.h index f8d80444..cd066d00 100644 --- a/libs/main/introspection/piintrospection_containers_p.h +++ b/libs/main/introspection/piintrospection_containers_p.h @@ -20,7 +20,7 @@ #ifndef PIINTROSPECTION_CONTAINERS_P_H #define PIINTROSPECTION_CONTAINERS_P_H -#include "pimutex.h" +#include "pispinlock.h" #include #include #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 getInfo() const; @@ -63,8 +61,8 @@ public: }; std::map data; - std::map typenames; - mutable PIMutex mutex; + std::map types; + mutable PISpinlock mutex; }; PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v); diff --git a/libs/main/introspection/piintrospection_server.h b/libs/main/introspection/piintrospection_server.h index 2fc1f31b..8c1c1a8e 100644 --- a/libs/main/introspection/piintrospection_server.h +++ b/libs/main/introspection/piintrospection_server.h @@ -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 diff --git a/libs/main/resources/piresourcesstorage.cpp b/libs/main/resources/piresourcesstorage.cpp index fd6e20eb..054e900c 100644 --- a/libs/main/resources/piresourcesstorage.cpp +++ b/libs/main/resources/piresourcesstorage.cpp @@ -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; } diff --git a/libs/main/thread/pithreadmodule.h b/libs/main/thread/pithreadmodule.h index bb7649bb..8e069d6d 100644 --- a/libs/main/thread/pithreadmodule.h +++ b/libs/main/thread/pithreadmodule.h @@ -18,8 +18,8 @@ */ //! \defgroup Thread //! \~\brief -//! \~english Multithreading support. -//! \~russian Поддержка многопоточности. +//! \~english Multithreading support +//! \~russian Поддержка многопоточности //! //! \~\details //! \~english \section cmake_module Building with CMake