diff -r 000000000000 -r a41df078684a kernel/eka/debug/crashMonitor/src/scmconfig.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/debug/crashMonitor/src/scmconfig.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,458 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32\debug\crashMonitor\src\scmconfig.cpp +// +// + +/** + @file + @internalTechnology +*/ + +#include +#include +#include + +#include +#include +#include + +namespace Debug + { + /** + * SCMConfiguration constructor + * Initialises the configuration object to default values + */ + SCMConfiguration::SCMConfiguration() + : iConfigList(NULL) + { + } + + /** + * SCMConfiguration destructor + */ + SCMConfiguration::~SCMConfiguration() + { + ClearList(); + } + + /** + * Goes to the flash and reads the configuration block and populates the object state + * accordingly + * @return one of the system wide error codes + */ + TInt SCMConfiguration::Deserialize(TByteStreamReader& aReader) + { + if( !iConfigList) + { + // we need to set up a default configuration to load the data into + TInt err = SetDefaultConfig(); + if(err != KErrNone) + { + CLTRACE1("SCMConfiguration::Deserialize SetDefaultConfig failed err = %d", err); + return err; + } + } + + TInt startPos = aReader.CurrentPosition(); + + TBuf8<10> magicNumbers; + // try and read the magic numbers - if they dont exist then + // there is not an scm config there + const TInt KLen = KScmConfigHeaderString().Length(); + for(TInt i=0;iDeserialize(aReader); + item = item->iNext; + } + + TInt endPos = aReader.CurrentPosition(); + if( endPos - startPos != GetSize()) + { + // error between actual size & real size in data + CLTRACE("SCMConfiguration::Deserialize size error"); + return KErrCorrupt; + } + return KErrNone; + } + + /** + * This writes the current configuration object state to flash. This configuration will be used on the next crash + * @return one of the system wide error codes + */ + TInt SCMConfiguration::Serialize(TByteStreamWriter& aWriter) + { + if( !iConfigList) + { + CLTRACE("SCMConfiguration::Serialize ERROR - NO LIST!!"); + return KErrNotReady; + } + + TInt startPos = aWriter.CurrentPosition(); + + // write the number of crashes and magic numbers + + // try and read the magic numbers - if they dont exist then + // there is not an scm config there + const TInt KLen = KScmConfigHeaderString().Length(); + const TDesC8& des = KScmConfigHeaderString(); + for(TInt i=0;iSerialize(aWriter); + item = item->iNext; + } + + TInt endPos = aWriter.CurrentPosition(); + if( endPos - startPos != GetSize()) + { + // error between actual size & real size in data + CLTRACE("SCMConfiguration::Serialize size error"); + return KErrCorrupt; + } + return KErrNone; + } + + /** + * Returns entire size of the SCMConfiguration block + * @return Size + */ + TInt SCMConfiguration::GetSize() const + { + // returns the size of all the config items when serialized to disk / flash + return (TConfigItem::ELast * iConfigList->GetSize()) + KScmConfigHeaderString().Length(); + } + + /** + * This will return, one at a time, the highest priority. + * @see ResetToHighestPriority() + * @param aSizeToDump this will contain the size in bytes of data to dump for this type - 0 means dump all + * @return Data type to dump + */ + TConfigItem* SCMConfiguration::GetNextItem() + { + if(!iNextItem) + { + return NULL; + } + + //get the values we need + TConfigItem* item = iNextItem; + + //Now move iNextItem to be next in the list + iNextItem = iNextItem->iNext; + return item; + } + + /** + * Deletes the linked list + * @return system wide OS code + */ + void SCMConfiguration::ClearList() + { + if(!iConfigList) + { + return; + } + + //all we need to do in here is delete the members of our linked list + TConfigItem* item = iConfigList; + + do{ + TConfigItem* tmp = item->iNext; + delete item; + item = tmp; + } + while(item != NULL); + + iConfigList = NULL; + } + + /** + * Rather than reading the configuration from the flash, this method sets up the configuration object + * to a default configuration type + * @return one of the system wide error codes + */ + TInt SCMConfiguration::SetDefaultConfig() + { + //flush the object first + ClearList(); + + //This is a predefined default config - in the future we may have multiple defaults based on use case + // currently however we use a fixed size list of config items of size TConfigItem::ELast + // also the TSCMDataType of each item must be unique + + for(TInt cnt = TConfigItem::ELast - 1; cnt >= 0; cnt --) + { + TInt priority = cnt + 1; + + //Lets not do these by default + if((TConfigItem::TSCMDataType)cnt == TConfigItem::EThreadsUsrStack || (TConfigItem::TSCMDataType)cnt == TConfigItem::EThreadsSvrStack) + { + priority = 0; + } + + //set it with the priority of its enum (ie. assume that the enum is listed in its priority - it is) + //by default dump everything until we run out of space + TInt err = CreateConfigItem((TConfigItem::TSCMDataType)cnt, priority, 0); + if(KErrNone != err) + { + return err; + } + } + + return KErrNone; + } + + /** + * This configures the required data for a given configuration item + * Note that aSizeToDump is only used in the case of memory dumps such as stacks + * @param aDataType - Type of data to dump + * @param aPriority - its priority 0-256. 0 Means do not dump and 256 is highest priority + * @param aSizeToDump - amount in bytes to dump. Only relevant for memory dumps and ignored when aPriority is 0 + * @return one of the OS wide return codes + */ + TInt SCMConfiguration::CreateConfigItem(const TConfigItem::TSCMDataType aDataType, const TUint8 aPriority, const TInt32 aSizeToDump) + { + //create the config item + TConfigItem* item = new TConfigItem(aDataType, aPriority, aSizeToDump); + + //insert to priority list + return InsertToList(item); + } + + + /** + * ModifyConfigItemPriority - modifies prioity for a given configuration item + * @param aDataType - The unique type of the config item + * @param aPriority - its priority 0-256. 0 Means do not dump and 256 is highest priority + * @return one of the OS wide return codes + */ + TInt SCMConfiguration::ModifyConfigItemPriority(const TConfigItem::TSCMDataType aDataType, const TUint8 aPriority) + { + + // find the item with the matching data type + TConfigItem* item = iConfigList; + while(item) + { + if(item->iDataType == aDataType) + { + break; + } + item = item->iNext; + } + + if(!item) + { + return KErrNotFound; + } + + item->iPriority = aPriority; + + // now reorder the list according to new priority + TInt err = RemoveFromList(item); + if(err != KErrNone) + { + return err; + } + + err = InsertToList(item); + + if(err != KErrNone) + { + return err; + } + + return KErrNone; + } + +/** + * Removes item from the linked list + * @param aItem - item to remove + * @return OS code + */ +TInt SCMConfiguration::RemoveFromList(TConfigItem* aItem) + { + if(!aItem) + { + return KErrArgument; + } + + if(!iConfigList) + { + return KErrCorrupt; // oops no list to remove + } + + + if(aItem == iConfigList) + { + // special case remove from beginning of list + iConfigList = iConfigList->iNext; + return KErrNone; + } + + TConfigItem* item = iConfigList; + while(item) + { + // is the next item the match ? + if(item->iNext == aItem) + { + item->iNext = aItem->iNext; + return KErrNone; + } + item = item->iNext; + } + + return KErrNotFound; + } + +/** + * Inserts a priority item into the linked list in its correct location + * @param aItem - item to insert + * @return OS code + */ +TInt SCMConfiguration::InsertToList(TConfigItem* aItem) + { + + //if the list is empty, then this is the only item + if(!iConfigList) + { + iConfigList = aItem; + return KErrNone; + } + + //should it go at the start? special case not covered by while loop + TConfigItem* temp; + + if(aItem->iPriority >= iConfigList->iPriority) + { + temp = iConfigList; + iConfigList = aItem; + aItem->iNext = temp; + return KErrNone; + } + + TConfigItem* item = iConfigList; + + do{ + //if we get to the end of the list and the item still hasnt been assigned then it must be lowest priority + if(item->iNext == NULL) + { + item->iNext = aItem; + return KErrNone; + } + + //check if its priority is between these + if(aItem->iPriority < item->iPriority && aItem->iPriority >= item->iNext->iPriority) + { + //insert between these nodes + temp = item->iNext; + item->iNext = aItem; + aItem->iNext = temp; + return KErrNone; + } + + item = item->iNext; + } + while(item != NULL); + + //should never get here + return KErrUnknown; + } + +/** + * This resets the next item counter back to the highest priority item in the list + */ +void SCMConfiguration::ResetToHighestPriority() + { + //set the next item counter back to the head of the list + iNextItem = iConfigList; + } + +/** + * Overloaded == operator + * @param aOther Item to compare + * @return + */ +TBool SCMConfiguration::operator == (const SCMConfiguration& aOther) const + { + + if(!iConfigList && !aOther.iConfigList) + { + return ETrue; + } + + if((!iConfigList && aOther.iConfigList) || (iConfigList && !aOther.iConfigList)) + { + return EFalse; + } + + + TConfigItem* item1 = iConfigList; + TConfigItem* item2 = aOther.iConfigList; + + while(item1 && item2) + { + if(!(*item1 == *item2)) + { + return EFalse; + } + + item1 = item1->iNext; + item2 = item2->iNext; + } + + if( item1 != item2) // both should now be null - if not then lists were different lengths + { + return EFalse; + } + + return ETrue; + + } + +/** + * Getter for the head of the SCMConfig list + * @return Head of List + */ +TConfigItem* SCMConfiguration::ConfigList() const + { + // returns the head of the list + return iConfigList; + } +} //End of debug namespace + +//eof + + + +