Ejemplo n.º 1
0
static SINT64 get_parameter(const SCHAR** ptr)
{
/**************************************
 *
 *	g e t _ p a r a m e t e r
 *
 **************************************
 *
 * Functional description
 *	Get a parameter (length is encoded), convert to internal form,
 *	and return.
 *
 **************************************/
	SSHORT l = *(*ptr)++;
	l += (*(*ptr)++) << 8;
	const SINT64 parameter = isc_portable_integer(reinterpret_cast<const ISC_UCHAR*>(*ptr), l);
	*ptr += l;

	return parameter;
}
Ejemplo n.º 2
0
void Why::UtilInterface::getPerfCounters(Firebird::CheckStatusWrapper* status,
	Firebird::IAttachment* att, const char* countersSet, ISC_INT64* counters)
{
	try
	{
		// Parse countersSet
		unsigned cntLink[TOTAL_COUNTERS];
		memset(cntLink, 0xFF, sizeof cntLink);
		Firebird::string dupSet(countersSet);
		char* set = dupSet.begin();
		char* save = NULL;
		const char* delim = " \t,;";
		unsigned typeMask = 0;
		unsigned n = 0;
		UCHAR info[TOTAL_COUNTERS];		// will never use all, but do not care about few bytes
		UCHAR* pinfo = info;

#ifdef WIN_NT
#define strtok_r strtok_s
#endif

		for (char* nm = strtok_r(set, delim, &save); nm; nm = strtok_r(NULL, delim, &save))
		{
			Firebird::NoCaseString name(nm);

			for (unsigned i = 0; i < TOTAL_COUNTERS; ++i)
			{
				if (name == knownCounters[i].name)
				{
					if (cntLink[i] != ~0u)
						(Firebird::Arg::Gds(isc_random) << "Duplicated name").raise();	//report name & position

					cntLink[i] = n++;
					typeMask |= knownCounters[i].type;

					if (knownCounters[i].type == CNT_DB_INFO)
						*pinfo++ = knownCounters[i].code;

					goto found;
				}
			}
			(Firebird::Arg::Gds(isc_random) << "Unknown name").raise();	//report name & position
found:		;
		}

#ifdef WIN_NT
#undef strtok_r
#endif

		// Force reset counters
		memset(counters, 0, n * sizeof(ISC_INT64));

		// Fill time counters
		if (typeMask & CNT_TIMER)
		{
			SINT64 tr = fb_utils::query_performance_counter() * 1000 / fb_utils::query_performance_frequency();
			SINT64 uTime, sTime;
			fb_utils::get_process_times(uTime, sTime);

			for (unsigned i = 0; i < TOTAL_COUNTERS; ++i)
			{
				if (cntLink[i] == ~0u)
					continue;

				if (knownCounters[i].type == CNT_TIMER)
				{
					clock_t v = 0;

					switch(knownCounters[i].code)
					{
					case CNT_TIME_REAL:
						v = tr;
						break;
					case CNT_TIME_USER:
						v = uTime;
						break;
					case CNT_TIME_SYSTEM:
						v = sTime;
						break;
					default:
						fb_assert(false);
						break;
					}

					counters[cntLink[i]] = v;
				}
			}
		}

		// Fill DB counters
		if (typeMask & CNT_DB_INFO)
		{
			UCHAR buffer[BUFFER_LARGE];
			att->getInfo(status, pinfo - info, info, sizeof(buffer), buffer);
			if (status->getState() & Firebird::IStatus::STATE_ERRORS)
				return;

			const UCHAR* p = buffer;

			while (true)
			{
				SINT64 v = 0;
				UCHAR ipb = *p++;

				switch (ipb)
				{
				case isc_info_reads:
				case isc_info_writes:
				case isc_info_marks:
				case isc_info_fetches:
				case isc_info_num_buffers:
				case isc_info_page_size:
				case isc_info_current_memory:
				case isc_info_max_memory:
					v = get_parameter(&p);
					break;

				case isc_info_end:
					goto parsed;

				case isc_info_error:
				{
					const SINT64 temp = isc_portable_integer(p, 2);
					fb_assert(temp <= MAX_SSHORT);
					p += temp + 2;
					continue;
				}

				default:
					(Firebird::Arg::Gds(isc_random) << "Unknown info code").raise();   //report char code
				}

				for (unsigned i = 0; i < TOTAL_COUNTERS; ++i)
				{
					if (knownCounters[i].type == CNT_DB_INFO && knownCounters[i].code == ipb)
					{
						if (cntLink[i] != ~0u)
							counters[cntLink[i]] = v;

						break;
					}
				}
			}
parsed:		;
		}
	}
	catch (const Firebird::Exception& ex)
	{
		ex.stuffException(status);
	}
}