Re: Warning on self assignment

2018-04-24 Thread Mike Franklin via Digitalmars-d-learn

On Wednesday, 25 April 2018 at 01:20:13 UTC, Mike Franklin wrote:

It appears a bug has already been filed 
(https://issues.dlang.org/show_bug.cgi?id=11970).  I'll see if 
I can fix it.


https://github.com/dlang/dmd/pull/8208

We'll see what happens.



Re: Add property-like Function to Type ?

2018-04-24 Thread Meta via Digitalmars-d-learn

On Tuesday, 24 April 2018 at 21:36:19 UTC, Rubn wrote:
I was wondering if I could create my own property in a way that 
can be used the same way as something like "T.sizeof". Right 
now I have the following to replace length:


uint length32(T)(T[] array)
{
return cast(uint)array.length;
}

I want something similar to be able to do the following:


uint size = T.sizeof32;

The closest I can think of is doing:

uint size = sizeof32!T


That's the best I can do, which is fine but I was wondering if 
there's any other way around that?


If you don't control T and can't add members, then the best thing 
you can probably do is instead write T.init.sizeof32. Actually, 
though, you can be sneaky about it and use a local function to 
shadow Test, but this is probably more trouble than it's worth:


import std.stdio;

struct Test
{
}

@property sizeof32(Test t) { return 1; }

void main()
{
@property Test() { return .Test.init; }
writeln(Test.sizeof32);
}

This is really annoying, though, because you have to declare the 
Test function in every function or struct/class definition you 
use it in. You can create a mixin that does it automatically, but 
you'd still have to do `mixin(testProperties)` (where 
testProperties is an enum you've defined that's just the function 
definition).


Re: Warning on self assignment

2018-04-24 Thread Meta via Digitalmars-d-learn

On Wednesday, 25 April 2018 at 02:32:32 UTC, Per Nordlöw wrote:
On Wednesday, 25 April 2018 at 02:23:04 UTC, Mike Franklin 
wrote:
Are people using self assignment of structs as a way of 
force-running the postblit?  Is there a valid use case for 
that?


Mike


If they are, there should be a better way of force-running the 
postblit.


You can call __postblit or __xpostblit (I think the latter is a 
postblit introduced via a mixin or template mixin).


Re: Warning on self assignment

2018-04-24 Thread Per Nordlöw via Digitalmars-d-learn

On Wednesday, 25 April 2018 at 02:23:04 UTC, Mike Franklin wrote:
Are people using self assignment of structs as a way of 
force-running the postblit?  Is there a valid use case for that?


Mike


If they are, there should be a better way of force-running the 
postblit.


Re: Warning on self assignment

2018-04-24 Thread Mike Franklin via Digitalmars-d-learn
On Wednesday, 25 April 2018 at 01:08:46 UTC, Arun Chandrasekaran 
wrote:
So I was telling my colleague that D would warn on self 
assignment, but found that I was wrong.


https://run.dlang.io/is/HLhtek

```
module a;

import std.stdio;

void main() {
string a;
a = a;  // Can the compiler warn at this line that 
there is no effect?

writeln(a);
return;
}
```


Are people using self assignment of structs as a way of 
force-running the postblit?  Is there a valid use case for that?


Mike


Re: Are Fibers just broken in D?

2018-04-24 Thread bitwise via Digitalmars-d-learn

On Friday, 20 April 2018 at 18:58:36 UTC, Byron Moxie wrote:

[...]
In WIN32 it looks like its leaking memory


Unless there is something I'm misunderstanding, it seems that 
Fibers that were not run to completion won't unroll their stack, 
which would mean that some destructors wouldn't be called, and 
possibly, some memory wouldn't be freed:


https://github.com/dlang/druntime/blob/86cd40a036a67d9b1bff6c14e91cba1e5557b119/src/core/thread.d#L4142

Could this have something to do with the problem?



Re: Warning on self assignment

2018-04-24 Thread Mike Franklin via Digitalmars-d-learn
On Wednesday, 25 April 2018 at 01:08:46 UTC, Arun Chandrasekaran 
wrote:
So I was telling my colleague that D would warn on self 
assignment, but found that I was wrong.


https://run.dlang.io/is/HLhtek

```
module a;

import std.stdio;

void main() {
string a;
a = a;  // Can the compiler warn at this line that 
there is no effect?

writeln(a);
return;
}
```


It appears a bug has already been filed 
(https://issues.dlang.org/show_bug.cgi?id=11970).  I'll see if I 
can fix it.


Mike


Warning on self assignment

2018-04-24 Thread Arun Chandrasekaran via Digitalmars-d-learn
So I was telling my colleague that D would warn on self 
assignment, but found that I was wrong.


https://run.dlang.io/is/HLhtek

```
module a;

import std.stdio;

void main() {
string a;
a = a;  // Can the compiler warn at this line that 
there is no effect?

writeln(a);
return;
}
```


Re: Sense check: construction / deconstruction

2018-04-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/24/18 6:59 PM, Jordan Wilson wrote:

I have the following code:
import std.stdio;
import std.typecons;
import d2sqlite3;

class A {
     Database db;
     this ( Database d) {
     db = d;
     }
}

class B {
     Database* db;
     this ( Database* d) {
     db = d;
     }
}

void main() {
     auto db = Database(":memory:");
     auto a = new A(db); // gives message:
     // Error: clean-up of Database incorrectly
     // depends on destructors called by the GC

     auto b = new B(); // no message
     auto c = scoped!A(db); // no message
}

Assumption 1: "a" gives me an error message due to the fact that proper 
clean up of db depends on a being collected by the GC, and this behavior 
is being dis-allowed through use of the idiom 
https://p0nce.github.io/d-idioms/#GC-proof-resource-class?

The relevant function calling the error message is:
void ensureNotInGC(T)(string info = null) nothrow
{
     import core.exception : InvalidMemoryOperationError;
     try
     {
     import core.memory : GC;
     cast(void) GC.malloc(1);
     return;
     }
     catch(InvalidMemoryOperationError e)
     {
     // error message here
     }
}

Assumption 2: "b" gives me no error messages because the class B uses 
pointers, which moves it from relying on GC, to being manually free?


Assumption 3: "c" gives me no error messages because...well, I don't 
really understand why, maybe because c is in the same scope as db?


What you are missing is that Database is pass-by-value, not a class. So 
when you include it directly in a class like you did in A, then when A's 
destructor is called, db's destructor is called.


Since in the first case, a is being destroyed by the GC, you get the error.

In the second case (b), you aren't including the db by value, so no 
destructor is called from the GC. But this is dangerous, because db 
stops existing after main exits, but b continues to exist in the GC, so 
this is a dangling pointer.


In the third case, scoped specifically destroys c when main exits, and 
you are not in the GC at that point.


What the error message is telling you is you should manually clean up 
the database directly instead of leaving it to the GC. What is the 
correct path? probably the scoped!A version. Though I'm not sure what 
making copies of the database does in that library.


-Steve


Sense check: construction / deconstruction

2018-04-24 Thread Jordan Wilson via Digitalmars-d-learn

I have the following code:
import std.stdio;
import std.typecons;
import d2sqlite3;

class A {
Database db;
this ( Database d) {
db = d;
}
}

class B {
Database* db;
this ( Database* d) {
db = d;
}
}

void main() {
auto db = Database(":memory:");
auto a = new A(db); // gives message:
// Error: clean-up of Database incorrectly
// depends on destructors called by the GC

auto b = new B(); // no message
auto c = scoped!A(db); // no message
}

Assumption 1: "a" gives me an error message due to the fact that 
proper clean up of db depends on a being collected by the GC, and 
this behavior is being dis-allowed through use of the idiom 
https://p0nce.github.io/d-idioms/#GC-proof-resource-class?

The relevant function calling the error message is:
void ensureNotInGC(T)(string info = null) nothrow
{
import core.exception : InvalidMemoryOperationError;
try
{
import core.memory : GC;
cast(void) GC.malloc(1);
return;
}
catch(InvalidMemoryOperationError e)
{
// error message here
}
}

Assumption 2: "b" gives me no error messages because the class B 
uses pointers, which moves it from relying on GC, to being 
manually free?


Assumption 3: "c" gives me no error messages because...well, I 
don't really understand why, maybe because c is in the same scope 
as db?


Thanks,

Jordan


Re: Add property-like Function to Type ?

2018-04-24 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, April 24, 2018 21:36:19 Rubn via Digitalmars-d-learn wrote:
> I was wondering if I could create my own property in a way that
> can be used the same way as something like "T.sizeof". Right now
> I have the following to replace length:
>
> uint length32(T)(T[] array)
> {
>  return cast(uint)array.length;
> }
>
> I want something similar to be able to do the following:
>
>
> uint size = T.sizeof32;
>
> The closest I can think of is doing:
>
> uint size = sizeof32!T
>
>
> That's the best I can do, which is fine but I was wondering if
> there's any other way around that?

If you're dealing with a user-defined type, you can declare an enum or
static function on it to do something like T.sizeof32. However, you can't
add stuff like that without editing the type itself, so it won't work with
any types that you aren't defining yourself - especially built-in types.

If you're willing to use an instance of the type, then you can declare a
free function and use UFCS, but as soon as you want to use the type itself,
you're going to need to use a template, which means something like
sizeof32!T rather than T.sizeof32.

- Jonathan M Davis



Add property-like Function to Type ?

2018-04-24 Thread Rubn via Digitalmars-d-learn
I was wondering if I could create my own property in a way that 
can be used the same way as something like "T.sizeof". Right now 
I have the following to replace length:


uint length32(T)(T[] array)
{
return cast(uint)array.length;
}

I want something similar to be able to do the following:


uint size = T.sizeof32;

The closest I can think of is doing:

uint size = sizeof32!T


That's the best I can do, which is fine but I was wondering if 
there's any other way around that?


Using an external Assembler with D

2018-04-24 Thread solidstate1991 via Digitalmars-d-learn
In order to make one of my own code more readable (and hopefully 
to avoid a lot of compiling errors under LDC, which don't happen 
in DMD for some reason), I'm planning to put my assembly 
functions into separate files for each system that needs them, 
mainly due to the lack of proper SIMD support, mainly due to 
these functions are relatively easy to implement. Here's a few 
questions of mine:


- Can I return vectors in XMM registers and accept arguments as 
vectors in them?
- How much is the D ABI differs on DMD and LDC for x86? I'm 
planning to support both (with mainly using DMD as a debug 
compiler for its speed), and want the most universal solution 
possible.


Re: Are Fibers just broken in D?

2018-04-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/24/18 4:30 PM, Steven Schveighoffer wrote:

I'll file an issue. We may not be able to solve the problem, but it's 
something we should try and solve.


Seems there's already a similar issue in there: 
https://issues.dlang.org/show_bug.cgi?id=3523


-Steve


Re: Are Fibers just broken in D?

2018-04-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/24/18 3:45 PM, Radu wrote:

On Tuesday, 24 April 2018 at 16:05:48 UTC, Steven Schveighoffer wrote:

On 4/24/18 10:16 AM, Radu wrote:

On Tuesday, 24 April 2018 at 13:36:48 UTC, Steven Schveighoffer wrote:

On 4/24/18 5:11 AM, bauss wrote:

On Tuesday, 24 April 2018 at 07:58:01 UTC, Radu wrote:

On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:

[...]


This is not a fiber issue but a more memory management issue. Your 
run out of address space on win32, the GC will not always collect 
all those 9 fibers that you allocate in that loop. As an 
exercise replace `auto` with `scope` like `scope foo = new Foo();` 
in that loop - you should see different results.


This shouldn't be a requirement, the 32-bit GC is generally not this 
bad.




Allocating so many fibers in a loop produces an OOM error on win32, 
that's a fact! Event though it doesn't always happen you often get 
OOM errors with the program above.


I'm not saying it doesn't happen, just that it *shouldn't* happen. At 
least not for small sized chunks like this.


I want to emphasize that the program is allocating and releasing to 
the GC 1 fiber at a time -- loop or no loop, this should work (more or 
less) reliably, or Win32 has some more serious issues.




Changing main to
---
void main(string[] args)
{
     import core.memory;
     foreach(ulong i; 0..99_999) {
     auto foo = new Foo();
     foo.call();
     foo.call();
     if (i % 1) // <-- this
     GC.collect();
     }
}
---

makes the OOM error go away.


This made it click for me -- VirtualAlloc does NOT allocate from the GC. 
I had mistakenly thought the GC was being used to allocate the stack. 
This means there is little to no pressure on the GC to run a collection 
even though all the memory is being consumed. In other words, the 
runtime has plenty of space to allocate the Fiber class (which is likely 
about 64 or 128 bytes per instance), and is consuming all the memory via 
VirtualAlloc.


I also noticed, Windows default stack size is 32k, not 16k (as it is on 
other systems), so 100,000 stacks in that case is 3.2GB. That's too much 
for sure.


I'll file an issue. We may not be able to solve the problem, but it's 
something we should try and solve.


Thanks

-Steve


Re: Are Fibers just broken in D?

2018-04-24 Thread Radu via Digitalmars-d-learn
On Tuesday, 24 April 2018 at 16:05:48 UTC, Steven Schveighoffer 
wrote:

On 4/24/18 10:16 AM, Radu wrote:
On Tuesday, 24 April 2018 at 13:36:48 UTC, Steven 
Schveighoffer wrote:

On 4/24/18 5:11 AM, bauss wrote:

On Tuesday, 24 April 2018 at 07:58:01 UTC, Radu wrote:
On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads 
wrote:

[...]


This is not a fiber issue but a more memory management 
issue. Your run out of address space on win32, the GC will 
not always collect all those 9 fibers that you allocate 
in that loop. As an exercise replace `auto` with `scope` 
like `scope foo = new Foo();` in that loop - you should see 
different results.


This shouldn't be a requirement, the 32-bit GC is generally 
not this bad.




Allocating so many fibers in a loop produces an OOM error on 
win32, that's a fact! Event though it doesn't always happen 
you often get OOM errors with the program above.


I'm not saying it doesn't happen, just that it *shouldn't* 
happen. At least not for small sized chunks like this.


I want to emphasize that the program is allocating and 
releasing to the GC 1 fiber at a time -- loop or no loop, this 
should work (more or less) reliably, or Win32 has some more 
serious issues.




Changing main to
---
void main(string[] args)
{
import core.memory;
foreach(ulong i; 0..99_999) {
auto foo = new Foo();
foo.call();
foo.call();
if (i % 1) // <-- this
GC.collect();
}
}
---

makes the OOM error go away.



Re: Are Fibers just broken in D?

2018-04-24 Thread rikki cattermole via Digitalmars-d-learn

On 25/04/2018 5:13 AM, Steven Schveighoffer wrote:

On 4/24/18 12:49 PM, kinke wrote:

On Tuesday, 24 April 2018 at 16:22:04 UTC, Steven Schveighoffer wrote:

On 4/24/18 10:31 AM, Byron Heads wrote:
I will start ignoring win32 when win64 doesn't require dealing with 
visual studio installs.

Also I have a feeling a client will ask for it.


Unfortunately I don't think the VS license will ever allow us to 
avoid installing VS as well.


DMD doesn't require VS anymore since v2.079.


Oh? That's good news. What do you need to install instead? Or do we 
include the SDK library directly?


I had thought there were licensing issues, but glad to be wrong!

-Steve


We are not providing it, its coming straight from MS, no licensing issues.


Re: Are Fibers just broken in D?

2018-04-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/24/18 12:49 PM, kinke wrote:

On Tuesday, 24 April 2018 at 16:22:04 UTC, Steven Schveighoffer wrote:

On 4/24/18 10:31 AM, Byron Heads wrote:
I will start ignoring win32 when win64 doesn't require dealing with 
visual studio installs.

Also I have a feeling a client will ask for it.


Unfortunately I don't think the VS license will ever allow us to avoid 
installing VS as well.


DMD doesn't require VS anymore since v2.079.


Oh? That's good news. What do you need to install instead? Or do we 
include the SDK library directly?


I had thought there were licensing issues, but glad to be wrong!

-Steve


Re: Are Fibers just broken in D?

2018-04-24 Thread kinke via Digitalmars-d-learn
On Tuesday, 24 April 2018 at 16:22:04 UTC, Steven Schveighoffer 
wrote:

On 4/24/18 10:31 AM, Byron Heads wrote:
I will start ignoring win32 when win64 doesn't require dealing 
with visual studio installs.

Also I have a feeling a client will ask for it.


Unfortunately I don't think the VS license will ever allow us 
to avoid installing VS as well.


DMD doesn't require VS anymore since v2.079.


Re: Are Fibers just broken in D?

2018-04-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/24/18 10:31 AM, Byron Heads wrote:

On Tuesday, 24 April 2018 at 13:36:48 UTC, Steven Schveighoffer wrote:
This is not the case of executing 100,000 concurrent fibers, but 
executing 100,000 *sequential* fibers. It should work just fine.




Correct, in a normal run of my system there maybe 10-20 fibers max 
alive. I was using threads only before, but found the system to execute 
jobs in a balanced way. But using a few threads to process Fibers keep 
in a queue balances out the work evenly. It is also easier to track down 
bugs by just using 1 thread to process the fiber pool.


I would love to use dip1000, Allocators, and shared. But none of that 
stuff really works beyond trivial examples. (Allocators probably works 
fine, but there are forum post about it changing and I dont want to 
refactor it twice..)


stdx.allocator (https://github.com/dlang-community/stdx-allocator and 
http://code.dlang.org/packages/stdx-allocator) is "stable", you can use 
that instead of the one inside phobos. This way, even if phobos 
introduces breaking changes, you can depend on a specific version of the 
allocators. DIP1000 is very much a work in progress, I'm unsure if/when 
it will become usable. Shared likely isn't going to get any better until 
the main players start focusing on it. Right now, I think they are more 
interested in memory safety.


I will start ignoring win32 when win64 doesn't require dealing with 
visual studio installs.

Also I have a feeling a client will ask for it.


Unfortunately I don't think the VS license will ever allow us to avoid 
installing VS as well.


My recommendation is just to ignore Win32. I wouldn't trust it at all. 
There are serious threading issues there, and the GC is prone to run out 
of memory if you aren't careful.


But I can understand if you can't go that route.

Another thing to try is -m32mscoff, which creates 32-bit binaries, but 
links against Microsoft's runtime instead of DMD. While this is a stated 
problem from you, it may help to determine if it's really the digital 
mars library or something more inherent in the way Fibers or the GC is 
working.


-Steve


Re: Are Fibers just broken in D?

2018-04-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/24/18 10:16 AM, Radu wrote:

On Tuesday, 24 April 2018 at 13:36:48 UTC, Steven Schveighoffer wrote:

On 4/24/18 5:11 AM, bauss wrote:

On Tuesday, 24 April 2018 at 07:58:01 UTC, Radu wrote:

On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:

[...]


This is not a fiber issue but a more memory management issue. Your 
run out of address space on win32, the GC will not always collect 
all those 9 fibers that you allocate in that loop. As an 
exercise replace `auto` with `scope` like `scope foo = new Foo();` 
in that loop - you should see different results.


This shouldn't be a requirement, the 32-bit GC is generally not this bad.



Allocating so many fibers in a loop produces an OOM error on win32, 
that's a fact! Event though it doesn't always happen you often get OOM 
errors with the program above.


I'm not saying it doesn't happen, just that it *shouldn't* happen. At 
least not for small sized chunks like this.


I want to emphasize that the program is allocating and releasing to the 
GC 1 fiber at a time -- loop or no loop, this should work (more or less) 
reliably, or Win32 has some more serious issues.


This isn't even a case of multi-threading, there are no extra threads here.

Probably the cause is related to how often the collection kicks in in 
relation to the pages allocated via VirtualAlloc. But still, the issue 
OP raised is not a Fiber related issue but a memory management issue.


Collections usually happen more often than they should. The biggest 
issue with 32-bit arch is that random stack data often keeps large 
blocks of memory from being collected. As those build up, the situation 
gets worse until you have no more memory left.


But smaller chunks like a 16k Fiber stack should work without issues.

It should be simple to prove, instead of allocating a fiber, allocate a 
similar sized chunk of bytes.


-Steve


Re: Are Fibers just broken in D?

2018-04-24 Thread Byron Heads via Digitalmars-d-learn
On Tuesday, 24 April 2018 at 13:36:48 UTC, Steven Schveighoffer 
wrote:

On 4/24/18 5:11 AM, bauss wrote:

On Tuesday, 24 April 2018 at 07:58:01 UTC, Radu wrote:

On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:


Fibers on Win32 have a memory leak for sure:

import core.thread : Fiber;

void main() {

    foreach(ulong i; 0..99_999) {
    auto foo = new Foo();
    foo.call();
    foo.call();
    }
}


class Foo : Fiber {
    this() {
    super();
    }


    void run() {
    Fiber.yield();
    }
}


Running this with -m64 on windows runs without a problem, 
but with -m32 it failes aith a Memory Allocation failed 
error.


This is not a fiber issue but a more memory management issue. 
Your run out of address space on win32, the GC will not 
always collect all those 9 fibers that you allocate in 
that loop. As an exercise replace `auto` with `scope` like 
`scope foo = new Foo();` in that loop - you should see 
different results.


This shouldn't be a requirement, the 32-bit GC is generally not 
this bad.




The issue boils down to the call to VirtualAlloc that the 
fiber constructor makes, which fails as Windows will not 
allocate any more virtual pages for the process. If you 
really want that many fibers you should reconsider 32 bit, 
and definitely use a different allocation strategy.


And in the end of the day it makes no sense to have that many 
fibers as they would probably perform terrible.


Let's not forget though, that he's executing the fiber 
completely within the loop. It should be done and collected.


This is not the case of executing 100,000 concurrent fibers, 
but executing 100,000 *sequential* fibers. It should work just 
fine.


-Steve


Correct, in a normal run of my system there maybe 10-20 fibers 
max alive. I was using threads only before, but found the system 
to execute jobs in a balanced way. But using a few threads to 
process Fibers keep in a queue balances out the work evenly. It 
is also easier to track down bugs by just using 1 thread to 
process the fiber pool.


I would love to use dip1000, Allocators, and shared. But none of 
that stuff really works beyond trivial examples. (Allocators 
probably works fine, but there are forum post about it changing 
and I dont want to refactor it twice..)


I will start ignoring win32 when win64 doesn't require dealing 
with visual studio installs.

Also I have a feeling a client will ask for it.



Re: Are Fibers just broken in D?

2018-04-24 Thread Radu via Digitalmars-d-learn
On Tuesday, 24 April 2018 at 13:36:48 UTC, Steven Schveighoffer 
wrote:

On 4/24/18 5:11 AM, bauss wrote:

On Tuesday, 24 April 2018 at 07:58:01 UTC, Radu wrote:

On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:

[...]


This is not a fiber issue but a more memory management issue. 
Your run out of address space on win32, the GC will not 
always collect all those 9 fibers that you allocate in 
that loop. As an exercise replace `auto` with `scope` like 
`scope foo = new Foo();` in that loop - you should see 
different results.


This shouldn't be a requirement, the 32-bit GC is generally not 
this bad.




Allocating so many fibers in a loop produces an OOM error on 
win32, that's a fact! Event though it doesn't always happen you 
often get OOM errors with the program above.


Probably the cause is related to how often the collection kicks 
in in relation to the pages allocated via VirtualAlloc. But 
still, the issue OP raised is not a Fiber related issue but a 
memory management issue.




The issue boils down to the call to VirtualAlloc that the 
fiber constructor makes, which fails as Windows will not 
allocate any more virtual pages for the process. If you 
really want that many fibers you should reconsider 32 bit, 
and definitely use a different allocation strategy.


And in the end of the day it makes no sense to have that many 
fibers as they would probably perform terrible.


Let's not forget though, that he's executing the fiber 
completely within the loop. It should be done and collected.


This is not the case of executing 100,000 concurrent fibers, 
but executing 100,000 *sequential* fibers. It should work just 
fine.


-Steve




Re: Are Fibers just broken in D?

2018-04-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/24/18 5:11 AM, bauss wrote:

On Tuesday, 24 April 2018 at 07:58:01 UTC, Radu wrote:

On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:


Fibers on Win32 have a memory leak for sure:

import core.thread : Fiber;

void main() {

    foreach(ulong i; 0..99_999) {
    auto foo = new Foo();
    foo.call();
    foo.call();
    }
}


class Foo : Fiber {
    this() {
    super();
    }


    void run() {
    Fiber.yield();
    }
}


Running this with -m64 on windows runs without a problem, but with 
-m32 it failes aith a Memory Allocation failed error.


This is not a fiber issue but a more memory management issue. Your run 
out of address space on win32, the GC will not always collect all 
those 9 fibers that you allocate in that loop. As an exercise 
replace `auto` with `scope` like `scope foo = new Foo();` in that loop 
- you should see different results.


This shouldn't be a requirement, the 32-bit GC is generally not this bad.



The issue boils down to the call to VirtualAlloc that the fiber 
constructor makes, which fails as Windows will not allocate any more 
virtual pages for the process. If you really want that many fibers you 
should reconsider 32 bit, and definitely use a different allocation 
strategy.


And in the end of the day it makes no sense to have that many fibers as 
they would probably perform terrible.


Let's not forget though, that he's executing the fiber completely within 
the loop. It should be done and collected.


This is not the case of executing 100,000 concurrent fibers, but 
executing 100,000 *sequential* fibers. It should work just fine.


-Steve


Re: Are Fibers just broken in D?

2018-04-24 Thread bauss via Digitalmars-d-learn

On Tuesday, 24 April 2018 at 07:58:01 UTC, Radu wrote:

On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:

On Friday, 20 April 2018 at 20:52:17 UTC, Byron Moxie wrote:
On Friday, 20 April 2018 at 20:46:20 UTC, Steven 
Schveighoffer wrote:

On 4/20/18 2:58 PM, Byron Moxie wrote:

[...]


It sounds like the problems may be due to Win32 and not the 
other pieces. Have you tried on a Win64 build? Even if 
that's not your target, at least it can help you discover 
whether that is the problem or not. The DMC runtime is the 
default on Win32, and it's not especially thread-safe in all 
places.


FWIW, I'm using vibe.d on Linux 64 bit with no problems (and 
I've NEVER heard of atomicLoad and atomicStore not working 
on any arch).


-Steve


I had move the data I wanted to sync with atomicLoad/Store 
into a shared struct and pass a pointer to this struct to the 
other fibers. Not sure if this was an issue with TLS messing 
with class object I was passing around.




Fibers on Win32 have a memory leak for sure:

import core.thread : Fiber;

void main() {

foreach(ulong i; 0..99_999) {
auto foo = new Foo();
foo.call();
foo.call();
}
}


class Foo : Fiber {
this() {
super();
}


void run() {
Fiber.yield();
}
}


Running this with -m64 on windows runs without a problem, but 
with -m32 it failes aith a Memory Allocation failed error.


This is not a fiber issue but a more memory management issue. 
Your run out of address space on win32, the GC will not always 
collect all those 9 fibers that you allocate in that loop. 
As an exercise replace `auto` with `scope` like `scope foo = 
new Foo();` in that loop - you should see different results.


The issue boils down to the call to VirtualAlloc that the fiber 
constructor makes, which fails as Windows will not allocate any 
more virtual pages for the process. If you really want that 
many fibers you should reconsider 32 bit, and definitely use a 
different allocation strategy.


And in the end of the day it makes no sense to have that many 
fibers as they would probably perform terrible.


Re: Are Fibers just broken in D?

2018-04-24 Thread Radu via Digitalmars-d-learn

On Tuesday, 24 April 2018 at 00:46:39 UTC, Byron Heads wrote:

On Friday, 20 April 2018 at 20:52:17 UTC, Byron Moxie wrote:
On Friday, 20 April 2018 at 20:46:20 UTC, Steven Schveighoffer 
wrote:

On 4/20/18 2:58 PM, Byron Moxie wrote:

[...]


It sounds like the problems may be due to Win32 and not the 
other pieces. Have you tried on a Win64 build? Even if that's 
not your target, at least it can help you discover whether 
that is the problem or not. The DMC runtime is the default on 
Win32, and it's not especially thread-safe in all places.


FWIW, I'm using vibe.d on Linux 64 bit with no problems (and 
I've NEVER heard of atomicLoad and atomicStore not working on 
any arch).


-Steve


I had move the data I wanted to sync with atomicLoad/Store 
into a shared struct and pass a pointer to this struct to the 
other fibers. Not sure if this was an issue with TLS messing 
with class object I was passing around.




Fibers on Win32 have a memory leak for sure:

import core.thread : Fiber;

void main() {

foreach(ulong i; 0..99_999) {
auto foo = new Foo();
foo.call();
foo.call();
}
}


class Foo : Fiber {
this() {
super();
}


void run() {
Fiber.yield();
}
}


Running this with -m64 on windows runs without a problem, but 
with -m32 it failes aith a Memory Allocation failed error.


This is not a fiber issue but a more memory management issue. 
Your run out of address space on win32, the GC will not always 
collect all those 9 fibers that you allocate in that loop. As 
an exercise replace `auto` with `scope` like `scope foo = new 
Foo();` in that loop - you should see different results.


The issue boils down to the call to VirtualAlloc that the fiber 
constructor makes, which fails as Windows will not allocate any 
more virtual pages for the process. If you really want that many 
fibers you should reconsider 32 bit, and definitely use a 
different allocation strategy.