Re: While loop on global variable optimised away?

2022-05-11 Thread ichneumwn via Digitalmars-d-learn

On Wednesday, 11 May 2022 at 10:01:18 UTC, Johan wrote:

Any function call (inside the loop) for which it cannot be 
proven that it never modifies your memory variable will work. 
That's why I'm pretty sure that mutex lock/unlock will work.


Thank you, in C I would not have been surprised. It was the 
default thread local storage that made me question it. Your 
remark about the mutex lock/unlock is very helpful, I was 
starting to get worried I would need to keep a very careful watch 
on those __gshareds [well, more than usual :) ]




While loop on global variable optimised away?

2022-05-11 Thread ichneumwn via Digitalmars-d-learn

Hi Forum,

I have a snippet of code as follows:
```
extern(C) extern __gshared uint g_count;

// inside a class member function:
  while(g_count) <= count) {}
```

This is from a first draft of the code without proper thread 
synchronisation. The global variable g_count is updated from a 
bit of C++ code. As soon as I turn the optimiser on, the code 
never gets passed this point, leading me to suspect it gets 
turned into

```
  while(true) {}
```

If modify the code in the following way:

```
  import core.volatile : volatileLoad;

  while(volatileLoad(_count) <= count) {}
```

it works again.

My question is, have I hit a compiler bug (ldc 1.28.1, aarch64 
[Raspberry Pi]) or is this part of the language design. I would 
have thought since D use thread-local storage by default, that 
for a __gshared variable it would be understood that it can get 
modified by another thread. Access through atomic function would 
prevent the compiler from optimising this away as well, but if I 
were to use a Mutex inside the loop, there is no way for the 
compiler to tell *what* that Mutex is protecting and it might 
still decide to optimise the test away (assuming that is what is 
happening, did not attempt to look at the assembler code).


Cheers



Re: Use bindbc-sdl statically

2021-04-24 Thread ichneumwn via Digitalmars-d-learn

On Saturday, 24 April 2021 at 16:44:09 UTC, Ishax wrote:


So I have the lib files. It's failing with only an exit code. 
No window is appearing. It's using the same D code as with the 
dynamic setup which I was able to produce a window with.

```sdl
dependency "bindbc-sdl" version="~>0.1.0"
versions "BindSDL_Static"
subConfigurations "bindbc-sdl" "staticBC"
libs "SDL2" "SDL2_image"
```


Hi, Linux programmer here who just went through the process of 
working with dll's and lib's on windows. In my current 
understanding, there are three ways of working with libraries:


1. Load DLL's at runtime (LoadLibrary and such)
2. Linking with DLL's at compile time. The compiler adds code to 
automatically load the DLL's when your program starts. You do 
this by linking against an *import library*. These have a *.lib* 
extension
3. Linking against *static libraries*. These have a *.lib* 
extension


Note that 2. & 3. are different things, but the files you need 
end in .lib in both cases. You'll have to check that your .lib 
files are actually static libraries, not import libraries.


I am not sure if linking to outside sources is appropriate, so I 
will just copy-paste from stackoverflow:



"Use the lib command. If it's static, lib will show you a pile of 
.obj files inside. Not so if it's am implib."


lib /list foo.lib


Re: Dlang equivalent of #define/#ifdef : not... version

2021-04-21 Thread ichneumwn via Digitalmars-d-learn

On Tuesday, 20 April 2021 at 18:57:46 UTC, ichneumwn wrote:

Hi,

Trying to convert a C header to D. The underlying package 
exists in different versions and may or may not expose certain 
functionality (modules/extensions). One should check at compile 
time that the header provides the relevant definitions, through 
#ifdef, and do a further run-time check to confirm the 
functionality is really present. It is the compile time check 
that I am finding tricky to do/emulate.


.h : #define i_am_a_feature 1

The C-code uses this define as a guard:

.c : #ifdef i_am_a_feature

What would the the D equivalent? This is my attempt so far:

features.d:

import std.traits;

private enum capabilities {
i_am_a_feature
}

template supported(string member)
{
enum bool supported = hasMember!(capabilities, member);
}

version = vs_i_am_a_feature;

enum can_i_test_for_this;

and use.d:

import features;
import std.stdio;

void main() {
static if (supported!("i_am_a_feature")) {
writeln("Feature 1!");
}
static if (supported!("i_am_not_a_feature")) {
writeln("Feature 2!");
}
version(vs_i_am_a_feature) {
writeln("If only I worked");
}
}

This produces "Feature 1!", so the supported() path works, but 
is a bit of a round-about way and all "capability flags" need 
to put in that single enum capabilities instead of being 
allowed to be scattered across the features.d module.


As is documented, "version" does not cross the module boundary.

So my questions:
- is there a module-crossing equivalent of "version"?
- if not, is there some way I could test for the existence of 
the enum can_i_test_for_this? A SymbolExists!() or 
ModuleHasSymbol!() or ModuleHasMember!() ?


Cheers


Between them, Simen and Ali have cracked the case. Ali's 
demonstration that "true" was returned made me look at it further 
and tried the module's name directly and that worked too. It 
seems that Simen's expansion of hasMember() into the __traits 
version does the trick -- the __traits version *does* accept the 
module as a parameter. It seems the template expansion does not 
like module arguments, not __traits itself. Here is the demo:


features.d:

import std.traits;

enum can_sing = 1;
enum can_dance = 1;

template supported(string member) {
enum bool supported = __traits(hasMember, features, 
member);

// features can be replaced by: mixin(__MODULE__)
// to make this module robust against renaming
}
/*
 * Note that using std.traits.hasMember *does not* work. 
Yields error:
 * template instance hasMember!(features, "can_sing") does 
not match template

 * declaration hasMember(T, string name)
 */

use.d:

import features;
import std.stdio;
import std.traits;

void main() {
static if (supported!"can_sing") {
writeln("can_sing");
}
static if (supported!("can_dance")) {
writeln("can_dance");
}
static if (supported!("can_jump")) {
writeln("can_jump");
}
}

Result:

can_sing
can_dance

I think the version with the mixin is neater, but I have put it 
in the direct "features" in the example to show it is not 
actually necessary.


Oh, I found a bonus option: passing the module as an argument. I 
do not really get templates beyond the very basic ones, but I 
remember seeing "alias" somewhere and that gets the module 
through my own template:


// accept module as argument
template supported(alias modname, string member) {
enum bool supported = __traits(hasMember, modname, 
member);

}
// accept module name (string) as argument:
template supported(string modname, string member) {
enum bool supported = __traits(hasMember, mixin(modname), 
member);

}

As I write this, I realise that the alias can also be used to get 
a version of hasMember that accepts modules:


enum hasMember(alias T, string name) = __traits(hasMember, T, 
name);


Although that might have unintended side effects? And, indeed, 
shorten my own use case to:


enum supported(string member) = __traits(hasMember, 
mixin(__MODULE__), member);



Many thanks to everyone with suggestions!



Re: write once type?

2021-04-20 Thread ichneumwn via Digitalmars-d-learn
On Tuesday, 20 April 2021 at 20:04:17 UTC, Steven Schveighoffer 
wrote:
I just realized, this is Rebindable, or tail-const. (I don't 
need the head to be truly const, I just need to be able to copy 
into a const-referring thing). I currently am using a pointer, 
which is working, but I prefer not to use it, and it is not 
general enough.


-Steve


Ah, you found it - I was looking up the reference for it and you 
replied in the mean-time. Ignore my answer :)


Re: write once type?

2021-04-20 Thread ichneumwn via Digitalmars-d-learn
On Tuesday, 20 April 2021 at 19:56:33 UTC, Steven Schveighoffer 
wrote:
I have had the need in some cases to *maybe* set a const value 
inside a loop. One can sometimes abstract this into a lambda 
function, but sometimes this is not possible (e.g. if the loop 
is static). Not only that, but I may also want to keep 
processing the loop and do something different if the value has 
already been set instead of returning immediately, which 
necessitates a second loop.


My use case is I have a property that is const inside a set of 
types, and I want to verify that they all have the same value, 
and extract what that value is.


I'm wondering if anyone has a "Write once" type, that is, a 
type that allows you to write it exactly once, and is treated 
like initialization on first setting (i.e. allows writing to 
previously unused const data).


This type has to decide at runtime whether it has been set. So 
it would kind of be like Nullable!T, but Nullable doesn't allow 
setting when the T is const. Optional!T doesn't work either.


-Steve


Not quite your use case, I think, but std.typecons.Rebindable at 
least allows you to bind a new const(object). Not write once 
though.


I think I found that after a hint of its existence in
https://forum.dlang.org/thread/orpbvvjspibfpitnn...@forum.dlang.org




Dlang equivalent of #define/#ifdef : not... version

2021-04-20 Thread ichneumwn via Digitalmars-d-learn

Hi,

Trying to convert a C header to D. The underlying package exists 
in different versions and may or may not expose certain 
functionality (modules/extensions). One should check at compile 
time that the header provides the relevant definitions, through 
#ifdef, and do a further run-time check to confirm the 
functionality is really present. It is the compile time check 
that I am finding tricky to do/emulate.


.h : #define i_am_a_feature 1

The C-code uses this define as a guard:

.c : #ifdef i_am_a_feature

What would the the D equivalent? This is my attempt so far:

features.d:

import std.traits;

private enum capabilities {
i_am_a_feature
}

template supported(string member)
{
enum bool supported = hasMember!(capabilities, member);
}

version = vs_i_am_a_feature;

enum can_i_test_for_this;

and use.d:

import features;
import std.stdio;

void main() {
static if (supported!("i_am_a_feature")) {
writeln("Feature 1!");
}
static if (supported!("i_am_not_a_feature")) {
writeln("Feature 2!");
}
version(vs_i_am_a_feature) {
writeln("If only I worked");
}
}

This produces "Feature 1!", so the supported() path works, but is 
a bit of a round-about way and all "capability flags" need to put 
in that single enum capabilities instead of being allowed to be 
scattered across the features.d module.


As is documented, "version" does not cross the module boundary.

So my questions:
- is there a module-crossing equivalent of "version"?
- if not, is there some way I could test for the existence of the 
enum can_i_test_for_this? A SymbolExists!() or ModuleHasSymbol!() 
or ModuleHasMember!() ?


Cheers




Re: Linux shared library loading/linking from C does not invoke (shared) static this

2021-01-12 Thread ichneumwn via Digitalmars-d-learn

On Tuesday, 12 January 2021 at 09:49:46 UTC, Mike Parker wrote:

On Tuesday, 12 January 2021 at 09:31:08 UTC, ichneumwn wrote:



Follow on to my own question: on Linux, with gcc, I have 
created the following file "starter.c" that I inject into my D 
shared library:


  int rt_init(void);
  int rt_term(void);

  // should really check for errors!
  static void __attribute__((constructor)) Dstarter(void) {
rt_init();
  }

  static void __attribute__((destructor)) Dterminator(void) {
rt_term();
  }

That seems to do the trick. Not sure how clean this is?


You should be able to do the same in D with 
`pragma(crt_constructor)` and `pragma(crt_destructor)`:


https://dlang.org/spec/pragma.html#crtctor
https://dlang.org/spec/pragma.html#crtdtor
https://dlang.org/changelog/2.078.0.html#crt-constructor


Perfect, thanks! Interestingly, as I removed the C stub and tried 
the D route, I noticed that just calling rt_init() is enough to 
also get static ~this() to run on exit. In fact then adding 
writeln in a pragma(crt_destructor) function shows that it gets 
called after static ~this().


For anyone stumbling across this thread and looking for the 
import for rt_init/term:


import core.runtime : rt_init, rt_term;



Re: Linux shared library loading/linking from C does not invoke (shared) static this

2021-01-12 Thread ichneumwn via Digitalmars-d-learn

On Tuesday, 12 January 2021 at 09:02:38 UTC, Imperatorn wrote:

On Tuesday, 12 January 2021 at 08:19:45 UTC, ichneumwn wrote:
Where could one file a suggestion for an update to the 
documentation?


In the top right section of the page you can click the "Improve 
this page"-link.


Thanks, I will leave it though. I do not want to mess about and 
write about something I have just learnt in the last hour. That 
could do more damage than good.




Re: Linux shared library loading/linking from C does not invoke (shared) static this

2021-01-12 Thread ichneumwn via Digitalmars-d-learn

On Tuesday, 12 January 2021 at 08:19:45 UTC, ichneumwn wrote:

Dear all,

I was trying to invoke some D code from Python and ran into 
issues which I eventually traced back to a simple example on 
the D website itself :


https://dlang.org/articles/dll-linux.html

Particularly the section "Dynamically Loading a D DLL From a C 
Program"


In my case, and indeed already in 2013 
(https://forum.dlang.org/post/yeqyqaaguhngczlnv...@forum.dlang.org), shared static this does not get invoked


I normally use:
LDC - the LLVM D compiler (1.21.0):
  based on DMD v2.091.1 and LLVM 10.0.0   (under Linux)

but I also tried
DMD64 D Compiler v2.095.0

Is the solution suggested in the linked post the "canonical 
way"?


Where could one file a suggestion for an update to the 
documentation?


Cheers!

PS Enjoying my project in D especially how easy it is to get 
the same code to run under windows too


Follow on to my own question: on Linux, with gcc, I have created 
the following file "starter.c" that I inject into my D shared 
library:


  int rt_init(void);
  int rt_term(void);

  // should really check for errors!
  static void __attribute__((constructor)) Dstarter(void) {
rt_init();
  }

  static void __attribute__((destructor)) Dterminator(void) {
rt_term();
  }

That seems to do the trick. Not sure how clean this is?





Linux shared library loading/linking from C does not invoke (shared) static this

2021-01-12 Thread ichneumwn via Digitalmars-d-learn

Dear all,

I was trying to invoke some D code from Python and ran into 
issues which I eventually traced back to a simple example on the 
D website itself :


https://dlang.org/articles/dll-linux.html

Particularly the section "Dynamically Loading a D DLL From a C 
Program"


In my case, and indeed already in 2013 
(https://forum.dlang.org/post/yeqyqaaguhngczlnv...@forum.dlang.org), shared static this does not get invoked


I normally use:
LDC - the LLVM D compiler (1.21.0):
  based on DMD v2.091.1 and LLVM 10.0.0   (under Linux)

but I also tried
DMD64 D Compiler v2.095.0

Is the solution suggested in the linked post the "canonical way"?

Where could one file a suggestion for an update to the 
documentation?


Cheers!

PS Enjoying my project in D especially how easy it is to get the 
same code to run under windows too







Re: Waiting on file descriptor/socket *AND* thread messages

2020-06-29 Thread ichneumwn via Digitalmars-d-learn
On Monday, 29 June 2020 at 12:25:16 UTC, Steven Schveighoffer 
wrote:

On 6/29/20 5:14 AM, ichneumwn wrote:

[...]


Not in the standard library. Such things require an event 
framework, because there is no OS-agnostic provided mechanism 
to sleep on all these things at once.


I recommend looking through code.dlang.org. I found these:

https://code.dlang.org/packages/libasync
https://code.dlang.org/packages/eventcore
https://code.dlang.org/packages/mecca (this seems very 
underdocumented, but I know it provides such a system)



[...]


I don't know the correct way to solve this, I've done it in the 
past by creating a file descriptor that can be waited on to 
wake up the target along with any other file descriptors being 
waited on.


-Steve


Thanks for the pointers Steve!


Waiting on file descriptor/socket *AND* thread messages

2020-06-29 Thread ichneumwn via Digitalmars-d-learn

Dear all,

Is there some facility in D for a single statement/function call 
that will wait on both file descriptors, like Socket.select(), 
and will also wake up when there is something to be receive()'d?


One solution would be to have my main thread use receive() and a 
helper thread that does the select() call and sends a message to 
the main thread. That seems a bit of overkill however.


Apologies if this has been asked before, but my google search and 
search in this thread were fruitless (could be my searching 
skills)


Cheers