示例#1
0
        public Sampler(long timeBase, int divisor, int samplerRate, int maxCallstackDepth, int startDelay, int bufferLength = 8192)
        {
            mTimeBase          = timeBase;
            mDivisor           = divisor;
            mSamplerRate       = samplerRate;
            mMaxCallstackDepth = maxCallstackDepth;
            mStartDelay        = startDelay;

            // allocate buffers
            mReadData = new Address[bufferLength];
            mData     = new Address[bufferLength];

            // allocate reusable sample class
            mSample                  = new Protocol.Sampler_sample();
            mSample.ticktimes        = new _root.Vector <double>();
            mSample.callstack        = new _root.Vector <uint>();
            mSample.callstack.length = (uint)maxCallstackDepth;
            mSample.callstack.length = 0;

            // save target thread id
            mTargetThread = mach_thread_self();

            // setup architecture specific settings
            var arch = flash.system.Capabilities.cpuArchitecture;

            switch (arch)
            {
            case "ARM":
                mThreadStateLength = 17;
                mThreadStateFlavor = 1;
                mRegisterPC        = 15;
                mRegisterBP        = 7;
                break;

            case "x86":
                mThreadStateLength = 32;
                mThreadStateFlavor = 1;
                mRegisterPC        = 10;
                mRegisterBP        = 6;
                break;

            default:
                Console.WriteLine("Telemetry: Architecture not supported for sampling");
                return;
            }

            // start sampler thread
            mSamplerThread          = new Thread(SamplerThreadFunc);
            mSamplerThread.Priority = ThreadPriority.Highest;
            mSamplerThread.Start();
            Console.WriteLine("Telemetry: Sampler started rate: {0} ms", samplerRate);
        }
示例#2
0
        // write sampler data to AMF
        public void Write(MethodMap methodMap, bool combineSamples = true)
        {
            // get accumulated sampler data
            Address[] data = GetSamplerData();

            // AMF serializable sample to write to
            Protocol.Sampler_sample sample = mSample;

            int lastCallStackIndex = 0;
            int lastCallStackCount = 0;

            // process all samples
            // this code is tricky because it tries to combine consecutive samples with the exact same callstack
            int sampleCount = 0;
            int index       = 0;

            for (;;)
            {
                // get length of callstack
                int count = (int)data[index++];
                if (count == 0)
                {
                    break;
                }

                // get sample time
                int time = (int)data[index++];

                // compare the last callstack with this one
                // if they are equal, the samples can be combined
                // else we have to start a new sample
                if (!combineSamples || (lastCallStackCount != count) || !ArrayEquals(data, index, lastCallStackIndex, count))
                {
                    // call stack is different...

                    if (sample.numticks > 0)
                    {
                        // write last sample to log
                        Session.WriteValueImmediate(sNameSamplerSample, sample);
                        // reset sample for new callstack
                        sample.numticks         = 0;
                        sample.ticktimes.length = 0;
                    }

                    // translate callstack to method ids
                    var callstack = sample.callstack;
                    callstack.length = 0;
                    for (int i = 0; i < count; i++)
                    {
                        bool topOfStack;
                        uint methodId = methodMap.GetMethodId(data[index + i], out topOfStack, true);
                        // add method id
                        callstack.push(methodId);
                        // abort callstack if we are at a "top of stack" method
                        if (topOfStack)
                        {
                            break;
                        }
                    }

                    // save last callstack position
                    lastCallStackIndex = index;
                    lastCallStackCount = count;
                }

                // add tick to sample
                sample.numticks++;
                sample.time = time;
                sample.ticktimes.push((double)time);

                // advance to next sample
                index += count;
                sampleCount++;
            }

            if (sample.numticks > 0)
            {
                // write last sample to log
                Session.WriteValueImmediate(sNameSamplerSample, sample);
                // reset sample for new callstack
                sample.numticks         = 0;
                sample.ticktimes.length = 0;
            }

            if (sampleCount > 0)
            {
                // TODO:
                Session.WriteValue(".sampler.medianInterval", 1000);
                Session.WriteValue(".sampler.averageInterval", 1000);
                Session.WriteValue(".sampler.maxInterval", 1000);
            }
        }