1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/debug/crashMonitor/src/scmconfig.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,458 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\debug\crashMonitor\src\scmconfig.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +/**
1.22 + @file
1.23 + @internalTechnology
1.24 +*/
1.25 +
1.26 +#include <e32err.h>
1.27 +#include <e32const.h>
1.28 +#include <e32const_private.h>
1.29 +
1.30 +#include <scmconfig.h>
1.31 +#include <scmconfigitem.h>
1.32 +#include <scmdatatypes.h>
1.33 +
1.34 +namespace Debug
1.35 + {
1.36 + /**
1.37 + * SCMConfiguration constructor
1.38 + * Initialises the configuration object to default values
1.39 + */
1.40 + SCMConfiguration::SCMConfiguration()
1.41 + : iConfigList(NULL)
1.42 + {
1.43 + }
1.44 +
1.45 + /**
1.46 + * SCMConfiguration destructor
1.47 + */
1.48 + SCMConfiguration::~SCMConfiguration()
1.49 + {
1.50 + ClearList();
1.51 + }
1.52 +
1.53 + /**
1.54 + * Goes to the flash and reads the configuration block and populates the object state
1.55 + * accordingly
1.56 + * @return one of the system wide error codes
1.57 + */
1.58 + TInt SCMConfiguration::Deserialize(TByteStreamReader& aReader)
1.59 + {
1.60 + if( !iConfigList)
1.61 + {
1.62 + // we need to set up a default configuration to load the data into
1.63 + TInt err = SetDefaultConfig();
1.64 + if(err != KErrNone)
1.65 + {
1.66 + CLTRACE1("SCMConfiguration::Deserialize SetDefaultConfig failed err = %d", err);
1.67 + return err;
1.68 + }
1.69 + }
1.70 +
1.71 + TInt startPos = aReader.CurrentPosition();
1.72 +
1.73 + TBuf8<10> magicNumbers;
1.74 + // try and read the magic numbers - if they dont exist then
1.75 + // there is not an scm config there
1.76 + const TInt KLen = KScmConfigHeaderString().Length();
1.77 + for(TInt i=0;i<KLen;i++)
1.78 + {
1.79 + TUint8 b = aReader.ReadByte();
1.80 + magicNumbers.Append(TChar(b));
1.81 + }
1.82 +
1.83 + if(magicNumbers.Compare(KScmConfigHeaderString()) != 0)
1.84 + {
1.85 + CLTRACE("No scm, config to read !");
1.86 + return KErrNotReady;
1.87 + }
1.88 +
1.89 + TConfigItem* item = iConfigList;
1.90 + while(item)
1.91 + {
1.92 + item->Deserialize(aReader);
1.93 + item = item->iNext;
1.94 + }
1.95 +
1.96 + TInt endPos = aReader.CurrentPosition();
1.97 + if( endPos - startPos != GetSize())
1.98 + {
1.99 + // error between actual size & real size in data
1.100 + CLTRACE("SCMConfiguration::Deserialize size error");
1.101 + return KErrCorrupt;
1.102 + }
1.103 + return KErrNone;
1.104 + }
1.105 +
1.106 + /**
1.107 + * This writes the current configuration object state to flash. This configuration will be used on the next crash
1.108 + * @return one of the system wide error codes
1.109 + */
1.110 + TInt SCMConfiguration::Serialize(TByteStreamWriter& aWriter)
1.111 + {
1.112 + if( !iConfigList)
1.113 + {
1.114 + CLTRACE("SCMConfiguration::Serialize ERROR - NO LIST!!");
1.115 + return KErrNotReady;
1.116 + }
1.117 +
1.118 + TInt startPos = aWriter.CurrentPosition();
1.119 +
1.120 + // write the number of crashes and magic numbers
1.121 +
1.122 + // try and read the magic numbers - if they dont exist then
1.123 + // there is not an scm config there
1.124 + const TInt KLen = KScmConfigHeaderString().Length();
1.125 + const TDesC8& des = KScmConfigHeaderString();
1.126 + for(TInt i=0;i<KLen;i++)
1.127 + {
1.128 + aWriter.WriteByte(des[i]);
1.129 + }
1.130 +
1.131 + TConfigItem* item = iConfigList;
1.132 + while(item)
1.133 + {
1.134 + item->Serialize(aWriter);
1.135 + item = item->iNext;
1.136 + }
1.137 +
1.138 + TInt endPos = aWriter.CurrentPosition();
1.139 + if( endPos - startPos != GetSize())
1.140 + {
1.141 + // error between actual size & real size in data
1.142 + CLTRACE("SCMConfiguration::Serialize size error");
1.143 + return KErrCorrupt;
1.144 + }
1.145 + return KErrNone;
1.146 + }
1.147 +
1.148 + /**
1.149 + * Returns entire size of the SCMConfiguration block
1.150 + * @return Size
1.151 + */
1.152 + TInt SCMConfiguration::GetSize() const
1.153 + {
1.154 + // returns the size of all the config items when serialized to disk / flash
1.155 + return (TConfigItem::ELast * iConfigList->GetSize()) + KScmConfigHeaderString().Length();
1.156 + }
1.157 +
1.158 + /**
1.159 + * This will return, one at a time, the highest priority.
1.160 + * @see ResetToHighestPriority()
1.161 + * @param aSizeToDump this will contain the size in bytes of data to dump for this type - 0 means dump all
1.162 + * @return Data type to dump
1.163 + */
1.164 + TConfigItem* SCMConfiguration::GetNextItem()
1.165 + {
1.166 + if(!iNextItem)
1.167 + {
1.168 + return NULL;
1.169 + }
1.170 +
1.171 + //get the values we need
1.172 + TConfigItem* item = iNextItem;
1.173 +
1.174 + //Now move iNextItem to be next in the list
1.175 + iNextItem = iNextItem->iNext;
1.176 + return item;
1.177 + }
1.178 +
1.179 + /**
1.180 + * Deletes the linked list
1.181 + * @return system wide OS code
1.182 + */
1.183 + void SCMConfiguration::ClearList()
1.184 + {
1.185 + if(!iConfigList)
1.186 + {
1.187 + return;
1.188 + }
1.189 +
1.190 + //all we need to do in here is delete the members of our linked list
1.191 + TConfigItem* item = iConfigList;
1.192 +
1.193 + do{
1.194 + TConfigItem* tmp = item->iNext;
1.195 + delete item;
1.196 + item = tmp;
1.197 + }
1.198 + while(item != NULL);
1.199 +
1.200 + iConfigList = NULL;
1.201 + }
1.202 +
1.203 + /**
1.204 + * Rather than reading the configuration from the flash, this method sets up the configuration object
1.205 + * to a default configuration type
1.206 + * @return one of the system wide error codes
1.207 + */
1.208 + TInt SCMConfiguration::SetDefaultConfig()
1.209 + {
1.210 + //flush the object first
1.211 + ClearList();
1.212 +
1.213 + //This is a predefined default config - in the future we may have multiple defaults based on use case
1.214 + // currently however we use a fixed size list of config items of size TConfigItem::ELast
1.215 + // also the TSCMDataType of each item must be unique
1.216 +
1.217 + for(TInt cnt = TConfigItem::ELast - 1; cnt >= 0; cnt --)
1.218 + {
1.219 + TInt priority = cnt + 1;
1.220 +
1.221 + //Lets not do these by default
1.222 + if((TConfigItem::TSCMDataType)cnt == TConfigItem::EThreadsUsrStack || (TConfigItem::TSCMDataType)cnt == TConfigItem::EThreadsSvrStack)
1.223 + {
1.224 + priority = 0;
1.225 + }
1.226 +
1.227 + //set it with the priority of its enum (ie. assume that the enum is listed in its priority - it is)
1.228 + //by default dump everything until we run out of space
1.229 + TInt err = CreateConfigItem((TConfigItem::TSCMDataType)cnt, priority, 0);
1.230 + if(KErrNone != err)
1.231 + {
1.232 + return err;
1.233 + }
1.234 + }
1.235 +
1.236 + return KErrNone;
1.237 + }
1.238 +
1.239 + /**
1.240 + * This configures the required data for a given configuration item
1.241 + * Note that aSizeToDump is only used in the case of memory dumps such as stacks
1.242 + * @param aDataType - Type of data to dump
1.243 + * @param aPriority - its priority 0-256. 0 Means do not dump and 256 is highest priority
1.244 + * @param aSizeToDump - amount in bytes to dump. Only relevant for memory dumps and ignored when aPriority is 0
1.245 + * @return one of the OS wide return codes
1.246 + */
1.247 + TInt SCMConfiguration::CreateConfigItem(const TConfigItem::TSCMDataType aDataType, const TUint8 aPriority, const TInt32 aSizeToDump)
1.248 + {
1.249 + //create the config item
1.250 + TConfigItem* item = new TConfigItem(aDataType, aPriority, aSizeToDump);
1.251 +
1.252 + //insert to priority list
1.253 + return InsertToList(item);
1.254 + }
1.255 +
1.256 +
1.257 + /**
1.258 + * ModifyConfigItemPriority - modifies prioity for a given configuration item
1.259 + * @param aDataType - The unique type of the config item
1.260 + * @param aPriority - its priority 0-256. 0 Means do not dump and 256 is highest priority
1.261 + * @return one of the OS wide return codes
1.262 + */
1.263 + TInt SCMConfiguration::ModifyConfigItemPriority(const TConfigItem::TSCMDataType aDataType, const TUint8 aPriority)
1.264 + {
1.265 +
1.266 + // find the item with the matching data type
1.267 + TConfigItem* item = iConfigList;
1.268 + while(item)
1.269 + {
1.270 + if(item->iDataType == aDataType)
1.271 + {
1.272 + break;
1.273 + }
1.274 + item = item->iNext;
1.275 + }
1.276 +
1.277 + if(!item)
1.278 + {
1.279 + return KErrNotFound;
1.280 + }
1.281 +
1.282 + item->iPriority = aPriority;
1.283 +
1.284 + // now reorder the list according to new priority
1.285 + TInt err = RemoveFromList(item);
1.286 + if(err != KErrNone)
1.287 + {
1.288 + return err;
1.289 + }
1.290 +
1.291 + err = InsertToList(item);
1.292 +
1.293 + if(err != KErrNone)
1.294 + {
1.295 + return err;
1.296 + }
1.297 +
1.298 + return KErrNone;
1.299 + }
1.300 +
1.301 +/**
1.302 + * Removes item from the linked list
1.303 + * @param aItem - item to remove
1.304 + * @return OS code
1.305 + */
1.306 +TInt SCMConfiguration::RemoveFromList(TConfigItem* aItem)
1.307 + {
1.308 + if(!aItem)
1.309 + {
1.310 + return KErrArgument;
1.311 + }
1.312 +
1.313 + if(!iConfigList)
1.314 + {
1.315 + return KErrCorrupt; // oops no list to remove
1.316 + }
1.317 +
1.318 +
1.319 + if(aItem == iConfigList)
1.320 + {
1.321 + // special case remove from beginning of list
1.322 + iConfigList = iConfigList->iNext;
1.323 + return KErrNone;
1.324 + }
1.325 +
1.326 + TConfigItem* item = iConfigList;
1.327 + while(item)
1.328 + {
1.329 + // is the next item the match ?
1.330 + if(item->iNext == aItem)
1.331 + {
1.332 + item->iNext = aItem->iNext;
1.333 + return KErrNone;
1.334 + }
1.335 + item = item->iNext;
1.336 + }
1.337 +
1.338 + return KErrNotFound;
1.339 + }
1.340 +
1.341 +/**
1.342 + * Inserts a priority item into the linked list in its correct location
1.343 + * @param aItem - item to insert
1.344 + * @return OS code
1.345 + */
1.346 +TInt SCMConfiguration::InsertToList(TConfigItem* aItem)
1.347 + {
1.348 +
1.349 + //if the list is empty, then this is the only item
1.350 + if(!iConfigList)
1.351 + {
1.352 + iConfigList = aItem;
1.353 + return KErrNone;
1.354 + }
1.355 +
1.356 + //should it go at the start? special case not covered by while loop
1.357 + TConfigItem* temp;
1.358 +
1.359 + if(aItem->iPriority >= iConfigList->iPriority)
1.360 + {
1.361 + temp = iConfigList;
1.362 + iConfigList = aItem;
1.363 + aItem->iNext = temp;
1.364 + return KErrNone;
1.365 + }
1.366 +
1.367 + TConfigItem* item = iConfigList;
1.368 +
1.369 + do{
1.370 + //if we get to the end of the list and the item still hasnt been assigned then it must be lowest priority
1.371 + if(item->iNext == NULL)
1.372 + {
1.373 + item->iNext = aItem;
1.374 + return KErrNone;
1.375 + }
1.376 +
1.377 + //check if its priority is between these
1.378 + if(aItem->iPriority < item->iPriority && aItem->iPriority >= item->iNext->iPriority)
1.379 + {
1.380 + //insert between these nodes
1.381 + temp = item->iNext;
1.382 + item->iNext = aItem;
1.383 + aItem->iNext = temp;
1.384 + return KErrNone;
1.385 + }
1.386 +
1.387 + item = item->iNext;
1.388 + }
1.389 + while(item != NULL);
1.390 +
1.391 + //should never get here
1.392 + return KErrUnknown;
1.393 + }
1.394 +
1.395 +/**
1.396 + * This resets the next item counter back to the highest priority item in the list
1.397 + */
1.398 +void SCMConfiguration::ResetToHighestPriority()
1.399 + {
1.400 + //set the next item counter back to the head of the list
1.401 + iNextItem = iConfigList;
1.402 + }
1.403 +
1.404 +/**
1.405 + * Overloaded == operator
1.406 + * @param aOther Item to compare
1.407 + * @return
1.408 + */
1.409 +TBool SCMConfiguration::operator == (const SCMConfiguration& aOther) const
1.410 + {
1.411 +
1.412 + if(!iConfigList && !aOther.iConfigList)
1.413 + {
1.414 + return ETrue;
1.415 + }
1.416 +
1.417 + if((!iConfigList && aOther.iConfigList) || (iConfigList && !aOther.iConfigList))
1.418 + {
1.419 + return EFalse;
1.420 + }
1.421 +
1.422 +
1.423 + TConfigItem* item1 = iConfigList;
1.424 + TConfigItem* item2 = aOther.iConfigList;
1.425 +
1.426 + while(item1 && item2)
1.427 + {
1.428 + if(!(*item1 == *item2))
1.429 + {
1.430 + return EFalse;
1.431 + }
1.432 +
1.433 + item1 = item1->iNext;
1.434 + item2 = item2->iNext;
1.435 + }
1.436 +
1.437 + if( item1 != item2) // both should now be null - if not then lists were different lengths
1.438 + {
1.439 + return EFalse;
1.440 + }
1.441 +
1.442 + return ETrue;
1.443 +
1.444 + }
1.445 +
1.446 +/**
1.447 + * Getter for the head of the SCMConfig list
1.448 + * @return Head of List
1.449 + */
1.450 +TConfigItem* SCMConfiguration::ConfigList() const
1.451 + {
1.452 + // returns the head of the list
1.453 + return iConfigList;
1.454 + }
1.455 +} //End of debug namespace
1.456 +
1.457 +//eof
1.458 +
1.459 +
1.460 +
1.461 +