Performance

2009-11-15 Thread Chris Carson
Hi all,

A performance related question:

I've written a Cocoa app that continuously reads data from a USB device and 
plots it on a graph. It consists of three of my own classes.

The first class is the model that submits asynchronous bulk reads to the USB 
device. The callback for these reads copies the received data from the buffer 
asynchronous filled by the request and into an NSData object that is allocated 
and added to an NSArray. The buffer that the asynchronous request was using is 
recycled into a new asynchronous request. So the pool of buffers is allocated 
once and reused while the NSData objects are continuously allocated and 
deallocated (when released by the controller).

The second class is the view that uses an NSTimer to call [self 
setNeedsDisplay:YES] 24 times per second. The drawRect: method requests data 
from the data source (the third, controller class) and draws it with OpenGL.

The third class is the controller class that serves as a data source for the 
view. When the view calls the giveMeData: method, the controller class calls 
the buffer: method in the model class, which removes and returns the oldest 
NSData object in its NSArray. The controller then does some computations on it 
and passes it off to the view in a new NSData object.

The application runs pretty well, and running it through the Leaks instrument 
there are no leaks except for 16-bytes when the application is first starting 
caused by IOUSBLib. However, looking at it in the Activity Monitor, the real 
memory used starts off at 25 MB and steadily grows to 250+ MB while the virtual 
memory starts off at about the same and steadily grows to about the same or 
sometimes close to 500MB, over the course of several minutes. This especially 
happens if I don't move the mouse for a while, or don't have the application in 
focus. As soon as a move the mouse or bring the application into focus, it's as 
if an autorelease pool is drained and the memory drops back down to 30-40MB 
real and 30-40MB virtual. This is annoying since the application hangs for 5 
seconds or so when this memory draining is occurring. Has anyone dealt with 
this before? Any ideas on what could be causing this and how to work around it?


Another related question:

The number of asynchronous requests that the driver submits at once and the 
maximum number of objects in the NSArray are set to some constant. Now in 
theory, the requests should be added and drained simultaneously (i.e. by 
separate threads), but if I make this constant larger, I notice a greater delay 
between when data entering the USB device and being plotted. It's as if the 
asynchronous requests are being filled and added to the NSArray all in a group, 
and then drained by the view all in a group... maybe? Is this something subtle 
from the way run loops work? Is the USB asynchronous bulk read run loop source 
on the same thread as the view class's drawRect method?


My apologies for the length of this post and if the USB stuff isn't strictly 
Cocoa related, but since it's so intertwined with Cocoa classes, I figured this 
was the best place to ask. Advice is much appreciated. Please CC me on replies.

Chris


  

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


usb notification

2009-09-08 Thread Chris Carson
Hi all,

Can't get a simple example working. AppearedNotificationHandler() should be 
called in the code below when a USB device (any device for now) is plugged in. 
I see the NSLog(@registerDeviceCallbackHandler) message appear in the console 
when I start the application, but never see the 
NSLog(@AppearedNotificationHandler) message when I plug in a device. What am 
I missing?

Note: The project's MainMenu.nib Interface Builder file has an NSObject whose 
class is USBDriver.


static void AppearedNotificationHandler (void * refCon, io_iterator_t iterator);

@interface USBDriver(Private)
- (void) registerDeviceCallbackHandler;
@end

@implementation USBDriver(Private)

- (void) registerDeviceCallbackHandler
{
IOReturnkernErr;
CFRunLoopSourceRef  runLoopSource;
CFMutableDictionaryRef  matchingDict = IOServiceMatching 
(kIOUSBDeviceClassName);
CFRunLoopRefrunLoop;

// Create the port on which we will receive notifications. We'll wrap 
it in a runLoopSource
// which we then feed into the runLoop for async event notifications.
deviceNotifyPort = IONotificationPortCreate (kIOMasterPortDefault);
if (deviceNotifyPort == NULL)
{
return;
}

// Get a runLoopSource for our mach port.
runLoopSource = IONotificationPortGetRunLoopSource (deviceNotifyPort);

matchingDict = (CFMutableDictionaryRef) CFRetain (matchingDict);

kernErr = IOServiceAddMatchingNotification (deviceNotifyPort,
kIOFirstMatchNotification,
matchingDict,
AppearedNotificationHandler,
(void *) self,
deviceAppearedIterator);

kernErr = IOServiceAddMatchingNotification (deviceNotifyPort,
kIOTerminatedNotification,
matchingDict,

DisappearedNotificationHandler,
(void *) self,
deviceDisappearedIterator 
);

// Get our runLoop
runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];

// Add our runLoopSource to our runLoop
CFRunLoopAddSource (runLoop, runLoopSource, kCFRunLoopDefaultMode);

NSLog(@registerDeviceCallbackHandler);
}

@end


@implementation USBDriver

- (id) init
{
[super init];

if (self) {
deviceNotifyPort= IO_OBJECT_NULL;
deviceAppearedIterator  = 0;

[self registerDeviceCallbackHandler];
}

return self;
}

@end

static void AppearedNotificationHandler (void * refCon, io_iterator_t iterator)
{
NSLog(@AppearedNotificationHandler);
}


Any help is much appreciated.

Thanks,
Chris


  

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: usb notification

2009-09-08 Thread Chris Carson
 IOReturnkernErr;
 
 You never seem to check for errors.  Please ensure
 your calls are
 succeeding by checking the value of this variable.  If
 they're
 failing, use macerror(1) to look up the error number.

IOServiceAddMatchingNotification() returns no errors (0).

  - (id) init
  {
 [super init];
 
 if (self) {
 
 This is not the correct initializer pattern.  You need
 to assign to self here.
 
 --Kyle Sluder

Changed this to self = [super init];

However, the issue still persists.

Chris


  

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


NSTableView bug?

2009-07-02 Thread Chris Carson

Hello,

I've created a simple application with an NSTableView. I have written a 
delegate for this table, 
numberOfRowsInTableView:objectValueForTableColumn:row:, that returns the number 
of rows in the table when requested.

My application uses the table view to display hexadecimal data on a flash 
memory chip, with 16 bytes displayed per row. As a test, I tried returning a 
large number for the number of rows, 0x100. When I scroll through the 
table, everything looks okay for the first 14 million rows or so, after which 
the gray horizonal cell separator disappears and the row data begins to shift 
by a pixel per row, until it eventually is superimposed on the row above it. 
This seems like a bug with the NSTableView class, but perhaps I'm doing 
something wrong. Has anyone else run into this problem?

Chris



  

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


instance management in IB

2009-05-11 Thread Chris Carson

Hello,

I've been scratching my head trying to get a basic delegate/data source 
Cocoa/AppKit program working and feel that I'm misunderstanding something basic 
(I've included the code is at the end).

I set a breakpoint within the if statement in the init method of MyModel and 
see it called more than once. The second time the debugger throws a 
EXC_BAD_ACCESS. This message goes away if I comment out the two lines in 
stepAnimation that call the getBuffer and getLength methods and then modify the 
buffer. All this makes me think that somehow the instance of MyModel is being 
deallocated as soon as the data source message returns, but before the data is 
copied into the pointBuffer.

I created an NSView and NSObject in Interface Builder, assigning the MyView 
subclass to the NSView object and MyModel to the NSObject object. Then I 
connected the dataSource outlet on MyView to th MyModel object.

What am I missing? How can I get the data from MyModel to be viewable my MyView?

Sidenote: Ultimately I'm trying to plot a real-time frequency spectrum. My plan 
is to pull in data over a CFMessagePort in the model and have the view access 
it view the data source.

Help is much appreciated!

Chris

main.m
--

int main(int argc, char *argv[]) {
// Launch Cocoa application
return NSApplicationMain(argc, (const char **) argv);
}

MyView.m:
--
@implementation MyView

- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
pointPath = [NSBezierPathbezierPath];
pointBuffer = malloc (sizeof(NSPoint) * 100);
[NSTimerscheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(stepAnimation:)
userInfo:nil
repeats:YES];
}
return self;
}

- (void)drawRect:(NSRect)rect {
[pointPath removeAllPoints];
[pointPathappendBezierPathWithPoints:(NSPointArray)pointBuffercount:100];
[pointPathstroke];
}

- (void)setDataSource:(id)inDataSource {
dataSource = inDataSource;
}

- (id)dataSource {
returndataSource;
}

- (void)stepAnimation:(NSTimer *)timer {
float*inBuffer;
int i, length;


// Fetch buffer pointer
inBuffer = [[self dataSource] getBuffer:self];
length   = [[self dataSource] getLength:self];

// Copy to point buffer
for (i = 0; i  length; i++) {
pointBuffer[i].y = inBuffer[i];
pointBuffer[i].x = i;
}

// Mark display for painting
[selfsetNeedsDisplay:YES];
}

- (void)dealloc {
free(pointBuffer);
[super dealloc];
}

@end

MyView.h
--
@interface MyView : NSView {
IBOutletid dataSource;
NSBezierPath *pointPath;
NSPoint *pointBuffer;
}

- (void)setDataSource:(id)inDataSource;
- (id)dataSource;
- (void)stepAnimation:(NSTimer *)timer;

@end

@interface NSObject(MyViewDataSource)

- (float *)getBuffer:(MyView *)view;
- (int)getLength:(MyView *)view;

@end

MyModel.m
--
@implementationMyModel

- (id)init {
self= [superinit];
if (self) {
buffer = malloc (sizeof(float) * 100);
length = 100;
}
return self;
}

- (float *)getBuffer:(GraphView *)view {
returnbuffer;
}

- (int)getLength:(GraphView *)view {
returnlength;
}

- (void)dealloc {
free (buffer);
[super dealloc];
}

@end

MyModel.h
--
@interface MyModel : NSObject {
float *buffer;
int length;
}

- (float *)getBuffer:(GraphView *)view;
- (int)getLength:(GraphView *)view;

@end



  
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: instance management in IB

2009-05-11 Thread Chris Carson

Hi Jon,

Thanks! That did the trick -- I was way off.

Chris


- Original Message 
 From: Jonathan Hess jh...@apple.com
 To: Chris Carson cucar...@yahoo.com
 Cc: cocoa-dev@lists.apple.com
 Sent: Tuesday, May 12, 2009 1:19:11 AM
 Subject: Re: instance management in IB
 
 Hey Chris -
 
 This line pointPath = [NSBezierPath bezierPath]; in the init method creates 
 an 
 NSBezierPath instance that may (will!) be destroyed with the next autorelease 
 pool flush. You should be creating your bezier path with pointPath = 
 [[NSBezierPath alloc] init]; and then add a [pointPath release] to your 
 dealloc method.
 
 http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html
 
 Good Luck -
 Jon Hess
 
 On May 11, 2009, at 6:29 PM, Chris Carson wrote:
 
  
  Hello,
  
  I've been scratching my head trying to get a basic delegate/data source 
 Cocoa/AppKit program working and feel that I'm misunderstanding something 
 basic 
 (I've included the code is at the end).
  
  I set a breakpoint within the if statement in the init method of MyModel 
  and 
 see it called more than once. The second time the debugger throws a 
 EXC_BAD_ACCESS. This message goes away if I comment out the two lines in 
 stepAnimation that call the getBuffer and getLength methods and then modify 
 the 
 buffer. All this makes me think that somehow the instance of MyModel is being 
 deallocated as soon as the data source message returns, but before the data 
 is 
 copied into the pointBuffer.
  
  I created an NSView and NSObject in Interface Builder, assigning the MyView 
 subclass to the NSView object and MyModel to the NSObject object. Then I 
 connected the dataSource outlet on MyView to th MyModel object.
  
  What am I missing? How can I get the data from MyModel to be viewable my 
 MyView?
  
  Sidenote: Ultimately I'm trying to plot a real-time frequency spectrum. My 
 plan is to pull in data over a CFMessagePort in the model and have the view 
 access it view the data source.
  
  Help is much appreciated!
  
  Chris
  
  main.m
  --
  
  int main(int argc, char *argv[]) {
 // Launch Cocoa application
 return NSApplicationMain(argc, (const char **) argv);
  }
  
  MyView.m:
  --
  @implementation MyView
  
  - (id)initWithFrame:(NSRect)frame {
 self = [super initWithFrame:frame];
 if (self) {
 pointPath = [NSBezierPathbezierPath];
 pointBuffer = malloc (sizeof(NSPoint) * 100);
 [NSTimerscheduledTimerWithTimeInterval:0.1
 target:self
 selector:@selector(stepAnimation:)
 userInfo:nil
 repeats:YES];
 }
 return self;
  }
  
  - (void)drawRect:(NSRect)rect {
 [pointPath removeAllPoints];
 [pointPathappendBezierPathWithPoints:(NSPointArray)pointBuffercount:100];
 [pointPathstroke];
  }
  
  - (void)setDataSource:(id)inDataSource {
 dataSource = inDataSource;
  }
  
  - (id)dataSource {
 returndataSource;
  }
  
  - (void)stepAnimation:(NSTimer *)timer {
 float*inBuffer;
 int i, length;
  
  
 // Fetch buffer pointer
 inBuffer = [[self dataSource] getBuffer:self];
 length   = [[self dataSource] getLength:self];
  
 // Copy to point buffer
 for (i = 0; i  length; i++) {
 pointBuffer[i].y = inBuffer[i];
 pointBuffer[i].x = i;
 }
  
 // Mark display for painting
 [selfsetNeedsDisplay:YES];
  }
  
  - (void)dealloc {
 free(pointBuffer);
 [super dealloc];
  }
  
  @end
  
  MyView.h
  --
  @interface MyView : NSView {
 IBOutletid dataSource;
 NSBezierPath *pointPath;
 NSPoint *pointBuffer;
  }
  
  - (void)setDataSource:(id)inDataSource;
  - (id)dataSource;
  - (void)stepAnimation:(NSTimer *)timer;
  
  @end
  
  @interface NSObject(MyViewDataSource)
  
  - (float *)getBuffer:(MyView *)view;
  - (int)getLength:(MyView *)view;
  
  @end
  
  MyModel.m
  --
  @implementationMyModel
  
  - (id)init {
 self= [superinit];
 if (self) {
 buffer = malloc (sizeof(float) * 100);
 length = 100;
 }
 return self;
  }
  
  - (float *)getBuffer:(GraphView *)view {
 returnbuffer;
  }
  
  - (int)getLength:(GraphView *)view {
 returnlength;
  }
  
  - (void)dealloc {
 free (buffer);
 [super dealloc];
  }
  
  @end
  
  MyModel.h
  --
  @interface MyModel : NSObject {
 float *buffer;
 int length;
  }
  
  - (float *)getBuffer:(GraphView *)view;
  - (int)getLength:(GraphView *)view;
  
  @end
  
  
  
  
  ___
  
  Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
  
  Please do not post admin requests or moderator comments to the list.
  Contact the moderators at cocoa-dev-admins(at)lists.apple.com
  
  Help/Unsubscribe/Update your Subscription:
  http://lists.apple.com/mailman/options/cocoa-dev/jhess%40apple.com
  
  This email sent to jh...@apple.com