13 messages in net.java.dev.jna.usersRe: [jna-users] Threading in JNA....
FromSent OnAttachments
Drayton BrownApr 6, 2009 3:40 am 
Timothy WallApr 6, 2009 5:24 am 
Drayton BrownApr 6, 2009 5:34 am 
Drayton BrownApr 6, 2009 9:28 am 
Timothy WallApr 6, 2009 9:50 am 
Drayton BrownApr 7, 2009 2:32 am 
Drayton BrownApr 9, 2009 3:20 am 
Timothy WallApr 13, 2009 6:11 am 
Drayton BrownApr 24, 2009 7:22 am 
Timothy WallApr 24, 2009 9:49 am 
Drayton BrownApr 28, 2009 5:42 am 
Timothy WallApr 28, 2009 6:44 am 
Drayton BrownApr 28, 2009 6:46 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:Re: [jna-users] Threading in JNA....Actions...
From:Drayton Brown (dray@gmail.com)
Date:Apr 28, 2009 6:46:53 am
List:net.java.dev.jna.users

Thanks Timothy!

2009/4/28 Timothy Wall <twal@dev.java.net>

On Apr 28, 2009, at 8:42 AM, Drayton Brown wrote:

Hi Timothy

You mentioned that the space taken up by the Memory object shouldn't be invalid unless the native code frees it. Can I check for this by calling Memory.isValid() ? Or will this only tell me if I have called Memory.free()?

The latter is correct. You'd have to poke at the memory manager internals, or hook into "free" in order to check if the native code has freed the memory. ElectricFence or other memory debugging tools might be useful if you have them.

Also do you have any ideas on how the native memory tracking could be corrupted?

Any time native code writes outside where it's supposed to, the results are undefined. You might hit critical memory, you might hit something superfluous.

Regards

Drayton

2009/4/24 Timothy Wall <twal@dev.java.net> Memory does perform bounds checking, so if it makes it through to Pointer.getByte then it's still within the range that Memory thinks is valid. That space shouldn't become invalid unless native code either frees it or corrupts the native memory tracking.

On Apr 24, 2009, at 10:22 AM, Drayton Brown wrote:

Hi Timothy

I've now changed the amount of memory I'm requesting (The previous amount requested was not taking into account the pixel size :P). So my code for decoding an image looks like this:

Integer pixelSizeInBytes = bufferedImage.getColorModel().getPixelSize() / Byte.SIZE; Integer stride = bufferedImage.getWidth() * pixelSizeInBytes;

log("Decomposing image..."); for (int band = 0; band < bufferedImage.getRaster().getNumBands(); band++) { int sample = 0; perfectlyClearImageTransfer.bands[band] = new Memory(stride * bufferedImage.getHeight()); for (int y = 0; y < bufferedImage.getHeight(); y++) { for (int x = 0; x < bufferedImage.getWidth(); x++) { myStructure.bands[band].setByte(sample++, (byte) bufferedImage.getRaster().getSample(x, y, band)); } } }

I've ajusted the code for composing the image, after receiving the data back from the native function call, so I can try and track when the getByte() function goes out of bounds:

long lenght = stride * bufferedImage.getHeight(); log("Image lenght: " + lenght);

log("Composing image..."); offset = 0; for (int band = 0; band < bufferedImage.getRaster().getNumBands(); band++) { for (int y = 0; y < perfectlyClearImageTransfer.height; y++) { for (int x = 0; x < perfectlyClearImageTransfer.width; x++) { offset++; if (offset > lenght) { log("Image offset: " + offset); result = -1; } bufferedImage.getRaster().setSample(x, y, band, myStructure.bands[band].getByte(offset) & 0xFF); } } }

with these changes I would expect to see the offset from which the getByte() function is requesting data if it is out of bounds, unfortunately in practice this is not the case.

Unfortunately the JVM is still crashing out with the same error: # C [jna506752203973678041.tmp+0x6db5] Java_com_sun_jna_Pointer__1getByte+0x8a

The native call I make, to which I pass myStructure, does not scale the image and the pixel size remains the same. So I'm a little confused about why this is happening. Is there any way to know the offset of the byte thats being retrieved?

Also I was under the impression that the Memory object performed boundry checking, if this is the case I would have expected an out of bounds exception to be thrown, is this not the case?

Thanks once again for any help!

Regards Drayton

2009/4/13 Timothy Wall <twal@dev.java.net> Memory backing the structure will be freed when no longer referenced (or at some point thereafter, following normal GC and finalization rules). Typically the only reference to a Structure's memory is the structure itself, although new references are generated via Pointer.share().

In your case, it looks like you've assigned additional memory to myStructure.bands[] elements, so you need to ensure that *that* memory is not being freed prematurely.

On Apr 9, 2009, at 6:21 AM, Drayton Brown wrote:

Hi all

I'm trying to do the following:

for (int band = 0; band < bufferedImage.getRaster().getNumBands(); band++) { int sample = 0; myStructure.bands[band] = new Memory(bufferedImage.getWidth() * bufferedImage.getHeight()); for (int x = 0; x < bufferedImage.getWidth(); x++) { for (int y = 0; y < bufferedImage.getHeight(); y++) { myStructure.bands[band].setByte(sample++, (byte) bufferedImage.getRaster().getSample(x, y, band)); } } }

//Pass in myStructure to a Natvie method. The method alters the data stored in myStructure.bands and passes it back. I then compose an image from the data:

log("Composing image..."); for (int band = 0; band < bufferedImage.getRaster().getNumBands(); band++) { int sample = 0; for (int x = 0; x < bufferedImage.getWidth(); x++) { for (int y = 0; y < bufferedImage.getHeight(); y++) { bufferedImage.getRaster().setSample(x, y, band, myStructure.bands[band].getByte(sample++) & 0xFF); // The '& 0xFF' is to convert to signed two's complement } } }

Unfortunately the JVM crashes out stating this as the offending code: C [jna9190890331615800015.tmp+0x6db5] Java_com_sun_jna_Pointer__1getByte+0x8a

This only happens in some cases, which makes me think its a memory issue. I have made the code thread safe and even run it with only one thread, I still get this intermittent problem. Also I know its not data specific, as sometimes the same data that failed will go through on a second attempt.

Any help on this would be greatly appreciated!

Regards Drayton

2009/4/7 Drayton Brown <dray@gmail.com> Ok, thanks Timothy!

2009/4/6 Timothy Wall <twal@dev.java.net> Native memory is allocated via malloc, not by requesting memory from the JVM. The only place JNA explicitly allocates memory is via the Memory object, which is used internally for backing Structures. Callbacks also allocate executable memory for small bits of trampoline code.

On Apr 6, 2009, at 12:28 PM, Drayton Brown wrote:

Hello again!

Just a quick question about how memory management works with JNA.

When starting the jvm I specify the size of the memory heap to be 2Gb. (I'm working on a 32bit machine, so this is the max I can use atm) Unfortunately the jvm crashes out while executing a native memory allocation function... (This only happens in some instances, so I'm confident that my code is ok since there are many instances where this does not happen)

Timing is everything. It's not necessarily a block of code that's incorrect, but how and when it operates within its environment.

My question is, when a native function allocates memory, does it take from the memory allocated to the jvm, or does it do its own thing and ask the OS?

Thanks for any input!

Regards Drayton

2009/4/6 Drayton Brown <dray@gmail.com> Hello again Timothy!

The thread safe object is a native object written in C. I ensured this was thread safe by asking the third party developers to whom the object belongs...

I'll give the Native.synchronizedLibrary() call a try... I was not aware of this, so its probably just what I'm missing!

Thanks again Timothy!

Drayton

2009/4/6 Timothy Wall <twal@dev.java.net>

On Apr 6, 2009, at 6:41 AM, Drayton Brown wrote:

Hi all

I've written a threaded application which uses a thread safe shared object, however when I run the application with more that one thread, the jvm crashes out.

Is the "thread safe object" a Java object or a native one? What makes it thread safe?

I've checked the JNA site for information on how the JNA wrapper handles threading, but I've been unable to find any information. I was hoping someone on the mailing list could give me more information on the topic, or at least point me in the direction of the documentation on it.

JNA itself doesn't do anything special w/r/t threading. There is a Native.synchronizedLibrary() call that may be used to ensure any calls to your native library are serialized (i.e. no more than one call is ever active at any given time).

Return error codes are saved on a per-thread basis.