Thread overview
How to convert these constructs to D?
Nov 30, 2013
Gary Willoughby
Nov 30, 2013
Adam D. Ruppe
Nov 30, 2013
Gary Willoughby
Nov 30, 2013
Rémy Mouëza
Dec 01, 2013
Craig Dillabaugh
Dec 01, 2013
Gary Willoughby
Dec 01, 2013
Kozzi
Dec 02, 2013
Gary Willoughby
Dec 02, 2013
Daniel Kozak
Dec 02, 2013
Craig Dillabaugh
November 30, 2013
I'm porting some C headers and wondered how would i convert the following to D:

#define pthread_self() GetCurrentThreadId()

#define pthread_handler_t void * __cdecl

typedef void * (__cdecl *pthread_handler)(void *);

#define set_timespec_nsec(ABSTIME,NSEC) { \
  GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
  (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
  (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
}
November 30, 2013
Just doing these by eyeball...

On Saturday, 30 November 2013 at 14:53:35 UTC, Gary Willoughby wrote:
> #define pthread_self() GetCurrentThreadId()

That's simply

alias pthread_self = GetCurrentThreadId;

> #define pthread_handler_t void * __cdecl

This depends on the text replacement and won't quite translate to D. Basically, this is a find/replace that transforms "pthread_handler_t" into "extern(C) void*". But since that's an incomplete type, D won't let you alias it nor even work as a standalone mixin.

I'd translate this by doing the find/replace yourself. Make sure those functions return void* and are marked as extern(C).

> typedef void * (__cdecl *pthread_handler)(void *);

This creates a name for a function pointer. In D, it'd look like:

alias extern(C) void* function(void*) pthread_handler;

> #define set_timespec_nsec(ABSTIME,NSEC) { \
>   GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
>   (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
>   (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
> }

I think the most straightforward way to do this would be either a mixin, a template, or a simple function. In any case, it will need changes at the call site too, but we can use the type system to help with that. Let's do it this way:

// GetSystemTimeAsFileTime needs a pointer to FILETIME, so that
// must be the type of ABSTIME in here too
void set_timespec_nsec(LPFILETIME time, long nsec) {
     GetSystemTimeAsFileTime(time.tv.ft); // no more pointer - we force that at the call site
     time.tv.i64 += nsec / 100;
     time.max_timeout_msec = nsec / 1000000;
}


might have to put in casts on those math if dmd complains, I'm not sure what the right types are.


But whereas the macro did everything inline, here we just take a pointer to the struct and update it that way, leading to simpler code. If you get an error about passing a FILETIME when you need a FILETIME*, this is why - the old macro did the & for us, but we can't really do that in D, so we just force the programmer to do it when used.
November 30, 2013
For the two first ones, I would use an alias:
    alias GetCurrentThreadId pthread_self;
    alias void *  pthread_handler_t;

The third one is a function pointer alias:
    alias void * function (void *) pthread_handler;

For the last one, I am not sure, being rusty with the C preprocessor rules. I would use a template function:
    import core.stdc.config : c_long;

    void set_timespec_nsec (T, U) (ref T abstime, U nsec) {
       GetSystemTimeAsFileTime (& abstime.tv.ft);
       abstime.tv.i64 += cast (long) (nsec) / 100;
       abstime.max_timeout_msec = cast (c_long) (nsec /1000000);
    }
Though, with that last one, you lost the ability to get it inlined (but there is still the -inline computer switch if performance is a real issue).
As for the type mapping, it seems that:
 - __int64 in C corresponds to long in D
 - long in C corresponds to c_long defined in core.stdc.config.

Don't hesitate to double check all this, I may have written something wrong.

On 11/30/2013 03:53 PM, Gary Willoughby wrote:
> I'm porting some C headers and wondered how would i convert the
> following to D:
>
> #define pthread_self() GetCurrentThreadId()
>
> #define pthread_handler_t void * __cdecl
>
> typedef void * (__cdecl *pthread_handler)(void *);
>
> #define set_timespec_nsec(ABSTIME,NSEC) { \
>    GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
>    (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
>    (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
> }

November 30, 2013
Thanks all.
December 01, 2013
On Saturday, 30 November 2013 at 14:53:35 UTC, Gary Willoughby wrote:
> I'm porting some C headers and wondered how would i convert the following to D:
>
> #define pthread_self() GetCurrentThreadId()
>
> #define pthread_handler_t void * __cdecl
>
> typedef void * (__cdecl *pthread_handler)(void *);
>
> #define set_timespec_nsec(ABSTIME,NSEC) { \
>   GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
>   (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
>   (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
> }

Maybe you have already solved all your problems, but have you tried DStep with this header?  I used it on FFTW3, which is basically one GIANT C 100 line macro, and it 'seems' to have done a great job on that. However, in other cases it just seems to have dropped some defines altogether, so your mileage may vary.

Craig
December 01, 2013
On Sunday, 1 December 2013 at 03:20:49 UTC, Craig Dillabaugh wrote:
> On Saturday, 30 November 2013 at 14:53:35 UTC, Gary Willoughby wrote:
>> I'm porting some C headers and wondered how would i convert the following to D:
>>
>> #define pthread_self() GetCurrentThreadId()
>>
>> #define pthread_handler_t void * __cdecl
>>
>> typedef void * (__cdecl *pthread_handler)(void *);
>>
>> #define set_timespec_nsec(ABSTIME,NSEC) { \
>>  GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
>>  (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
>>  (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
>> }
>
> Maybe you have already solved all your problems, but have you tried DStep with this header?  I used it on FFTW3, which is basically one GIANT C 100 line macro, and it 'seems' to have done a great job on that. However, in other cases it just seems to have dropped some defines altogether, so your mileage may vary.
>
> Craig

To be honest i didn't. The last time i tried DStep i had problems with compilation. I'll take another look though. I'm basically porting all the mysql-client headers which i thought would be pretty straight forward but it's taking a little more thought than i anticipated.
December 01, 2013
> I'm basically porting all the mysql-client headers which i thought would be pretty straight forward but it's taking a little more thought than i anticipated.

Can I ask why? And the part of code you are asking is from pthread headers not from mysql.



December 02, 2013
On Sunday, 1 December 2013 at 18:51:51 UTC, Gary Willoughby wrote:
> On Sunday, 1 December 2013 at 03:20:49 UTC, Craig Dillabaugh wrote:
>> On Saturday, 30 November 2013 at 14:53:35 UTC, Gary Willoughby wrote:
>>> I'm porting some C headers and wondered how would i convert the following to D:
>>>
>>> #define pthread_self() GetCurrentThreadId()
>>>
>>> #define pthread_handler_t void * __cdecl
>>>
>>> typedef void * (__cdecl *pthread_handler)(void *);
>>>
>>> #define set_timespec_nsec(ABSTIME,NSEC) { \
>>> GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \
>>> (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \
>>> (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
>>> }
>>
>> Maybe you have already solved all your problems, but have you tried DStep with this header?  I used it on FFTW3, which is basically one GIANT C 100 line macro, and it 'seems' to have done a great job on that. However, in other cases it just seems to have dropped some defines altogether, so your mileage may vary.
>>
>> Craig
>
> To be honest i didn't. The last time i tried DStep i had problems with compilation. I'll take another look though. I'm basically porting all the mysql-client headers which i thought would be pretty straight forward but it's taking a little more thought than i anticipated.

I think you end up with a bit nicer interface if you hand role your own, but at least DStep can take care of a good bit of the grunt work for you.  I had some trouble getting it running the first time (mostly my own fault), but am now glad I made the effort.
December 02, 2013
On Sunday, 1 December 2013 at 20:46:20 UTC, Kozzi wrote:
>> I'm basically porting all the mysql-client headers which i thought would be pretty straight forward but it's taking a little more thought than i anticipated.
>
> Can I ask why? And the part of code you are asking is from pthread headers not from mysql.

No, it's from my_pthread.h
December 02, 2013
On Monday, 2 December 2013 at 09:01:25 UTC, Gary Willoughby wrote:
> On Sunday, 1 December 2013 at 20:46:20 UTC, Kozzi wrote:
>>> I'm basically porting all the mysql-client headers which i thought would be pretty straight forward but it's taking a little more thought than i anticipated.
>>
>> Can I ask why? And the part of code you are asking is from pthread headers not from mysql.
>
> No, it's from my_pthread.h

Ok, my fault :)