perfsrv/piprofiler/plugins/GeneralsPlugin/src/MemSamplerImpl.cpp
author hgs
Tue, 26 Oct 2010 16:20:32 +0300
changeset 62 1c2bb2fc7c87
parent 51 98307c651589
permissions -rw-r--r--
201043
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
51
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
hgs
parents:
diff changeset
     3
* All rights reserved.
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
*
hgs
parents:
diff changeset
     9
* Initial Contributors:
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
*
hgs
parents:
diff changeset
    12
* Contributors:
hgs
parents:
diff changeset
    13
*
hgs
parents:
diff changeset
    14
* Description:  
hgs
parents:
diff changeset
    15
*
hgs
parents:
diff changeset
    16
*/
hgs
parents:
diff changeset
    17
hgs
parents:
diff changeset
    18
hgs
parents:
diff changeset
    19
#include <piprofiler/ProfilerVersion.h>
hgs
parents:
diff changeset
    20
#include <piprofiler/ProfilerTraces.h>
hgs
parents:
diff changeset
    21
hgs
parents:
diff changeset
    22
#include <kern_priv.h>
hgs
parents:
diff changeset
    23
#include <plat_priv.h>
hgs
parents:
diff changeset
    24
hgs
parents:
diff changeset
    25
#include "MemSamplerImpl.h"
hgs
parents:
diff changeset
    26
hgs
parents:
diff changeset
    27
// for testing precise stack utilization tracing...
hgs
parents:
diff changeset
    28
// crashes at the moment
hgs
parents:
diff changeset
    29
hgs
parents:
diff changeset
    30
#include <nk_cpu.h>
hgs
parents:
diff changeset
    31
hgs
parents:
diff changeset
    32
#if !defined(__NKERN_H__)
hgs
parents:
diff changeset
    33
#include <nkern.h>
hgs
parents:
diff changeset
    34
#endif 
hgs
parents:
diff changeset
    35
hgs
parents:
diff changeset
    36
#define TAG(obj) (*(TUint32*)&(obj->iAsyncDeleteNext))
hgs
parents:
diff changeset
    37
#define PROFILER_CHUNK_MARK		((TUint32)0x00001000)
hgs
parents:
diff changeset
    38
#define PROFILER_MEM_THREAD_MARK	((TUint32)0x00000001)
hgs
parents:
diff changeset
    39
#define PROFILER_LIBRARY_MARK    ((TUint32)0x10000000)
hgs
parents:
diff changeset
    40
#define PROFILER_MEM_THREAD_UNMARK  ~PROFILER_MEM_THREAD_MARK
hgs
parents:
diff changeset
    41
hgs
parents:
diff changeset
    42
#ifdef MEM_EVENT_HANDLER
hgs
parents:
diff changeset
    43
#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
hgs
parents:
diff changeset
    44
_LIT8(KMemVersion,"2.03");
hgs
parents:
diff changeset
    45
#else
hgs
parents:
diff changeset
    46
_LIT8(KMemVersion, "2.02");
hgs
parents:
diff changeset
    47
#endif
hgs
parents:
diff changeset
    48
#else
hgs
parents:
diff changeset
    49
_LIT8(KMemVersion, "1.56");
hgs
parents:
diff changeset
    50
#endif
hgs
parents:
diff changeset
    51
hgs
parents:
diff changeset
    52
DMemSamplerImpl::DMemSamplerImpl() :
hgs
parents:
diff changeset
    53
	sampleDescriptor(&(this->sample[1]),0,256)
hgs
parents:
diff changeset
    54
    {
hgs
parents:
diff changeset
    55
    LOGSTRING("MemSamplerImpl::MemSamplerImpl() - konstruktori");
hgs
parents:
diff changeset
    56
hgs
parents:
diff changeset
    57
	iCount = 0;
hgs
parents:
diff changeset
    58
		
hgs
parents:
diff changeset
    59
	iSampleType = ESampleThreads;
62
hgs
parents: 51
diff changeset
    60
	//iSampleType = ESampleChunks;
hgs
parents: 51
diff changeset
    61
hgs
parents: 51
diff changeset
    62
	iTimeToSample = true;
51
hgs
parents:
diff changeset
    63
	iTotalMemoryOk = false;
hgs
parents:
diff changeset
    64
	iTotalMemoryNameOk = false;
hgs
parents:
diff changeset
    65
	
hgs
parents:
diff changeset
    66
	iNewChunkCount = 0;
hgs
parents:
diff changeset
    67
	iChunkCount = 0;
hgs
parents:
diff changeset
    68
	iChunksProcessing = ENothingToProcess;
hgs
parents:
diff changeset
    69
    iThreadsProcessing = ENothingToProcess;
hgs
parents:
diff changeset
    70
	
62
hgs
parents: 51
diff changeset
    71
    iChunksGathered = false;
hgs
parents: 51
diff changeset
    72
    iThreadsGathered = false;
hgs
parents: 51
diff changeset
    73
    
51
hgs
parents:
diff changeset
    74
	iNewThreadCount = 0;
hgs
parents:
diff changeset
    75
	iThreadCount = 0;
hgs
parents:
diff changeset
    76
	
hgs
parents:
diff changeset
    77
	// reset data structures
hgs
parents:
diff changeset
    78
    for(TInt i(0);i<KProfilerMaxChunksAmount;i++)
hgs
parents:
diff changeset
    79
        {
hgs
parents:
diff changeset
    80
        // heap chunks
hgs
parents:
diff changeset
    81
        this->heapChunksToSample[i] = 0;
hgs
parents:
diff changeset
    82
        this->heapChunkNamesToReport[i] = 0;
hgs
parents:
diff changeset
    83
        }
hgs
parents:
diff changeset
    84
    
hgs
parents:
diff changeset
    85
    for(TInt i(0);i<KProfilerMaxThreadsAmount;i++)
hgs
parents:
diff changeset
    86
        {
hgs
parents:
diff changeset
    87
        // threads
hgs
parents:
diff changeset
    88
        this->threadsToSample[i] = 0;
hgs
parents:
diff changeset
    89
        this->threadNamesToReport[i] = 0;
hgs
parents:
diff changeset
    90
        }
hgs
parents:
diff changeset
    91
    
hgs
parents:
diff changeset
    92
#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
hgs
parents:
diff changeset
    93
    iLibrariesProcessing = ENothingToProcess;
hgs
parents:
diff changeset
    94
    iNewLibraryCount = 0;
hgs
parents:
diff changeset
    95
    iLibraryCount = 0;
hgs
parents:
diff changeset
    96
    
hgs
parents:
diff changeset
    97
    for(TInt i(0); i<KProfilerMaxLibrariesAmount; i++)
hgs
parents:
diff changeset
    98
        {
hgs
parents:
diff changeset
    99
        // libraries
hgs
parents:
diff changeset
   100
        this->librariesToSample[i] = 0;
hgs
parents:
diff changeset
   101
        this->libraryNamesToReport[i] = 0;
hgs
parents:
diff changeset
   102
        }
hgs
parents:
diff changeset
   103
#endif
hgs
parents:
diff changeset
   104
hgs
parents:
diff changeset
   105
    }
hgs
parents:
diff changeset
   106
hgs
parents:
diff changeset
   107
DMemSamplerImpl::~DMemSamplerImpl()
hgs
parents:
diff changeset
   108
    {
hgs
parents:
diff changeset
   109
hgs
parents:
diff changeset
   110
    }
hgs
parents:
diff changeset
   111
hgs
parents:
diff changeset
   112
TInt DMemSamplerImpl::CreateFirstSample()
hgs
parents:
diff changeset
   113
    {
hgs
parents:
diff changeset
   114
    LOGSTRING("MemSamplerImpl::CreateFirstSample - entry");
hgs
parents:
diff changeset
   115
	
hgs
parents:
diff changeset
   116
	this->sampleDescriptor.Zero();
hgs
parents:
diff changeset
   117
	this->sampleDescriptor.Append(_L8("Bappea_V"));
hgs
parents:
diff changeset
   118
	this->sampleDescriptor.Append(KMemVersion);
hgs
parents:
diff changeset
   119
	this->sampleDescriptor.Append(_L8("_MEM"));
hgs
parents:
diff changeset
   120
	
62
hgs
parents: 51
diff changeset
   121
    LOGSTRING2("timestamp : 0x%04x",  iCount);
51
hgs
parents:
diff changeset
   122
62
hgs
parents: 51
diff changeset
   123
    LOGSTRING("MemSamplerImpl::CreateFirstSample - exit");
hgs
parents: 51
diff changeset
   124
    sample[0] = this->sampleDescriptor.Size();
hgs
parents: 51
diff changeset
   125
    
hgs
parents: 51
diff changeset
   126
    return (TInt)(sample[0]+1);
51
hgs
parents:
diff changeset
   127
    }
hgs
parents:
diff changeset
   128
62
hgs
parents: 51
diff changeset
   129
TBool DMemSamplerImpl::SampleNeeded(TUint32 sampleNum)
51
hgs
parents:
diff changeset
   130
    {
62
hgs
parents: 51
diff changeset
   131
    TBool ret(false);
hgs
parents: 51
diff changeset
   132
    iCount = sampleNum;
51
hgs
parents:
diff changeset
   133
#ifdef MEM_EVENT_HANDLER
hgs
parents:
diff changeset
   134
    // make the collection of chunks/threads only once, rest will be collected with mem event handler
62
hgs
parents: 51
diff changeset
   135
hgs
parents: 51
diff changeset
   136
//    #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
hgs
parents: 51
diff changeset
   137
//    if (iCount <= iMemSamplingPeriod && ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv3) == 0))
hgs
parents: 51
diff changeset
   138
//    #else
hgs
parents: 51
diff changeset
   139
	if (iCount % iMemSamplingPeriod == 0)
hgs
parents: 51
diff changeset
   140
//    #endif
hgs
parents: 51
diff changeset
   141
51
hgs
parents:
diff changeset
   142
#else
hgs
parents:
diff changeset
   143
	if ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv2) == 0)
hgs
parents:
diff changeset
   144
#endif
hgs
parents:
diff changeset
   145
	    {
hgs
parents:
diff changeset
   146
        LOGSTRING2("MemSamplerImpl::SampleNeeded - time: %d", iCount);
62
hgs
parents: 51
diff changeset
   147
        ret= true;
51
hgs
parents:
diff changeset
   148
        }
62
hgs
parents: 51
diff changeset
   149
	else
51
hgs
parents:
diff changeset
   150
	    {
62
hgs
parents: 51
diff changeset
   151
		ret=false;
51
hgs
parents:
diff changeset
   152
        }
62
hgs
parents: 51
diff changeset
   153
	return ret;
hgs
parents: 51
diff changeset
   154
	}
51
hgs
parents:
diff changeset
   155
62
hgs
parents: 51
diff changeset
   156
/*
hgs
parents: 51
diff changeset
   157
 * When returns 0, means that all samples done.
hgs
parents: 51
diff changeset
   158
 * Should return length of sample available in iSample
hgs
parents: 51
diff changeset
   159
 */
hgs
parents: 51
diff changeset
   160
TInt DMemSamplerImpl::SampleImpl(TUint32 sampleNum)
hgs
parents: 51
diff changeset
   161
    {
hgs
parents: 51
diff changeset
   162
    if(iTimeToSample)
hgs
parents: 51
diff changeset
   163
        {
hgs
parents: 51
diff changeset
   164
        // Sample threads:
hgs
parents: 51
diff changeset
   165
        if( iSampleType == ESampleThreads && !iThreadsGathered )
hgs
parents: 51
diff changeset
   166
            {
hgs
parents: 51
diff changeset
   167
            if(this->iThreadsProcessing == ENothingToProcess )
51
hgs
parents:
diff changeset
   168
                {
62
hgs
parents: 51
diff changeset
   169
                 // gather first all thread stacks
hgs
parents: 51
diff changeset
   170
                 return GatherThreads(); 
51
hgs
parents:
diff changeset
   171
                }
hgs
parents:
diff changeset
   172
            else
hgs
parents:
diff changeset
   173
                {
62
hgs
parents: 51
diff changeset
   174
                // process now thread stack list
hgs
parents: 51
diff changeset
   175
                TInt length = this->ProcessThreads();
hgs
parents: 51
diff changeset
   176
                if(length == 0)
hgs
parents: 51
diff changeset
   177
                    {
hgs
parents: 51
diff changeset
   178
                    this->iThreadsProcessing = ENothingToProcess;
hgs
parents: 51
diff changeset
   179
                    // switch to collect chunk data
hgs
parents: 51
diff changeset
   180
                    iSampleType = ESampleChunks;
hgs
parents: 51
diff changeset
   181
                    iThreadsGathered = ETrue;
hgs
parents: 51
diff changeset
   182
                    }
hgs
parents: 51
diff changeset
   183
                return length;
51
hgs
parents:
diff changeset
   184
                }
hgs
parents:
diff changeset
   185
            }
62
hgs
parents: 51
diff changeset
   186
        // Sample chunks:
hgs
parents: 51
diff changeset
   187
        else if( iSampleType == ESampleChunks && !iChunksGathered)
51
hgs
parents:
diff changeset
   188
            {
62
hgs
parents: 51
diff changeset
   189
            if(this->iChunksProcessing == ENothingToProcess)
51
hgs
parents:
diff changeset
   190
                {
hgs
parents:
diff changeset
   191
                // gather first all chunks
hgs
parents:
diff changeset
   192
                return GatherChunks();
hgs
parents:
diff changeset
   193
                }
hgs
parents:
diff changeset
   194
            else
hgs
parents:
diff changeset
   195
                {
62
hgs
parents: 51
diff changeset
   196
                // still something to go through in lists
hgs
parents: 51
diff changeset
   197
                TInt length = this->ProcessChunks();
hgs
parents: 51
diff changeset
   198
                if(length == 0) 
hgs
parents: 51
diff changeset
   199
                    {
hgs
parents: 51
diff changeset
   200
                    this->iChunksProcessing = ENothingToProcess;
hgs
parents: 51
diff changeset
   201
                    // switch to collect library data
hgs
parents: 51
diff changeset
   202
                    iSampleType = ESampleLibraries;
hgs
parents: 51
diff changeset
   203
                    iChunksGathered = ETrue;
hgs
parents: 51
diff changeset
   204
                    iThreadsGathered = ETrue;
hgs
parents: 51
diff changeset
   205
                    //iSampleThreads = true;
hgs
parents: 51
diff changeset
   206
                    }
hgs
parents: 51
diff changeset
   207
                return length;
hgs
parents: 51
diff changeset
   208
                }
hgs
parents: 51
diff changeset
   209
            }
hgs
parents: 51
diff changeset
   210
hgs
parents: 51
diff changeset
   211
    #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
hgs
parents: 51
diff changeset
   212
        // Sample libraries:
hgs
parents: 51
diff changeset
   213
        else if( iSampleType == ESampleLibraries )
hgs
parents: 51
diff changeset
   214
            {
hgs
parents: 51
diff changeset
   215
            if(this->iLibrariesProcessing == ENothingToProcess )
hgs
parents: 51
diff changeset
   216
                {        
51
hgs
parents:
diff changeset
   217
                // gather libraries
hgs
parents:
diff changeset
   218
                return GatherLibraries();
hgs
parents:
diff changeset
   219
                }
62
hgs
parents: 51
diff changeset
   220
            else
hgs
parents: 51
diff changeset
   221
                {
hgs
parents: 51
diff changeset
   222
                // process now thread stack list
hgs
parents: 51
diff changeset
   223
                TInt length = this->ProcessLibraries();
hgs
parents: 51
diff changeset
   224
                if(length == 0)
hgs
parents: 51
diff changeset
   225
                    {
hgs
parents: 51
diff changeset
   226
                    this->iLibrariesProcessing = ENothingToProcess;
hgs
parents: 51
diff changeset
   227
                    // switch to collect chunk data
hgs
parents: 51
diff changeset
   228
                    iSampleType = ESampleThreads;
hgs
parents: 51
diff changeset
   229
                    iLibrariesGathered = ETrue;
hgs
parents: 51
diff changeset
   230
                    }
hgs
parents: 51
diff changeset
   231
                return length;
hgs
parents: 51
diff changeset
   232
                }
51
hgs
parents:
diff changeset
   233
            }
62
hgs
parents: 51
diff changeset
   234
    #endif
51
hgs
parents:
diff changeset
   235
        else
hgs
parents:
diff changeset
   236
            {
62
hgs
parents: 51
diff changeset
   237
            // Will not be executed. Ever. PostSample handles the state change and starting of
hgs
parents: 51
diff changeset
   238
            // memory event handler.
hgs
parents: 51
diff changeset
   239
            iChunksGathered = ETrue;
hgs
parents: 51
diff changeset
   240
            iThreadsGathered = ETrue;
hgs
parents: 51
diff changeset
   241
            iTimeToSample = false;
hgs
parents: 51
diff changeset
   242
            Kern::Printf("MEM sampler - all initial samples generated but we should not be here...!");
51
hgs
parents:
diff changeset
   243
            }
hgs
parents:
diff changeset
   244
        }
62
hgs
parents: 51
diff changeset
   245
    else    // not time to sample
hgs
parents: 51
diff changeset
   246
        {
hgs
parents: 51
diff changeset
   247
        LOGSTRING("MEM sampler - not time to sample!");
hgs
parents: 51
diff changeset
   248
        }
51
hgs
parents:
diff changeset
   249
    // should not reach this point...
hgs
parents:
diff changeset
   250
    return 0;
hgs
parents:
diff changeset
   251
    }
hgs
parents:
diff changeset
   252
hgs
parents:
diff changeset
   253
hgs
parents:
diff changeset
   254
inline TInt DMemSamplerImpl::GatherChunks()
hgs
parents:
diff changeset
   255
    {
hgs
parents:
diff changeset
   256
    // encode a process binary
hgs
parents:
diff changeset
   257
    name.Zero();
hgs
parents:
diff changeset
   258
    NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
hgs
parents:
diff changeset
   259
    DObjectCon& chunks = *Kern::Containers()[EChunk];
hgs
parents:
diff changeset
   260
    chunks.Wait();  // Obtain the container mutex so the list does get changed under us
hgs
parents:
diff changeset
   261
    
hgs
parents:
diff changeset
   262
    this->iChunkCount = 0; 
hgs
parents:
diff changeset
   263
    this->iNewChunkCount = 0;
hgs
parents:
diff changeset
   264
    this->iTotalMemoryOk = false;
hgs
parents:
diff changeset
   265
    TInt totalChunkCount(chunks.Count());
hgs
parents:
diff changeset
   266
    DChunk* c; 
62
hgs
parents: 51
diff changeset
   267
    LOGSTRING2("DMemSamplerImpl::GatherChunks() chunk count %d",totalChunkCount);
51
hgs
parents:
diff changeset
   268
    for(TInt i(0);i<totalChunkCount;i++)
hgs
parents:
diff changeset
   269
        {
hgs
parents:
diff changeset
   270
        c = (DChunk*)(chunks)[i];
hgs
parents:
diff changeset
   271
62
hgs
parents: 51
diff changeset
   272
        //LOGSTRING3("Processing chunk %d, tag: 0x%x",i,TAG(c));
51
hgs
parents:
diff changeset
   273
        
hgs
parents:
diff changeset
   274
        if( (TAG(c) & 0x0000ffff) != PROFILER_CHUNK_MARK)
hgs
parents:
diff changeset
   275
            {
62
hgs
parents: 51
diff changeset
   276
            //LOGSTRING4("Marking chunk %d/%d, old tag 0x%x",i,(totalChunkCount-1), TAG(c));
51
hgs
parents:
diff changeset
   277
            // this chunk has not been tagged yet
hgs
parents:
diff changeset
   278
            name.Zero();
hgs
parents:
diff changeset
   279
            c->TraceAppendName(name,false);
hgs
parents:
diff changeset
   280
            
hgs
parents:
diff changeset
   281
            TAG(c) = (PROFILER_CHUNK_MARK);
hgs
parents:
diff changeset
   282
            this->heapChunkNamesToReport[iNewChunkCount] = c;
hgs
parents:
diff changeset
   283
            iNewChunkCount++;
hgs
parents:
diff changeset
   284
            }
hgs
parents:
diff changeset
   285
hgs
parents:
diff changeset
   286
        // the chunk has been tagged, add heap chunks to the list
hgs
parents:
diff changeset
   287
        this->heapChunksToSample[this->iChunkCount] = c;
hgs
parents:
diff changeset
   288
        this->iChunkCount++;
hgs
parents:
diff changeset
   289
        }
62
hgs
parents: 51
diff changeset
   290
        LOGSTRING2("Added  %d Chunks", totalChunkCount);
51
hgs
parents:
diff changeset
   291
hgs
parents:
diff changeset
   292
    if(this->iChunkCount > 0 || this->iNewChunkCount > 0)
hgs
parents:
diff changeset
   293
        {
hgs
parents:
diff changeset
   294
        this->iChunksProcessing = EStartingToProcess;
hgs
parents:
diff changeset
   295
        
hgs
parents:
diff changeset
   296
        // process the first sample
hgs
parents:
diff changeset
   297
        TInt length = this->ProcessChunks();
hgs
parents:
diff changeset
   298
        if(length == 0)
hgs
parents:
diff changeset
   299
            {
hgs
parents:
diff changeset
   300
            this->iChunksProcessing = ENothingToProcess;
hgs
parents:
diff changeset
   301
            }
hgs
parents:
diff changeset
   302
    
hgs
parents:
diff changeset
   303
        chunks.Signal();  // Release the container mutex
hgs
parents:
diff changeset
   304
        NKern::ThreadLeaveCS();  // End of critical section
hgs
parents:
diff changeset
   305
        return length;
hgs
parents:
diff changeset
   306
        }
hgs
parents:
diff changeset
   307
hgs
parents:
diff changeset
   308
    LOGTEXT("MemSamplerImpl::SampleImpl - Error, no threads"); 
hgs
parents:
diff changeset
   309
    chunks.Signal();  // Release the container mutex
hgs
parents:
diff changeset
   310
    NKern::ThreadLeaveCS();  // End of critical section
hgs
parents:
diff changeset
   311
    return 0;
hgs
parents:
diff changeset
   312
    }
hgs
parents:
diff changeset
   313
hgs
parents:
diff changeset
   314
inline TInt DMemSamplerImpl::GatherThreads()
hgs
parents:
diff changeset
   315
    {
hgs
parents:
diff changeset
   316
    // The thread memory consumption
hgs
parents:
diff changeset
   317
    NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
hgs
parents:
diff changeset
   318
    DObjectCon& threads = *Kern::Containers()[EThread];
hgs
parents:
diff changeset
   319
    threads.Wait(); // Obtain the container mutex so the list does get changed under us
hgs
parents:
diff changeset
   320
    
hgs
parents:
diff changeset
   321
    this->iThreadCount = 0; 
hgs
parents:
diff changeset
   322
    this->iNewThreadCount = 0;
hgs
parents:
diff changeset
   323
    this->iTotalMemoryOk = false;           
hgs
parents:
diff changeset
   324
hgs
parents:
diff changeset
   325
    TInt totalThreadCount = threads.Count();
62
hgs
parents: 51
diff changeset
   326
    LOGSTRING2("DMemSamplerImpl::GatherThreads() thread count %d",totalThreadCount);
51
hgs
parents:
diff changeset
   327
    for(TInt i(0);i<totalThreadCount;i++)
hgs
parents:
diff changeset
   328
        {
hgs
parents:
diff changeset
   329
        DThread* t = (DThread*)(threads)[i];
hgs
parents:
diff changeset
   330
62
hgs
parents: 51
diff changeset
   331
        //LOGSTRING3("Processing thread %d, tag: 0x%x",i,TAG(t));
51
hgs
parents:
diff changeset
   332
hgs
parents:
diff changeset
   333
        if( (TAG(t) & PROFILER_MEM_THREAD_MARK) == 0)
hgs
parents:
diff changeset
   334
            {
62
hgs
parents: 51
diff changeset
   335
            //LOGSTRING4("Marking thread %d/%d, old tag 0x%x",i,(totalThreadCount-1), TAG(t));
51
hgs
parents:
diff changeset
   336
            // this thread's chunk has not been reported yet
hgs
parents:
diff changeset
   337
            this->threadNamesToReport[iNewThreadCount] = t;
hgs
parents:
diff changeset
   338
            iNewThreadCount++;
hgs
parents:
diff changeset
   339
            // tag the thread
hgs
parents:
diff changeset
   340
            TAG(t) |= PROFILER_MEM_THREAD_MARK;
hgs
parents:
diff changeset
   341
            }
hgs
parents:
diff changeset
   342
hgs
parents:
diff changeset
   343
        // the chunk has been tagged, add heap chunks to the list
hgs
parents:
diff changeset
   344
        this->threadsToSample[this->iThreadCount] = t;
hgs
parents:
diff changeset
   345
        this->iThreadCount++;
62
hgs
parents: 51
diff changeset
   346
        //LOGSTRING2("Added thread %d to threads to sample",i);
51
hgs
parents:
diff changeset
   347
        }
62
hgs
parents: 51
diff changeset
   348
hgs
parents: 51
diff changeset
   349
    LOGSTRING3("Added %d threads. ithreadcount %d",totalThreadCount, iThreadCount);
hgs
parents: 51
diff changeset
   350
   
51
hgs
parents:
diff changeset
   351
    if(this->iThreadCount > 0 || this->iNewThreadCount > 0)
hgs
parents:
diff changeset
   352
        {
hgs
parents:
diff changeset
   353
        this->iThreadsProcessing = EStartingToProcess;
62
hgs
parents: 51
diff changeset
   354
      // process the first sample
51
hgs
parents:
diff changeset
   355
        TInt length = this->ProcessThreads();
hgs
parents:
diff changeset
   356
        if(length == 0)
hgs
parents:
diff changeset
   357
            {
hgs
parents:
diff changeset
   358
            this->iThreadsProcessing = ENothingToProcess;
hgs
parents:
diff changeset
   359
            }
hgs
parents:
diff changeset
   360
        threads.Signal();  // Release the container mutex
hgs
parents:
diff changeset
   361
        NKern::ThreadLeaveCS();  // End of critical section
hgs
parents:
diff changeset
   362
        return length;
hgs
parents:
diff changeset
   363
        }
hgs
parents:
diff changeset
   364
    
62
hgs
parents: 51
diff changeset
   365
    LOGTEXT("DMemSamplerImpl::GatherThreads() - Error, no threads"); 
51
hgs
parents:
diff changeset
   366
    threads.Signal();  // Release the container mutex
hgs
parents:
diff changeset
   367
    NKern::ThreadLeaveCS();  // End of critical section
hgs
parents:
diff changeset
   368
    return 0;
hgs
parents:
diff changeset
   369
    }
hgs
parents:
diff changeset
   370
hgs
parents:
diff changeset
   371
#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
hgs
parents:
diff changeset
   372
hgs
parents:
diff changeset
   373
inline TInt DMemSamplerImpl::GatherLibraries()
hgs
parents:
diff changeset
   374
    {
hgs
parents:
diff changeset
   375
    LOGTEXT("MemSamplerImpl::GatherLibraries() - entry");
hgs
parents:
diff changeset
   376
    // encode a process binary
hgs
parents:
diff changeset
   377
    name.Zero();
hgs
parents:
diff changeset
   378
    
hgs
parents:
diff changeset
   379
    NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
hgs
parents:
diff changeset
   380
    DObjectCon& libs = *Kern::Containers()[ELibrary];
hgs
parents:
diff changeset
   381
    libs.Wait();  // Obtain the container mutex so the list does get changed under us
hgs
parents:
diff changeset
   382
    
hgs
parents:
diff changeset
   383
    this->iLibraryCount = 0; 
hgs
parents:
diff changeset
   384
    this->iNewLibraryCount = 0;
hgs
parents:
diff changeset
   385
    this->iTotalMemoryOk = false;
hgs
parents:
diff changeset
   386
    TInt totalLibCount(libs.Count());
hgs
parents:
diff changeset
   387
    DLibrary* l; 
hgs
parents:
diff changeset
   388
    
hgs
parents:
diff changeset
   389
    for(TInt i(0);i<totalLibCount;i++)
hgs
parents:
diff changeset
   390
        {
hgs
parents:
diff changeset
   391
        l = (DLibrary*)(libs)[i];
hgs
parents:
diff changeset
   392
hgs
parents:
diff changeset
   393
        LOGSTRING3("Processing library %d, tag: 0x%x",i,TAG(l));
hgs
parents:
diff changeset
   394
        
hgs
parents:
diff changeset
   395
        if( (TAG(l) & 0xffffffff) != PROFILER_LIBRARY_MARK)
hgs
parents:
diff changeset
   396
            {
hgs
parents:
diff changeset
   397
            LOGSTRING4("Marking library %d/%d, old tag 0x%x",i,(totalLibCount-1), TAG(l));
hgs
parents:
diff changeset
   398
            // this library has not been tagged yet
hgs
parents:
diff changeset
   399
            name.Zero();
hgs
parents:
diff changeset
   400
            l->TraceAppendName(name,false);
hgs
parents:
diff changeset
   401
            
hgs
parents:
diff changeset
   402
            TAG(l) = (PROFILER_LIBRARY_MARK);
hgs
parents:
diff changeset
   403
            this->libraryNamesToReport[iNewLibraryCount] = l;
hgs
parents:
diff changeset
   404
            iNewLibraryCount++;
hgs
parents:
diff changeset
   405
            }
hgs
parents:
diff changeset
   406
hgs
parents:
diff changeset
   407
        // the library has been tagged, add library to the list
hgs
parents:
diff changeset
   408
        this->librariesToSample[this->iLibraryCount] = l;
hgs
parents:
diff changeset
   409
        this->iLibraryCount++;
hgs
parents:
diff changeset
   410
        LOGSTRING2("Added library %d to Libraries",i);
hgs
parents:
diff changeset
   411
        }
hgs
parents:
diff changeset
   412
hgs
parents:
diff changeset
   413
    if(this->iLibraryCount > 0 || this->iNewLibraryCount > 0)
hgs
parents:
diff changeset
   414
        {
hgs
parents:
diff changeset
   415
        this->iLibrariesProcessing = EStartingToProcess;
hgs
parents:
diff changeset
   416
        
hgs
parents:
diff changeset
   417
        // process the first sample
hgs
parents:
diff changeset
   418
        TInt length = this->ProcessLibraries();
hgs
parents:
diff changeset
   419
        
hgs
parents:
diff changeset
   420
        if(length == 0)
hgs
parents:
diff changeset
   421
            {
hgs
parents:
diff changeset
   422
            this->iLibrariesProcessing = ENothingToProcess;
hgs
parents:
diff changeset
   423
            }
hgs
parents:
diff changeset
   424
    
hgs
parents:
diff changeset
   425
        libs.Signal();  // Release the container mutex
hgs
parents:
diff changeset
   426
        NKern::ThreadLeaveCS();  // End of critical section
hgs
parents:
diff changeset
   427
        return length;
hgs
parents:
diff changeset
   428
        }
hgs
parents:
diff changeset
   429
hgs
parents:
diff changeset
   430
    LOGTEXT("MemSamplerImpl::SampleImpl - Error, no libraries"); 
hgs
parents:
diff changeset
   431
    libs.Signal();  // Release the container mutex
hgs
parents:
diff changeset
   432
    NKern::ThreadLeaveCS();  // End of critical section
hgs
parents:
diff changeset
   433
    return 0;
hgs
parents:
diff changeset
   434
    }
hgs
parents:
diff changeset
   435
#endif
hgs
parents:
diff changeset
   436
hgs
parents:
diff changeset
   437
inline TInt DMemSamplerImpl::ProcessChunks()
hgs
parents:
diff changeset
   438
    {
62
hgs
parents: 51
diff changeset
   439
    if(iHandledChunks < 50)
hgs
parents: 51
diff changeset
   440
        {
hgs
parents: 51
diff changeset
   441
        if(iNewChunkCount > 0)
hgs
parents: 51
diff changeset
   442
            {
hgs
parents: 51
diff changeset
   443
            if(this->iChunksProcessing == EStartingToProcess)
hgs
parents: 51
diff changeset
   444
                {
hgs
parents: 51
diff changeset
   445
                // this is the first sample, encode a code for names
hgs
parents: 51
diff changeset
   446
                this->iChunksProcessing = EProcessingNames;
hgs
parents: 51
diff changeset
   447
                iHandledChunks++;
hgs
parents: 51
diff changeset
   448
                return EncodeNameCode();
hgs
parents: 51
diff changeset
   449
                }
hgs
parents: 51
diff changeset
   450
    
hgs
parents: 51
diff changeset
   451
            if(iTotalMemoryNameOk == false)
hgs
parents: 51
diff changeset
   452
                {
hgs
parents: 51
diff changeset
   453
                iHandledChunks++;
hgs
parents: 51
diff changeset
   454
                return EncodeTotalMemoryName();
hgs
parents: 51
diff changeset
   455
                }
hgs
parents: 51
diff changeset
   456
            iNewChunkCount--;
hgs
parents: 51
diff changeset
   457
            DChunk* c = this->heapChunkNamesToReport[iNewChunkCount];
hgs
parents: 51
diff changeset
   458
            iHandledChunks++;
hgs
parents: 51
diff changeset
   459
            return EncodeChunkName(*c);
hgs
parents: 51
diff changeset
   460
            }
hgs
parents: 51
diff changeset
   461
        else if(iChunkCount > 0)
hgs
parents: 51
diff changeset
   462
            {
hgs
parents: 51
diff changeset
   463
            if(this->iChunksProcessing == EProcessingNames || this->iChunksProcessing == EStartingToProcess)
hgs
parents: 51
diff changeset
   464
                {
hgs
parents: 51
diff changeset
   465
                // this is the first data sample, encode a code for data
hgs
parents: 51
diff changeset
   466
                this->iChunksProcessing = EProcessingData;
hgs
parents: 51
diff changeset
   467
                iHandledChunks++;
hgs
parents: 51
diff changeset
   468
                return EncodeDataCode();
hgs
parents: 51
diff changeset
   469
                }
hgs
parents: 51
diff changeset
   470
            
hgs
parents: 51
diff changeset
   471
            if(this->iTotalMemoryOk == false)
hgs
parents: 51
diff changeset
   472
                {
hgs
parents: 51
diff changeset
   473
                iHandledChunks++;
hgs
parents: 51
diff changeset
   474
                return EncodeTotalMemory();
hgs
parents: 51
diff changeset
   475
                }
hgs
parents: 51
diff changeset
   476
    
hgs
parents: 51
diff changeset
   477
            // there are no new chunks to report
hgs
parents: 51
diff changeset
   478
            // thus generate the real report
hgs
parents: 51
diff changeset
   479
            iChunkCount--;
hgs
parents: 51
diff changeset
   480
            DChunk* c = this->heapChunksToSample[iChunkCount];
hgs
parents: 51
diff changeset
   481
            iHandledChunks++;
hgs
parents: 51
diff changeset
   482
            return EncodeChunkData(*c);
hgs
parents: 51
diff changeset
   483
            }
hgs
parents: 51
diff changeset
   484
        else
hgs
parents: 51
diff changeset
   485
            {
hgs
parents: 51
diff changeset
   486
            // everything is processed
hgs
parents: 51
diff changeset
   487
            LOGSTRING2("MemSamplerImpl::ProcessChunks() Chunks processed! Chunk count = %d", iChunkCount);
hgs
parents: 51
diff changeset
   488
    #ifdef MEM_EVENT_HANDLER
hgs
parents: 51
diff changeset
   489
            this->iChunksGathered = ETrue;
hgs
parents: 51
diff changeset
   490
            LOGSTRING2("MemSamplerImpl::ProcessChunks() - chunks gathered! Time: %d",iCount);
hgs
parents: 51
diff changeset
   491
    #endif
hgs
parents: 51
diff changeset
   492
            return 0;
hgs
parents: 51
diff changeset
   493
            }
hgs
parents: 51
diff changeset
   494
        }
hgs
parents: 51
diff changeset
   495
    else
hgs
parents: 51
diff changeset
   496
        {
hgs
parents: 51
diff changeset
   497
        LOGSTRING("MemSamplerImpl::ProcessChunks() 0");
hgs
parents: 51
diff changeset
   498
        iHandledChunks =0;
hgs
parents: 51
diff changeset
   499
        }
hgs
parents: 51
diff changeset
   500
    return -1;
hgs
parents: 51
diff changeset
   501
    }
hgs
parents: 51
diff changeset
   502
hgs
parents: 51
diff changeset
   503
inline TInt DMemSamplerImpl::ProcessThreads()
hgs
parents: 51
diff changeset
   504
    {
hgs
parents: 51
diff changeset
   505
    if(iHandledThreads < 50)
51
hgs
parents:
diff changeset
   506
        {
62
hgs
parents: 51
diff changeset
   507
        if(iNewThreadCount > 0)
hgs
parents: 51
diff changeset
   508
            {
hgs
parents: 51
diff changeset
   509
            if(this->iThreadsProcessing == EStartingToProcess)
hgs
parents: 51
diff changeset
   510
                {
hgs
parents: 51
diff changeset
   511
                // this is the first sample, encode a code for names
hgs
parents: 51
diff changeset
   512
                this->iThreadsProcessing = EProcessingNames;
hgs
parents: 51
diff changeset
   513
                iHandledThreads++;
hgs
parents: 51
diff changeset
   514
                return EncodeNameCode();
hgs
parents: 51
diff changeset
   515
                }
hgs
parents: 51
diff changeset
   516
            
hgs
parents: 51
diff changeset
   517
            if(iTotalMemoryNameOk == false)
hgs
parents: 51
diff changeset
   518
                {
hgs
parents: 51
diff changeset
   519
                LOGSTRING("MemSamplerImpl::ProcessThreads() Encoding total memory name!");
hgs
parents: 51
diff changeset
   520
                iHandledThreads++;
hgs
parents: 51
diff changeset
   521
                return EncodeTotalMemoryName();
hgs
parents: 51
diff changeset
   522
                }
hgs
parents: 51
diff changeset
   523
            iNewThreadCount--;
hgs
parents: 51
diff changeset
   524
            DThread* t = this->threadNamesToReport[iNewThreadCount];
hgs
parents: 51
diff changeset
   525
            iHandledThreads++;
hgs
parents: 51
diff changeset
   526
            return EncodeChunkName(*t);
hgs
parents: 51
diff changeset
   527
            }
hgs
parents: 51
diff changeset
   528
        else if(iThreadCount > 0)
hgs
parents: 51
diff changeset
   529
            {
hgs
parents: 51
diff changeset
   530
            if(this->iThreadsProcessing == EProcessingNames || this->iThreadsProcessing == EStartingToProcess)
hgs
parents: 51
diff changeset
   531
                {
hgs
parents: 51
diff changeset
   532
                // this is the first data sample, encode a code for data
hgs
parents: 51
diff changeset
   533
                this->iThreadsProcessing = EProcessingData;
hgs
parents: 51
diff changeset
   534
                iHandledThreads++;
hgs
parents: 51
diff changeset
   535
                return EncodeDataCode();
hgs
parents: 51
diff changeset
   536
                }
hgs
parents: 51
diff changeset
   537
    
hgs
parents: 51
diff changeset
   538
            if(this->iTotalMemoryOk == false)
hgs
parents: 51
diff changeset
   539
                {
hgs
parents: 51
diff changeset
   540
                iHandledThreads++;
hgs
parents: 51
diff changeset
   541
                return EncodeTotalMemory(); 
hgs
parents: 51
diff changeset
   542
                }
hgs
parents: 51
diff changeset
   543
    
hgs
parents: 51
diff changeset
   544
            // there are no new threads to report
hgs
parents: 51
diff changeset
   545
            // thus generate the real report
hgs
parents: 51
diff changeset
   546
            iThreadCount--;
hgs
parents: 51
diff changeset
   547
            DThread* t = this->threadsToSample[iThreadCount];
hgs
parents: 51
diff changeset
   548
            iHandledThreads++;
hgs
parents: 51
diff changeset
   549
            return EncodeChunkData(*t);
hgs
parents: 51
diff changeset
   550
            }
hgs
parents: 51
diff changeset
   551
        else
hgs
parents: 51
diff changeset
   552
            {   
hgs
parents: 51
diff changeset
   553
            // everything is processed
hgs
parents: 51
diff changeset
   554
            LOGSTRING2("MemSamplerImpl::ProcessThreads() Threads processed! Thread count = %d", iThreadCount);
hgs
parents: 51
diff changeset
   555
#ifdef MEM_EVENT_HANDLER
hgs
parents: 51
diff changeset
   556
            this->iThreadsGathered = true;
hgs
parents: 51
diff changeset
   557
            LOGSTRING2("MemSamplerImpl::ProcessThreads() - threads gathered! Time: %d", iCount);
hgs
parents: 51
diff changeset
   558
#endif
hgs
parents: 51
diff changeset
   559
            return 0;
hgs
parents: 51
diff changeset
   560
            }
hgs
parents: 51
diff changeset
   561
        }
hgs
parents: 51
diff changeset
   562
    else
hgs
parents: 51
diff changeset
   563
        {
hgs
parents: 51
diff changeset
   564
        LOGSTRING("MemSamplerImpl::ProcessThreads() 0");
hgs
parents: 51
diff changeset
   565
        iHandledThreads=0;
hgs
parents: 51
diff changeset
   566
        }
hgs
parents: 51
diff changeset
   567
    return -1;
hgs
parents: 51
diff changeset
   568
    }
hgs
parents: 51
diff changeset
   569
hgs
parents: 51
diff changeset
   570
#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
hgs
parents: 51
diff changeset
   571
inline TInt DMemSamplerImpl::ProcessLibraries()
hgs
parents: 51
diff changeset
   572
    {
hgs
parents: 51
diff changeset
   573
    LOGTEXT("ProcessLibraries - entry");
hgs
parents: 51
diff changeset
   574
    
hgs
parents: 51
diff changeset
   575
    if(iHandledLibs < 50)
hgs
parents: 51
diff changeset
   576
        {
hgs
parents: 51
diff changeset
   577
        if(iNewLibraryCount > 0)
hgs
parents: 51
diff changeset
   578
        {
hgs
parents: 51
diff changeset
   579
        if(this->iLibrariesProcessing == EStartingToProcess)
51
hgs
parents:
diff changeset
   580
            {
hgs
parents:
diff changeset
   581
            // this is the first sample, encode a code for names
62
hgs
parents: 51
diff changeset
   582
            this->iLibrariesProcessing = EProcessingNames;
hgs
parents: 51
diff changeset
   583
            iHandledLibs++;
51
hgs
parents:
diff changeset
   584
            return EncodeNameCode();
hgs
parents:
diff changeset
   585
            }
hgs
parents:
diff changeset
   586
hgs
parents:
diff changeset
   587
        if(iTotalMemoryNameOk == false)
hgs
parents:
diff changeset
   588
            {
62
hgs
parents: 51
diff changeset
   589
            iHandledLibs++;
51
hgs
parents:
diff changeset
   590
            return EncodeTotalMemoryName();
hgs
parents:
diff changeset
   591
            }
hgs
parents:
diff changeset
   592
        
hgs
parents:
diff changeset
   593
        // there are new library names to report
hgs
parents:
diff changeset
   594
        iNewLibraryCount--;
hgs
parents:
diff changeset
   595
        DLibrary* l = this->libraryNamesToReport[iNewLibraryCount];
62
hgs
parents: 51
diff changeset
   596
        iHandledLibs++;
51
hgs
parents:
diff changeset
   597
        return EncodeChunkName(*l);
hgs
parents:
diff changeset
   598
        
hgs
parents:
diff changeset
   599
        }
hgs
parents:
diff changeset
   600
    else if(iLibraryCount > 0)
hgs
parents:
diff changeset
   601
        {
hgs
parents:
diff changeset
   602
        if(this->iLibrariesProcessing == EProcessingNames || this->iLibrariesProcessing == EStartingToProcess)
hgs
parents:
diff changeset
   603
            {
hgs
parents:
diff changeset
   604
            // this is the first data sample, encode a code for data
hgs
parents:
diff changeset
   605
            this->iLibrariesProcessing = EProcessingData;
62
hgs
parents: 51
diff changeset
   606
            iHandledLibs++;
51
hgs
parents:
diff changeset
   607
            return EncodeDataCode();
hgs
parents:
diff changeset
   608
            }
hgs
parents:
diff changeset
   609
        
hgs
parents:
diff changeset
   610
        if(this->iTotalMemoryOk == false)
hgs
parents:
diff changeset
   611
            {
62
hgs
parents: 51
diff changeset
   612
            iHandledLibs++;
51
hgs
parents:
diff changeset
   613
            return EncodeTotalMemory(); 
hgs
parents:
diff changeset
   614
            }
hgs
parents:
diff changeset
   615
hgs
parents:
diff changeset
   616
        // there are no new libraries to report
hgs
parents:
diff changeset
   617
        // thus generate the real report
hgs
parents:
diff changeset
   618
        iLibraryCount--;
hgs
parents:
diff changeset
   619
        DLibrary* l = this->librariesToSample[iLibraryCount];
62
hgs
parents: 51
diff changeset
   620
        iHandledLibs++;
51
hgs
parents:
diff changeset
   621
        return EncodeChunkData(*l);
hgs
parents:
diff changeset
   622
        }
hgs
parents:
diff changeset
   623
    else
hgs
parents:
diff changeset
   624
        {
hgs
parents:
diff changeset
   625
        // everything is processed
hgs
parents:
diff changeset
   626
        LOGSTRING2(" Libraries processed! Library count = %d", iLibraryCount);
hgs
parents:
diff changeset
   627
hgs
parents:
diff changeset
   628
        this->iLibrariesGathered = true;
62
hgs
parents: 51
diff changeset
   629
        LOGSTRING2("MemSamplerImpl::ProcessLibraries() - libraries gathered! Time: %d",iCount);
51
hgs
parents:
diff changeset
   630
hgs
parents:
diff changeset
   631
        return 0;
hgs
parents:
diff changeset
   632
        }
hgs
parents:
diff changeset
   633
    }
62
hgs
parents: 51
diff changeset
   634
    else
hgs
parents: 51
diff changeset
   635
        {
hgs
parents: 51
diff changeset
   636
        LOGSTRING("MemSamplerImpl::ProcessLibs() 0");
hgs
parents: 51
diff changeset
   637
        iHandledLibs =0;
hgs
parents: 51
diff changeset
   638
        }
hgs
parents: 51
diff changeset
   639
    return -1;
hgs
parents: 51
diff changeset
   640
    }
51
hgs
parents:
diff changeset
   641
#endif
62
hgs
parents: 51
diff changeset
   642
51
hgs
parents:
diff changeset
   643
inline TInt DMemSamplerImpl::EncodeNameCode()
hgs
parents:
diff changeset
   644
    {
hgs
parents:
diff changeset
   645
	sample[0] = 1;
hgs
parents:
diff changeset
   646
	sample[1] = 0xaa;
hgs
parents:
diff changeset
   647
	return 2;
hgs
parents:
diff changeset
   648
    }
hgs
parents:
diff changeset
   649
hgs
parents:
diff changeset
   650
inline TInt DMemSamplerImpl::EncodeDataCode()
hgs
parents:
diff changeset
   651
    {
hgs
parents:
diff changeset
   652
	sample[0] = 1;
hgs
parents:
diff changeset
   653
	sample[1] = 0xdd;
hgs
parents:
diff changeset
   654
	return 2;
hgs
parents:
diff changeset
   655
    }
hgs
parents:
diff changeset
   656
hgs
parents:
diff changeset
   657
inline TInt DMemSamplerImpl::EncodeTotalMemoryName()
hgs
parents:
diff changeset
   658
    {
hgs
parents:
diff changeset
   659
	this->iTotalMemoryNameOk = true;
hgs
parents:
diff changeset
   660
	
hgs
parents:
diff changeset
   661
	TUint8* size = &sample[0];
hgs
parents:
diff changeset
   662
	*size = 0;
hgs
parents:
diff changeset
   663
		
hgs
parents:
diff changeset
   664
	// encode name
hgs
parents:
diff changeset
   665
	this->sampleDescriptor.Zero();
hgs
parents:
diff changeset
   666
	this->sampleDescriptor.Append(_L("TOTAL_MEMORY"));
hgs
parents:
diff changeset
   667
	*size += this->sampleDescriptor.Size();
hgs
parents:
diff changeset
   668
		
hgs
parents:
diff changeset
   669
	// add id here
hgs
parents:
diff changeset
   670
	TUint32 id(0xbabbeaaa);
hgs
parents:
diff changeset
   671
	this->sampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32));
hgs
parents:
diff changeset
   672
	*size += sizeof(TUint32);
hgs
parents:
diff changeset
   673
	
hgs
parents:
diff changeset
   674
	// the size is the descriptor length + the size field
hgs
parents:
diff changeset
   675
	return ((TInt)(*size))+1;	
hgs
parents:
diff changeset
   676
    }
hgs
parents:
diff changeset
   677
hgs
parents:
diff changeset
   678
inline TInt DMemSamplerImpl::EncodeTotalMemory()
hgs
parents:
diff changeset
   679
    {	
hgs
parents:
diff changeset
   680
	TUint8* size = &sample[0];
hgs
parents:
diff changeset
   681
	*size = 0;
hgs
parents:
diff changeset
   682
hgs
parents:
diff changeset
   683
	NKern::LockSystem();
hgs
parents:
diff changeset
   684
	TInt freeRam = Kern::FreeRamInBytes();
hgs
parents:
diff changeset
   685
	TInt totalRam = Kern::SuperPage().iTotalRamSize;
hgs
parents:
diff changeset
   686
	NKern::UnlockSystem();
hgs
parents:
diff changeset
   687
hgs
parents:
diff changeset
   688
	this->sampleDescriptor.Zero();
hgs
parents:
diff changeset
   689
	
hgs
parents:
diff changeset
   690
	TUint32 id(0xbabbeaaa);
hgs
parents:
diff changeset
   691
	TInt zero(0);
hgs
parents:
diff changeset
   692
		
hgs
parents:
diff changeset
   693
	this->sampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32));
hgs
parents:
diff changeset
   694
	*size += sizeof(TUint);
hgs
parents:
diff changeset
   695
	
hgs
parents:
diff changeset
   696
	this->sampleDescriptor.Append((TUint8*)&(totalRam),sizeof(TInt));
hgs
parents:
diff changeset
   697
	*size += sizeof(TInt);
hgs
parents:
diff changeset
   698
		
hgs
parents:
diff changeset
   699
	// append the cell amount allocated
hgs
parents:
diff changeset
   700
	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
hgs
parents:
diff changeset
   701
	*size += sizeof(TInt);
hgs
parents:
diff changeset
   702
	
hgs
parents:
diff changeset
   703
	// append the chunk size
hgs
parents:
diff changeset
   704
	this->sampleDescriptor.Append((TUint8*)&(freeRam),sizeof(TInt));
hgs
parents:
diff changeset
   705
	*size += sizeof(TInt);
hgs
parents:
diff changeset
   706
		
hgs
parents:
diff changeset
   707
	// append the thread user stack size
hgs
parents:
diff changeset
   708
	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
hgs
parents:
diff changeset
   709
	*size += sizeof(TInt);
hgs
parents:
diff changeset
   710
hgs
parents:
diff changeset
   711
	this->iTotalMemoryOk = true;
hgs
parents:
diff changeset
   712
hgs
parents:
diff changeset
   713
	return ((TInt)(*size))+1;
hgs
parents:
diff changeset
   714
    }
hgs
parents:
diff changeset
   715
hgs
parents:
diff changeset
   716
inline TInt DMemSamplerImpl::EncodeChunkName(DChunk& c)
hgs
parents:
diff changeset
   717
    {	
hgs
parents:
diff changeset
   718
	// the size of the following name is in the first byte
hgs
parents:
diff changeset
   719
	TUint8* size = &sample[0];
hgs
parents:
diff changeset
   720
	*size = 0;
hgs
parents:
diff changeset
   721
		
hgs
parents:
diff changeset
   722
	// encode chunk name
hgs
parents:
diff changeset
   723
	this->sampleDescriptor.Zero();
hgs
parents:
diff changeset
   724
	this->sampleDescriptor.Append(_L("C_"));
hgs
parents:
diff changeset
   725
	c.TraceAppendFullName(this->sampleDescriptor,false);
hgs
parents:
diff changeset
   726
	*size += this->sampleDescriptor.Size();
hgs
parents:
diff changeset
   727
		
hgs
parents:
diff changeset
   728
	// add chunk object address here
hgs
parents:
diff changeset
   729
	TUint32 chunkAddr((TUint32)&c);
hgs
parents:
diff changeset
   730
	this->sampleDescriptor.Append((TUint8*)&(chunkAddr),sizeof(TUint32));
hgs
parents:
diff changeset
   731
	*size += sizeof(TUint32);
hgs
parents:
diff changeset
   732
hgs
parents:
diff changeset
   733
	// the size is the descriptor length + the size field
hgs
parents:
diff changeset
   734
	LOGSTRING2("Non-Heap Chunk Name - %d",*size);
62
hgs
parents: 51
diff changeset
   735
	return ((TInt)(*size))+1;
51
hgs
parents:
diff changeset
   736
    }
hgs
parents:
diff changeset
   737
hgs
parents:
diff changeset
   738
inline TInt DMemSamplerImpl::EncodeChunkName(DThread& t)
hgs
parents:
diff changeset
   739
    {		
hgs
parents:
diff changeset
   740
	// the size of the following name is in the first byte
hgs
parents:
diff changeset
   741
	TUint8* size = &sample[0];
hgs
parents:
diff changeset
   742
	*size = 0;
hgs
parents:
diff changeset
   743
	this->sampleDescriptor.Zero();
hgs
parents:
diff changeset
   744
	
hgs
parents:
diff changeset
   745
	this->sampleDescriptor.Append(_L("T_"));
hgs
parents:
diff changeset
   746
	t.TraceAppendFullName(this->sampleDescriptor,false);
hgs
parents:
diff changeset
   747
	*size += this->sampleDescriptor.Size();
hgs
parents:
diff changeset
   748
	
hgs
parents:
diff changeset
   749
	// copy the 4 bytes from the thread id field
hgs
parents:
diff changeset
   750
	this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
hgs
parents:
diff changeset
   751
	*size += sizeof(TUint);
hgs
parents:
diff changeset
   752
hgs
parents:
diff changeset
   753
	// the size is the descriptor length + the size field
hgs
parents:
diff changeset
   754
	LOGSTRING2("Name - %d",*size);
hgs
parents:
diff changeset
   755
	return ((TInt)(*size))+1;
hgs
parents:
diff changeset
   756
    }
hgs
parents:
diff changeset
   757
#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
hgs
parents:
diff changeset
   758
inline TInt DMemSamplerImpl::EncodeChunkName(DLibrary& l)
hgs
parents:
diff changeset
   759
    {   
hgs
parents:
diff changeset
   760
    // the size of the following name is in the first byte
hgs
parents:
diff changeset
   761
    TUint8* size = &sample[0];
hgs
parents:
diff changeset
   762
    *size = 0;
hgs
parents:
diff changeset
   763
        
hgs
parents:
diff changeset
   764
    // encode library name
hgs
parents:
diff changeset
   765
    this->sampleDescriptor.Zero();
hgs
parents:
diff changeset
   766
    this->sampleDescriptor.Append(_L("L_"));
hgs
parents:
diff changeset
   767
    l.TraceAppendFullName(this->sampleDescriptor,false);
hgs
parents:
diff changeset
   768
    *size += this->sampleDescriptor.Size();
hgs
parents:
diff changeset
   769
        
hgs
parents:
diff changeset
   770
    // add chunk object address here
hgs
parents:
diff changeset
   771
    TUint32 libAddr((TUint32)&l);
hgs
parents:
diff changeset
   772
    this->sampleDescriptor.Append((TUint8*)&(libAddr),sizeof(TUint32));
hgs
parents:
diff changeset
   773
    *size += sizeof(TUint32);
hgs
parents:
diff changeset
   774
hgs
parents:
diff changeset
   775
    // the size is the descriptor length + the size field
hgs
parents:
diff changeset
   776
    LOGSTRING2("Name - %d",*size);
hgs
parents:
diff changeset
   777
    return ((TInt)(*size))+1;           
hgs
parents:
diff changeset
   778
    }
hgs
parents:
diff changeset
   779
#endif
hgs
parents:
diff changeset
   780
inline TInt DMemSamplerImpl::EncodeChunkData(DChunk& c)
hgs
parents:
diff changeset
   781
    {
hgs
parents:
diff changeset
   782
	// the size of the following name is in the first byte
hgs
parents:
diff changeset
   783
	TUint8* size = &sample[0];
hgs
parents:
diff changeset
   784
	*size = 0;
62
hgs
parents: 51
diff changeset
   785
	
hgs
parents: 51
diff changeset
   786
    TInt zero(0);
51
hgs
parents:
diff changeset
   787
	this->sampleDescriptor.Zero();
hgs
parents:
diff changeset
   788
	TUint32 address((TUint32)&c);
hgs
parents:
diff changeset
   789
		
hgs
parents:
diff changeset
   790
	this->sampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
62
hgs
parents: 51
diff changeset
   791
	*size += sizeof(TUint32);
hgs
parents: 51
diff changeset
   792
	LOGSTRING2("address - 0x%04x",&address);
51
hgs
parents:
diff changeset
   793
	// copy the total amount of memory allocated
hgs
parents:
diff changeset
   794
	this->sampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt));
hgs
parents:
diff changeset
   795
	*size += sizeof(TInt);
hgs
parents:
diff changeset
   796
		
hgs
parents:
diff changeset
   797
	// append the cell amount allocated
hgs
parents:
diff changeset
   798
	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
hgs
parents:
diff changeset
   799
	*size += sizeof(TInt);
hgs
parents:
diff changeset
   800
	
hgs
parents:
diff changeset
   801
	// append the chunk size
hgs
parents:
diff changeset
   802
	this->sampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TUint));
hgs
parents:
diff changeset
   803
	*size += sizeof(TUint);
hgs
parents:
diff changeset
   804
		
hgs
parents:
diff changeset
   805
	// append the thread user stack size
hgs
parents:
diff changeset
   806
	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
hgs
parents:
diff changeset
   807
	*size += sizeof(TInt);
hgs
parents:
diff changeset
   808
62
hgs
parents: 51
diff changeset
   809
	LOGSTRING2("chunk Data - %d",*size);
51
hgs
parents:
diff changeset
   810
	return ((TInt)(*size))+1;
hgs
parents:
diff changeset
   811
    }
hgs
parents:
diff changeset
   812
hgs
parents:
diff changeset
   813
inline TInt DMemSamplerImpl::EncodeChunkData(DThread& t)
hgs
parents:
diff changeset
   814
    {
hgs
parents:
diff changeset
   815
	// the size of the following name is in the first byte
hgs
parents:
diff changeset
   816
	TUint8* size = &sample[0];
hgs
parents:
diff changeset
   817
	*size = 0;
62
hgs
parents: 51
diff changeset
   818
    TInt zero(0);
51
hgs
parents:
diff changeset
   819
	this->sampleDescriptor.Zero();
62
hgs
parents: 51
diff changeset
   820
	//LOGTEXT("MemSamplerImpl::EncodeChunkData - cleared");
51
hgs
parents:
diff changeset
   821
hgs
parents:
diff changeset
   822
	this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
hgs
parents:
diff changeset
   823
	*size += sizeof(TUint);
hgs
parents:
diff changeset
   824
		
hgs
parents:
diff changeset
   825
	// copy the total amount of memory allocated for user side stack
hgs
parents:
diff changeset
   826
	this->sampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
hgs
parents:
diff changeset
   827
	*size += sizeof(TInt);
hgs
parents:
diff changeset
   828
62
hgs
parents: 51
diff changeset
   829
51
hgs
parents:
diff changeset
   830
	// append the cell amount allocated (zero, not in use here)
hgs
parents:
diff changeset
   831
	this->sampleDescriptor.Append((TUint8*)&zero,sizeof(TInt));
hgs
parents:
diff changeset
   832
	*size += sizeof(TInt);
hgs
parents:
diff changeset
   833
	
hgs
parents:
diff changeset
   834
	// append the chunk size (this is not a chunk)
hgs
parents:
diff changeset
   835
	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TUint));
hgs
parents:
diff changeset
   836
	*size += sizeof(TUint);
hgs
parents:
diff changeset
   837
hgs
parents:
diff changeset
   838
	// append user stack (max) size
hgs
parents:
diff changeset
   839
	this->sampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
hgs
parents:
diff changeset
   840
	*size += sizeof(TInt);
hgs
parents:
diff changeset
   841
hgs
parents:
diff changeset
   842
	LOGSTRING2("Data -> %d",*size);
hgs
parents:
diff changeset
   843
	return ((TInt)(*size))+1;
hgs
parents:
diff changeset
   844
    }
hgs
parents:
diff changeset
   845
#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
hgs
parents:
diff changeset
   846
inline TInt DMemSamplerImpl::EncodeChunkData(DLibrary& l)
hgs
parents:
diff changeset
   847
    {
hgs
parents:
diff changeset
   848
    LOGTEXT("MemSamplerImpl::EncodeChunkData (Library) - entry");
hgs
parents:
diff changeset
   849
    // the size of the following name is in the first byte
hgs
parents:
diff changeset
   850
    TUint8* size = &sample[0];
hgs
parents:
diff changeset
   851
    *size = 0;
hgs
parents:
diff changeset
   852
    this->sampleDescriptor.Zero();
hgs
parents:
diff changeset
   853
    
hgs
parents:
diff changeset
   854
    TUint32 address((TUint32)&l);
hgs
parents:
diff changeset
   855
        
hgs
parents:
diff changeset
   856
    this->sampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
hgs
parents:
diff changeset
   857
    *size += sizeof(TUint);
hgs
parents:
diff changeset
   858
             
hgs
parents:
diff changeset
   859
	this->sampleDescriptor.Append((TUint8*)&(l.iCodeSeg->iSize),sizeof(TUint32));
hgs
parents:
diff changeset
   860
    *size += sizeof(TInt); 
hgs
parents:
diff changeset
   861
             
hgs
parents:
diff changeset
   862
    this->sampleDescriptor.Append((TUint8*)&(l.iMapCount),sizeof(TInt));
hgs
parents:
diff changeset
   863
    *size += sizeof(TInt);  
hgs
parents:
diff changeset
   864
        
hgs
parents:
diff changeset
   865
    TInt zero(0);   
hgs
parents:
diff changeset
   866
    this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
hgs
parents:
diff changeset
   867
    *size += sizeof(TInt);   
hgs
parents:
diff changeset
   868
        
hgs
parents:
diff changeset
   869
    this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
hgs
parents:
diff changeset
   870
    *size += sizeof(TInt);   
hgs
parents:
diff changeset
   871
hgs
parents:
diff changeset
   872
    LOGSTRING2("LData - %d",*size);
hgs
parents:
diff changeset
   873
    return ((TInt)(*size))+1;
hgs
parents:
diff changeset
   874
hgs
parents:
diff changeset
   875
    }
hgs
parents:
diff changeset
   876
#endif
hgs
parents:
diff changeset
   877
void DMemSamplerImpl::Reset()
hgs
parents:
diff changeset
   878
    {
62
hgs
parents: 51
diff changeset
   879
    LOGSTRING("MemSamplerImpl::Reset - entry");
51
hgs
parents:
diff changeset
   880
	iCount = 0; // sample threads 1 cycle after actual MEM sample time...
62
hgs
parents: 51
diff changeset
   881
    this->iTimeToSample = true;
51
hgs
parents:
diff changeset
   882
    this->iChunkCount = 0;
hgs
parents:
diff changeset
   883
	this->iNewChunkCount = 0;
hgs
parents:
diff changeset
   884
	
hgs
parents:
diff changeset
   885
	this->iTotalMemoryOk = false;
hgs
parents:
diff changeset
   886
	this->iTotalMemoryNameOk = false;
hgs
parents:
diff changeset
   887
hgs
parents:
diff changeset
   888
	this->iChunksProcessing = ENothingToProcess;
hgs
parents:
diff changeset
   889
    this->iThreadsProcessing = ENothingToProcess;
hgs
parents:
diff changeset
   890
#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
hgs
parents:
diff changeset
   891
    this->iLibrariesProcessing = ENothingToProcess;
62
hgs
parents: 51
diff changeset
   892
#else
51
hgs
parents:
diff changeset
   893
    this->iSampleType = ESampleThreads;
62
hgs
parents: 51
diff changeset
   894
    //this->iSampleType = ESampleChunks;
hgs
parents: 51
diff changeset
   895
    //this->iSampleThreads = true;
51
hgs
parents:
diff changeset
   896
#endif
62
hgs
parents: 51
diff changeset
   897
    this->sampleDescriptor.Zero();
hgs
parents: 51
diff changeset
   898
    // clear all chunk tags
51
hgs
parents:
diff changeset
   899
    NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
hgs
parents:
diff changeset
   900
	DObjectCon* chunks = Kern::Containers()[EChunk];
hgs
parents:
diff changeset
   901
    chunks->Wait(); // Obtain the container mutex so the list does get changed under us
hgs
parents:
diff changeset
   902
hgs
parents:
diff changeset
   903
	TInt totalChunkCount = chunks->Count();
hgs
parents:
diff changeset
   904
	for(TInt i=0;i<totalChunkCount;i++)
hgs
parents:
diff changeset
   905
	    {
hgs
parents:
diff changeset
   906
		DChunk* c = (DChunk*)(*chunks)[i];
hgs
parents:
diff changeset
   907
		TAG(c) = 0;
hgs
parents:
diff changeset
   908
	    }
hgs
parents:
diff changeset
   909
	chunks->Signal();  // Release the container mutex
hgs
parents:
diff changeset
   910
62
hgs
parents: 51
diff changeset
   911
	LOGSTRING("MemSamplerImpl::Reset");
51
hgs
parents:
diff changeset
   912
	this->iThreadCount = 0;
hgs
parents:
diff changeset
   913
	this->iNewThreadCount = 0;
hgs
parents:
diff changeset
   914
	this->sampleDescriptor.Zero();
hgs
parents:
diff changeset
   915
62
hgs
parents: 51
diff changeset
   916
	// clear all thread tags
51
hgs
parents:
diff changeset
   917
	DObjectCon* threads = Kern::Containers()[EThread];
hgs
parents:
diff changeset
   918
    threads->Wait(); // Obtain the container mutex so the list does get changed under us
hgs
parents:
diff changeset
   919
hgs
parents:
diff changeset
   920
	TInt totalThreadCount = threads->Count();
hgs
parents:
diff changeset
   921
	for(TInt i=0;i<totalThreadCount;i++)
hgs
parents:
diff changeset
   922
	    {
hgs
parents:
diff changeset
   923
		DThread* t = (DThread*)(*threads)[i];
hgs
parents:
diff changeset
   924
		TAG(t) = (TAG(t) & 0xfffffffe);
hgs
parents:
diff changeset
   925
	    }
hgs
parents:
diff changeset
   926
	threads->Signal();  // Release the container mutex
hgs
parents:
diff changeset
   927
	
hgs
parents:
diff changeset
   928
#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
hgs
parents:
diff changeset
   929
	this->iLibraryCount = 0;
hgs
parents:
diff changeset
   930
	this->iNewLibraryCount = 0;
hgs
parents:
diff changeset
   931
	this->sampleDescriptor.Zero();
hgs
parents:
diff changeset
   932
hgs
parents:
diff changeset
   933
	// clear all library tags
hgs
parents:
diff changeset
   934
	DObjectCon* libs = Kern::Containers()[ELibrary];
hgs
parents:
diff changeset
   935
	libs->Wait(); // Obtain the container mutex so the list does get changed under us
hgs
parents:
diff changeset
   936
hgs
parents:
diff changeset
   937
	TInt totalLibraryCount = libs->Count();
hgs
parents:
diff changeset
   938
	for(TInt i=0; i<totalLibraryCount; i++)
hgs
parents:
diff changeset
   939
	    {
hgs
parents:
diff changeset
   940
        DLibrary* l = (DLibrary*)(*libs)[i];
hgs
parents:
diff changeset
   941
        TAG(l) = (TAG(l) & 0xefffffff);
hgs
parents:
diff changeset
   942
	    }
hgs
parents:
diff changeset
   943
	libs->Signal();  // Release the container mutex
hgs
parents:
diff changeset
   944
#endif
hgs
parents:
diff changeset
   945
hgs
parents:
diff changeset
   946
    NKern::ThreadLeaveCS();  // End of critical section
hgs
parents:
diff changeset
   947
    }
hgs
parents:
diff changeset
   948
62
hgs
parents: 51
diff changeset
   949
hgs
parents: 51
diff changeset
   950
// end of file