Author: thebeing
Date: Wed Jul 15 10:41:14 2015
New Revision: 38798
URL: http://svn.gna.org/viewcvs/gnustep?rev=38798&view=rev
Log:
Implement an interface to export memory usage statistics by loading
a bundle. Controlled using the `MemoryLoggerBundle' defaults key.
Added:
libs/ec/trunk/EcMemoryLogger.h
Modified:
libs/ec/trunk/ChangeLog
libs/ec/trunk/EcProcess.m
libs/ec/trunk/GNUmakefile
Modified: libs/ec/trunk/ChangeLog
URL:
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/ChangeLog?rev=38798&r1=38797&r2=38798&view=diff
==============================================================================
--- libs/ec/trunk/ChangeLog (original)
+++ libs/ec/trunk/ChangeLog Wed Jul 15 10:41:14 2015
@@ -1,3 +1,9 @@
+2015-07-15 Niels Grewe <[email protected]>
+ * EcMemoryLogger.h
+ * EcProcess.m:
+ Add the ability to load a bundle to export memory logs to. Configured
+ using the 'MemoryLoggerBundle' default key.
+
2015-07-13 Richard Frith-Macdonald <[email protected]>
* EcProcess.h:
Added: libs/ec/trunk/EcMemoryLogger.h
URL:
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcMemoryLogger.h?rev=38798&view=auto
==============================================================================
--- libs/ec/trunk/EcMemoryLogger.h (added)
+++ libs/ec/trunk/EcMemoryLogger.h Wed Jul 15 10:41:14 2015
@@ -0,0 +1,48 @@
+
+/** Enterprise Control Configuration and Logging
+ -- memory logger protocol
+
+ Copyright (C) 2015 Free Software Foundation, Inc.
+
+ Written by: Niels Grewe <[email protected]>
+ Date: July 2015
+
+ This file is part of the GNUstep project.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02111 USA.
+
+ */
+
+#import <Foundation/NSObject.h>
+
+@class EcProcess;
+
+/**
+ * This protocol should be implemented by classes that want to receive
+ * callbacks about memory usage in the process. This feature is enabled
+ * by setting the MemoryLoggerBundle user default to a bundle whose
+ * principal class implements this protocol.
+ */
+@protocol EcMemoryLogger <NSObject>
+/**
+ * This callback is issued once per minute, with totalUsage representing
+ * the memory usage of the process and notLeaked the amount of memory
+ * accounted for as active by -ecNotLeaked. All values are in bytes.
+ */
+- (void)process: (EcProcess*)process
+ didUseMemory: (uint64_t)totalUsage
+ notLeaked: (uint64_t)notLeaked;
+@end
Modified: libs/ec/trunk/EcProcess.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcProcess.m?rev=38798&r1=38797&r2=38798&view=diff
==============================================================================
--- libs/ec/trunk/EcProcess.m (original)
+++ libs/ec/trunk/EcProcess.m Wed Jul 15 10:41:14 2015
@@ -59,6 +59,7 @@
#import "EcHost.h"
#import "EcUserDefaults.h"
#import "EcBroadcastProxy.h"
+#import "EcMemoryLogger.h"
#include "config.h"
@@ -130,6 +131,7 @@
static NSUserDefaults *cmdDefs = nil;
static NSString *cmdDebugName = nil;
static NSMutableDictionary *cmdLogMap = nil;
+static id<EcMemoryLogger> cmdMemoryLogger = nil;
static NSDate *started = nil; /* Time object was created. */
static NSDate *memStats = nil; /* Time stats were started. */
@@ -1055,8 +1057,51 @@
DESTROY(started);
DESTROY(userDir);
DESTROY(warningLogger);
- }
-}
+ DESTROY(cmdMemoryLogger);
+ }
+}
+
+
+- (Class)_memoryLoggerClassFromBundle: (NSString*)bundleName
+{
+ NSString *path = nil;
+ Class c = Nil;
+ NSBundle *bundle = nil;
+ NSArray *paths =
+ NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
+ NSAllDomainsMask,
+ YES);
+ NSEnumerator *e = [paths objectEnumerator];
+ while (nil != (path = [e nextObject]))
+ {
+ path = [path stringByAppendingPathComponent: @"Bundles"];
+ path = [path stringByAppendingPathComponent: bundleName];
+ path = [path stringByAppendingPathExtension: @"bundle"];
+ bundle = [NSBundle bundleWithPath: path];
+ if (bundle != nil)
+ {
+ break;
+ }
+ }
+ if (nil == bundle)
+ {
+ [self cmdWarn: @"Could not load bundle '%@'", bundleName];
+ }
+ else if (Nil == (c = [bundle principalClass]))
+ {
+ [self cmdWarn: @"Could not load principal class from %@ at %@.",
+ bundleName, path];
+ }
+ else if (NO == [c conformsToProtocol: @protocol(EcMemoryLogger)])
+ {
+ [self cmdWarn:
+ @"%@ does not implement the EcMemoryLogger protocol",
+ NSStringFromClass(c)];
+ c = Nil;
+ }
+ return c;
+}
+
+ (NSMutableDictionary*) ecInitialDefaults
{
@@ -4294,6 +4339,48 @@
}
}
+- (void)_ensureMemLogger
+{
+ NSString *bundle = [cmdDefs stringForKey: @"MemoryLoggerBundle"];
+ Class cls = Nil;
+ if (nil == bundle)
+ {
+ DESTROY(cmdMemoryLogger);
+ return;
+ }
+ // This is a reasonable fast path if we have already loaded the bundle
+ cls = NSClassFromString(bundle);
+ if ((Nil == cls)
+ || (NO == [cls conformsToProtocol: @protocol(EcMemoryLogger)]))
+ {
+ cls = [self _memoryLoggerClassFromBundle: bundle];
+ }
+ if (Nil == cls)
+ {
+ // No usable logger class, destroy any we might have
+ DESTROY(cmdMemoryLogger);
+ return;
+ }
+ if (NO == [cmdMemoryLogger isKindOfClass: cls])
+ {
+ // If it's no longer the right class, destroy it
+ DESTROY(cmdMemoryLogger);
+ }
+ if (nil == cmdMemoryLogger)
+ {
+ NS_DURING
+ {
+ cmdMemoryLogger = [cls new];
+ }
+ NS_HANDLER
+ {
+ [self cmdWarn: @"Exception creating memory logger: %@",
+ localException];
+ }
+ NS_ENDHANDLER
+ }
+}
+
- (void) _memCheck
{
BOOL memDebug = [cmdDefs boolForKey: @"Memory"];
@@ -4319,6 +4406,24 @@
fclose(fptr);
}
excLast = (uint64_t)[self ecNotLeaked];
+
+ [self _ensureMemLogger];
+ if (nil != cmdMemoryLogger)
+ {
+ NS_DURING
+ {
+ [cmdMemoryLogger process: self
+ didUseMemory: memLast
+ notLeaked: excLast];
+ }
+ NS_HANDLER
+ {
+ [self cmdWarn:
+ @"Exception logging memory usage to bundle: %@",
+ localException];
+ }
+ NS_ENDHANDLER
+ }
/* Do initial population so we can work immediately.
*/
Modified: libs/ec/trunk/GNUmakefile
URL:
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/GNUmakefile?rev=38798&r1=38797&r2=38798&view=diff
==============================================================================
--- libs/ec/trunk/GNUmakefile (original)
+++ libs/ec/trunk/GNUmakefile Wed Jul 15 10:41:14 2015
@@ -60,7 +60,7 @@
EcProcess.h \
EcTest.h \
EcUserDefaults.h \
-
+ EcMemoryLogger.h
TOOL_NAME = \
Command \
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs