NativeBoost and memory management

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

NativeBoost and memory management

Holger Freyther
Good Morning,

I used NB to access openlog, closelog and syslog of libc and I am not sure
if I got it right but didn’t really get further by browsing testcases/reading the
examples.

openlog(3) takes an “char *ident” as first parameter and the caller needs to
make sure that the string passed remains valid until closelog is called.

My binding looks like this:

c_openlog: ident opt: aOpt facility: aFac
        "openlog(const char *ident, int logopt, int facility);"
        <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
        ^self nbCall: #(void openlog(char *ident, int aOpt, int aFac))

And I call it like this:

        Identity := anIdentity asNBExternalString.
        self c_openlog: Identity opt: anOption facility: aFacility.

The things I am not sure with:

1.) is it right to use “char *ident” instead of “String ident”? “String” will copy
the string by value but the pointer passed to openlog would be a pointer from
the C callstack?

2.) Am I right with the call to asNBExternalString?

3.) How does this integrate with GC and image quit/image resume? E.g. I could
use >>#freeAfterUse and if I do “Identity := nil” at some point free should be called
on the old string. Is there anything in the system that sets the address to 0x0 after
the image is starting?

thanks
  holger
Reply | Threaded
Open this post in threaded view
|

Re: NativeBoost and memory management

philippeback
On Thu, May 7, 2015 at 8:53 AM, Holger Freyther <[hidden email]> wrote:
Good Morning,

I used NB to access openlog, closelog and syslog of libc and I am not sure
if I got it right but didn’t really get further by browsing testcases/reading the
examples.

openlog(3) takes an “char *ident” as first parameter and the caller needs to
make sure that the string passed remains valid until closelog is called.

My binding looks like this:

c_openlog: ident opt: aOpt facility: aFac
        "openlog(const char *ident, int logopt, int facility);"
        <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
        ^self nbCall: #(void openlog(char *ident, int aOpt, int aFac))

And I call it like this:

        Identity := anIdentity asNBExternalString.
        self c_openlog: Identity opt: anOption facility: aFacility.

The things I am not sure with:

1.) is it right to use “char *ident” instead of “String ident”? “String” will copy
the string by value but the pointer passed to openlog would be a pointer from
the C callstack?

asNBExternalString will do this with a NBExternalAddress:

fromString: aString
| result |
result := NativeBoost allocate: aString size + 1.
(self assert: result notNil).
result writeString: aString.
^ result 

writeString: aString
"write a null-terminated byte string to receiver's address"
| str |
str := aString copyWith: (Character value: 0).
NativeBoost memCopy: str asByteArray to: self size: str size.

So, yes, it allocates heap memory 

basicAllocate: numBytes
"Allocate a memory block with given size in bytes,
answer an NBExternalAddress instance - address to the beginning of memory block"
| addr |
addr := heap allocate: numBytes.
addr = 0 ifTrue: [ ^ nil ].
^ NBExternalAddress value: addr

char * looks a null terminated string, which str := aString copyWith: (Character value: 0). provides

So, asNBExternalString is compatible with the char *


2.) Am I right with the call to asNBExternalString?

Should work.
 

3.) How does this integrate with GC and image quit/image resume? E.g. I could
use >>#freeAfterUse and if I do “Identity := nil” at some point free should be called
on the old string. Is there anything in the system that sets the address to 0x0 after
the image is starting?

As the thing is a NBExternalAddress, there is a 

finalize
self free

which will do the "free" call when the Identity will be gc'd.

As for the statup/shutdown, maybe 

startUp: resuming
shutDown: quitting

methods on the class side of your facility will do the necessary things.

I am pretty sure the address would be pointing to invalid crap upon image restart.

Doing free too many times will just raise an error I guess (which you can catch).

free: address

sema critical: [ | block |
block := reservedBlocks removeKey: address ifAbsent: [
self error: 'Unable to find a memory block with given address' ].
block makeFreeFor: self ]
HTH

Phil

 

thanks
  holger




 

Reply | Threaded
Open this post in threaded view
|

Re: NativeBoost and memory management

Sven Van Caekenberghe-2
In reply to this post by Holger Freyther

> On 07 May 2015, at 08:53, Holger Freyther <[hidden email]> wrote:
>
> I used NB to access openlog, closelog and syslog of libc

Why not use UDP datagrams to send messages to syslog ?

If you do it manually it should be just a couple of lines of code.

Or have a look at SysLogSender in SystemLogger on StHub.

No need to mess with native code, unless you want to, of course.

Reply | Threaded
Open this post in threaded view
|

Re: NativeBoost and memory management

Luc Fabresse

2015-05-07 9:58 GMT+02:00 Sven Van Caekenberghe <[hidden email]>:

> On 07 May 2015, at 08:53, Holger Freyther <[hidden email]> wrote:
>
> I used NB to access openlog, closelog and syslog of libc

Why not use UDP datagrams to send messages to syslog ?

such as what Olivier did:


Luc
 

If you do it manually it should be just a couple of lines of code.

Or have a look at SysLogSender in SystemLogger on StHub.

No need to mess with native code, unless you want to, of course.