Re: DUB, link automatically right object for platform and archi

2016-09-01 Thread rikki cattermole via Digitalmars-d-learn

On 02/09/2016 6:01 AM, Basile B. wrote:

I've converted this section:


"configurations" : [
{
  "name" : "nux32",
  "dflags" : [
"objects/coff32/beaengine.o"
  ]
},
{
  "name" : "nux64",
  "dflags" : [
"objects/coff64/beaengine.o"
  ]
},
{
  "name" : "win32",
  "dflags" : [
"objects\\omf32\\beaengine.obj"
  ]


to:


  "buildSettings" : {
"dflags-linux-x86" : ["objects/coff32/beaengine.o"],
"dflags-linux-x86_64" : ["objects/coff64/beaengine.o"],
"dflags-windows-x86" : ["objects\\omf32\\beaengine.obj"]
  },


Because previously the right config could not be selected when the
package was used as dependency. But now the object is not linked in the
static library produced by the project.

What's wrong in my description ?


Well for starters buildSettings is just a name given to a group of 
properties. It doesn't actually go INTO the dub file.


dflags is valid in top level config, subPackage and of course configuration.


Re: Fiber cross threads terminated

2016-09-01 Thread mogu via Digitalmars-d-learn
On Friday, 2 September 2016 at 01:53:58 UTC, Steven Schveighoffer 
wrote:

On 9/1/16 9:27 PM, mogu wrote:

Here's my code in main function:
```
auto fiber = new Fiber({
while (true) {
Thread.sleep(1.seconds);
Fiber.yield;
}
});

void foo() {
while (true) {
fiber.call;
//Thread.sleep(1.seconds);
//"---".writeln;
}
}

new Thread({
foo();
}).start;

new Thread({
Thread.sleep(500.msecs);
foo();
}).start;

```
If I comment the `fiber.call;`, all works.
system: ubuntu 16.04LTS
dmd version: 2.071.1


Fibers in D are not meant to be run in multiple threads.

-Steve


Thanks. I got it.


Re: Fiber cross threads terminated

2016-09-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/1/16 9:27 PM, mogu wrote:

Here's my code in main function:
```
auto fiber = new Fiber({
while (true) {
Thread.sleep(1.seconds);
Fiber.yield;
}
});

void foo() {
while (true) {
fiber.call;
//Thread.sleep(1.seconds);
//"---".writeln;
}
}

new Thread({
foo();
}).start;

new Thread({
Thread.sleep(500.msecs);
foo();
}).start;

```
If I comment the `fiber.call;`, all works.
system: ubuntu 16.04LTS
dmd version: 2.071.1


Fibers in D are not meant to be run in multiple threads.

-Steve


Fiber cross threads terminated

2016-09-01 Thread mogu via Digitalmars-d-learn

Here's my code in main function:
```
auto fiber = new Fiber({
while (true) {
Thread.sleep(1.seconds);
Fiber.yield;
}
});

void foo() {
while (true) {
fiber.call;
//Thread.sleep(1.seconds);
//"---".writeln;
}
}

new Thread({
foo();
}).start;

new Thread({
Thread.sleep(500.msecs);
foo();
}).start;

```
If I comment the `fiber.call;`, all works.
system: ubuntu 16.04LTS
dmd version: 2.071.1


Re: Storing a reference

2016-09-01 Thread Yuxuan Shui via Digitalmars-d-learn
On Thursday, 1 September 2016 at 21:07:36 UTC, Steven 
Schveighoffer wrote:

On 9/1/16 4:38 PM, Yuxuan Shui wrote:

[...]


Referring to a null object is not a problem. Your program 
crashes ungracefully, but does not corrupt memory. However, in 
either approach, it can easily end up being a dangling pointer.


But to refer to a null location is quite easy:

int *foo; // null ptr
auto a = x(*foo);
assert(() == null);

Your approach is less desirable because of the closure to point 
at a given reference which can be had with just a reference. 
Needless allocation.


-Steve


Makes sense. Thanks!


Re: Storing a reference

2016-09-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/1/16 4:38 PM, Yuxuan Shui wrote:

On Thursday, 1 September 2016 at 20:28:03 UTC, Rene Zwanenburg wrote:

On Thursday, 1 September 2016 at 19:37:25 UTC, Yuxuan Shui wrote:

[...]


This will allocate a closure. A struct definition inside a function
has a hidden context / closure pointer, unless it's a static struct.

There is nothing like a ref variable in D. If you want to refer to
something someplace else, use a pointer. You can create a pointer
wrapper which acts like a reference (untested):


auto toRef(ref T value)
{
  return Ref!T();
}

struct Ref(T)
{
  private T* value;
  @property ref T _value() { return *value; }
  alias _value this;
}

Note that D's pointer syntax is a bit friendlier than C++'s: the dot
operator works fine on pointers. A good reason to use the Ref wrapper
is to forward arithmetic operations to the wrapped value.


I think my approach is probably better, because I believe (correct me if
I'm wrong): 1) it will never refer to a null object. 2) after DIP1000 is
implemented we will be able to make sure there will be no dangling
reference.


Referring to a null object is not a problem. Your program crashes 
ungracefully, but does not corrupt memory. However, in either approach, 
it can easily end up being a dangling pointer.


But to refer to a null location is quite easy:

int *foo; // null ptr
auto a = x(*foo);
assert(() == null);

Your approach is less desirable because of the closure to point at a 
given reference which can be had with just a reference. Needless allocation.


-Steve


Re: Storing a reference

2016-09-01 Thread Rene Zwanenburg via Digitalmars-d-learn

On Thursday, 1 September 2016 at 20:38:13 UTC, Yuxuan Shui wrote:
I think my approach is probably better, because I believe 
(correct me if I'm wrong): 1) it will never refer to a null 
object.


That's true, but you can ensure the same thing for the wrapper:

struct Ref()
{
  @disable this();
  this(T* value)
  {
assert(value !is null);
this.value = value;
  }
  // rest same as before
}

2) after DIP1000 is implemented we will be able to make sure 
there will be no dangling reference.


I'm not very familiar with the details of DIP1000, so I can't 
comment on that.


Re: DUB, link automatically right object for platform and archi

2016-09-01 Thread Basile B. via Digitalmars-d-learn

On Thursday, 1 September 2016 at 18:01:19 UTC, Basile B. wrote:

I've converted this section:
[...]
to:


  "buildSettings" : {
"dflags-linux-x86" : ["objects/coff32/beaengine.o"],
"dflags-linux-x86_64" : ["objects/coff64/beaengine.o"],
"dflags-windows-x86" : ["objects\\omf32\\beaengine.obj"]
  },


Because previously the right config could not be selected when 
the package was used as dependency. But now the object is not 
linked in the static library produced by the project.


What's wrong in my description ?


neither dflags, lflags nor sourceFiles work. Strangely enough 
this new section is completely missing in the dub.json obtained 
after the dub fetch.


Re: Storing a reference

2016-09-01 Thread Yuxuan Shui via Digitalmars-d-learn
On Thursday, 1 September 2016 at 20:28:03 UTC, Rene Zwanenburg 
wrote:
On Thursday, 1 September 2016 at 19:37:25 UTC, Yuxuan Shui 
wrote:

[...]


This will allocate a closure. A struct definition inside a 
function has a hidden context / closure pointer, unless it's a 
static struct.


There is nothing like a ref variable in D. If you want to refer 
to something someplace else, use a pointer. You can create a 
pointer wrapper which acts like a reference (untested):



auto toRef(ref T value)
{
  return Ref!T();
}

struct Ref(T)
{
  private T* value;
  @property ref T _value() { return *value; }
  alias _value this;
}

Note that D's pointer syntax is a bit friendlier than C++'s: 
the dot operator works fine on pointers. A good reason to use 
the Ref wrapper is to forward arithmetic operations to the 
wrapped value.


I think my approach is probably better, because I believe 
(correct me if I'm wrong): 1) it will never refer to a null 
object. 2) after DIP1000 is implemented we will be able to make 
sure there will be no dangling reference.


Re: Storing a reference

2016-09-01 Thread Rene Zwanenburg via Digitalmars-d-learn

On Thursday, 1 September 2016 at 19:37:25 UTC, Yuxuan Shui wrote:

I just figured out how to store a reference:

@safe:
auto x(ref int a) {
struct A {
ref int xa() { return a; }
}
return A();
}
void main() {
import std.stdio;
int b = 10;
auto a = x(b);
a.xa = 20;
writeln(b); //Prints 20
}

I have no idea if this is a right thing to do. Can someone tell 
me if this is idiomatic D, and whether there're any catches to 
this method or not?


Thanks.


This will allocate a closure. A struct definition inside a 
function has a hidden context / closure pointer, unless it's a 
static struct.


There is nothing like a ref variable in D. If you want to refer 
to something someplace else, use a pointer. You can create a 
pointer wrapper which acts like a reference (untested):



auto toRef(ref T value)
{
  return Ref!T();
}

struct Ref(T)
{
  private T* value;
  @property ref T _value() { return *value; }
  alias _value this;
}

Note that D's pointer syntax is a bit friendlier than C++'s: the 
dot operator works fine on pointers. A good reason to use the Ref 
wrapper is to forward arithmetic operations to the wrapped value.


Storing a reference

2016-09-01 Thread Yuxuan Shui via Digitalmars-d-learn

I just figured out how to store a reference:

@safe:
auto x(ref int a) {
struct A {
ref int xa() { return a; }
}
return A();
}
void main() {
import std.stdio;
int b = 10;
auto a = x(b);
a.xa = 20;
writeln(b); //Prints 20
}

I have no idea if this is a right thing to do. Can someone tell 
me if this is idiomatic D, and whether there're any catches to 
this method or not?


Thanks.


DUB, link automatically right object for platform and archi

2016-09-01 Thread Basile B. via Digitalmars-d-learn

I've converted this section:


"configurations" : [
{
  "name" : "nux32",
  "dflags" : [
"objects/coff32/beaengine.o"
  ]
},
{
  "name" : "nux64",
  "dflags" : [
"objects/coff64/beaengine.o"
  ]
},
{
  "name" : "win32",
  "dflags" : [
"objects\\omf32\\beaengine.obj"
  ]


to:


  "buildSettings" : {
"dflags-linux-x86" : ["objects/coff32/beaengine.o"],
"dflags-linux-x86_64" : ["objects/coff64/beaengine.o"],
"dflags-windows-x86" : ["objects\\omf32\\beaengine.obj"]
  },


Because previously the right config could not be selected when 
the package was used as dependency. But now the object is not 
linked in the static library produced by the project.


What's wrong in my description ?


Re: traits.d: error: forward reference of variable parentPrefix

2016-09-01 Thread Noob via Digitalmars-d-learn

nvm. Renaming the MyDigestWrapper import caused the error.


Re: Error when running vibe.d example application, not sure of the cause.

2016-09-01 Thread e-y-e via Digitalmars-d-learn

On Thursday, 1 September 2016 at 09:37:22 UTC, Kagamin wrote:

Probably LDC issue https://github.com/ldc-developers/ldc/issues


Thank you for your reply. I built LDC (version 1.1.0 beta 2) from 
source and ran dub using:


$ dub run --compiler="~/Downloads/ldc/bin/ldc2"

And everything works now, so it must have been. I looked through 
some of the issues and it surprises me that I was the only one 
having this problem, but it must have been fixed at some point.


Anyway, thanks for your time, I feel a bit silly now :)


Re: About spinlock implementation

2016-09-01 Thread Guillaume Piolat via Digitalmars-d-learn

On Thursday, 1 September 2016 at 10:38:07 UTC, qznc wrote:
On Thursday, 1 September 2016 at 10:30:12 UTC, Guillaume Piolat 
wrote:

On Thursday, 1 September 2016 at 07:46:04 UTC, qznc wrote:


I find the documentation on MemoryOrder lacking about the 
semantics of rel. :(


[0] https://dlang.org/library/core/atomic/memory_order.html


What helped me was to read std::memory_order documentation
http://en.cppreference.com/w/cpp/atomic/memory_order


Yes, but how do they map? Is D's rel = relaxed or release or 
acq_rel?


Also, reading C++ documentation should not be required of 
course. ;)


MemoryOrder.rel must be std::memory_order::release (70% 
confidence)
And std::memory_order::relaxed is MemoryOrder.raw of course (90% 
confidence).


traits.d: error: forward reference of variable parentPrefix

2016-09-01 Thread Noob via Digitalmars-d-learn

Hello all,

I'm trying to use a std.digest, namely MD5 and sHA,  as a 
template parameter like so:


auto x = new MyDigestWrapper!MD5;

The compiler (dmd2) then throws two error messages at me which 
puzzle me.


phobos/std/traits.d 554: Error: forward reference of variable 
parentPrefix, and
phobos/std/traits.d 727: Error: template instance 
std.traits.fqnSym!(const(MyDigestWrapper!(MD5))) error 
instantiating
...std/traits.d 462: inst. from here: 
fqn!Type(const(MyDigestWrapper!(MD5)), false, false, false, false)
mydigestwrapper.d-mixin-283 310: inst. from here: 
fullyQualifiedName!(const(MyDigestWrapper!(MD5)))

app.d 211: inst. from here MyDigestWrapper!(MD5)

1. What's going on ?
2. How is that fqnSym involved ?
3. What is parentPrefix ?
4. What is this forward ref, and why ?
5. How can I review mydigestwrapper.d-mixin-283 ?

Thanks for your time


Re: Different array rotation algorithms benchmark

2016-09-01 Thread Johan Engelen via Digitalmars-d-learn

On Thursday, 1 September 2016 at 10:37:18 UTC, Miguel L wrote:


Also, forgot to specify I am using LDC with -05.


And the version of LDC too please ;-)


Re: Overriding abstract class fields

2016-09-01 Thread slaid via Digitalmars-d-learn

On Thursday, 1 September 2016 at 11:34:28 UTC, Basile B. wrote:

On Thursday, 1 September 2016 at 11:09:18 UTC, slaid wrote:

I have a snippet:

How do I override this height field?

Thanks


The field height is not overridden. In C you have two "height". 
Since your array is of type A[], map takes A.height.


Only methods are virtual. To solve the problem you can create a 
virtual getter:


But since height is only a field you can just use the same 
variable and set the value in the constructor (for example)


Just what I needed, thanks a bunch!



Re: Overriding abstract class fields

2016-09-01 Thread Basile B. via Digitalmars-d-learn

On Thursday, 1 September 2016 at 11:09:18 UTC, slaid wrote:

I have a snippet:

How do I override this height field?

Thanks


The field height is not overridden. In C you have two "height". 
Since your array is of type A[], map takes A.height.


abstract class A
{
int height = 0;
}

class B : A {}

class C : A
{
int height = 1;
}

void main()
{
writeln((new C).height); // prints 0, the height of C
writeln((cast(A)(new C).height); // prints 1, the height of A
}

Only methods are virtual. To solve the problem you can create a 
virtual getter:


°°
abstract class A
{
int height();
}

class B : A
{
override int height(){return 0;}
}

class C : A
{
override int height(){return 1;}
}
°°

But since height is only a field you can just use the same 
variable and set the value in the constructor (for example)


°°
abstract class A
{
int height;
}

class B : A
{
this(){height = 0;}
}

class C : A
{
this(){height = 1;}
}
°°


Re: testing for deprecation

2016-09-01 Thread rikki cattermole via Digitalmars-d-learn

On 01/09/2016 11:11 PM, Cauterite wrote:

How does one test whether a symbol is deprecated? I would have expected
something like: __traits(isDeprecated, foo).

In the compiler we have Dsymbol.isDeprecated, is that not accessible in
any way from code?

The only solution I can think of is compiling with -de and using
__traits(compiles, {alias x = foo;})
which actually does seem to work. Pretty lousy though.


That is a first that somebody wanted it.
Bug report please!


testing for deprecation

2016-09-01 Thread Cauterite via Digitalmars-d-learn
How does one test whether a symbol is deprecated? I would have 
expected something like: __traits(isDeprecated, foo).


In the compiler we have Dsymbol.isDeprecated, is that not 
accessible in any way from code?


The only solution I can think of is compiling with -de and using 
__traits(compiles, {alias x = foo;})

which actually does seem to work. Pretty lousy though.


Overriding abstract class fields

2016-09-01 Thread slaid via Digitalmars-d-learn

I have a snippet:

  import std.stdio;
  import std.algorithm;

  abstract class A {
  int height = 0;
  }

  class B : A {
  }

  class C : A {
  int height = 1;
  }

  void main() {
  A[][int] list;
  list[0] = new A[](0);
  list[0] ~= new B();
  list[0] ~= new C();
  list[0] ~= new B();
  writeln(list[0].map!(x=>x.height));
  }

The output of this is [0, 0, 0] when if height was overridden it 
should print [0, 1, 0]. This is a trivial case for simplicity of 
the question, but in my actual code, I am trying to use the 
height field for sorting the A[] list (or reducing with max to 
get the object with the max height), but since they're all 0, 
none of the sorting occurs.


How do I override this height field?

Thanks


Re: About spinlock implementation

2016-09-01 Thread qznc via Digitalmars-d-learn
On Thursday, 1 September 2016 at 10:30:12 UTC, Guillaume Piolat 
wrote:

On Thursday, 1 September 2016 at 07:46:04 UTC, qznc wrote:


I find the documentation on MemoryOrder lacking about the 
semantics of rel. :(


[0] https://dlang.org/library/core/atomic/memory_order.html


What helped me was to read std::memory_order documentation
http://en.cppreference.com/w/cpp/atomic/memory_order


Yes, but how do they map? Is D's rel = relaxed or release or 
acq_rel?


Also, reading C++ documentation should not be required of course. 
;)


Re: Different array rotation algorithms benchmark

2016-09-01 Thread Miguel L via Digitalmars-d-learn

On Thursday, 1 September 2016 at 09:53:59 UTC, Miguel L wrote:

On Thursday, 1 September 2016 at 09:36:16 UTC, Miguel L wrote:

Hi

I recently needed a very optimized array rotation algorithm, 
so I did this benchmark, hope you find it interesting. I am a 
bit surprised by the poor results of 
std.algorithm.bringToFront:


[...]


Sorry Rotate4 had a bug, there was an extra for that was not 
neccesary, this is the correct implementation:


void Rotate4(T)(T[] input, long n) pure
{
/* 1,2,3,4,5,6,7,8 - 2 -
 * 7,2,3,4,5,6,1,8 - a=0 b=8-2=6
 * 7,8,3,4,5,6,1,2 - a=1 b=7
 * 7,8,1,4,5,6,3,2 - a=2 b=6
 * 7,8,1,2,5,6,3,4 - a=3 b=7
 * 7,8,1,2,3,6,5,4 - a=4 b=6
 * 7,8,1,2,3,4,5,6 - a=5 b=7

   1,2,3,4,5,6,7,8,9 - 3 -
 * 7,2,3,4,5,6,1,8,9 - a=0 b=9-3=6
 * 7,8,3,4,5,6,1,2,9 - a=1 b=7
 * 7,8,9,4,5,6,1,2,3 - a=2 b=8
 * 7,8,9,1,5,6,4,2,3 - a=3 b=6
 * 7,8,9,1,2,6,4,5,3 - a=4 b=7
 * 7,8,9,1,2,3,4,5,6 - a=5 b=8
 */
if(n<0)
n=input.length+n;

long a=0,b=input.length-n;
T tmp;

while(a=input.length)
{
b=input.length-n;
}
}

}


Very sorry again: Rotate4 was not correct with negative offsets.
This implementation works correctly:

void Rotar4(T)(T[] input, long n) pure
{
/* 1,2,3,4,5,6,7,8 - 2 -
 * 7,2,3,4,5,6,1,8 - a=0 b=8-2=6
 * 7,8,3,4,5,6,1,2 - a=1 b=7
 * 7,8,1,4,5,6,3,2 - a=2 b=6
 * 7,8,1,2,5,6,3,4 - a=3 b=7
 * 7,8,1,2,3,6,5,4 - a=4 b=6
 * 7,8,1,2,3,4,5,6 - a=5 b=7
 *

 * 1,2,3,4,5,6,7,8 - -2 -
 * 1,8,3,4,5,6,7,2 - a=7 b=1
 * 7,8,3,4,5,6,1,2 - a=6 b=0
 * 7,6,3,4,5,8,1,2 - a=5 b=1
 * 5,6,3,4,7,8,3,4 - a=4 b=0
 * 3,6,5,4,7,8,1,2 - a=3 b=1
 * 3,4,5,6,7,8,1,2 - a=2 b=0


   1,2,3,4,5,6,7,8,9 - 2 -
 * 7,2,3,4,5,6,1,8,9 - a=0 b=9-3=6
 * 7,8,3,4,5,6,1,2,9 - a=1 b=7
 * 7,8,9,4,5,6,1,2,3 - a=2 b=8
 * 7,8,9,1,5,6,4,2,3 - a=3 b=6
 * 7,8,9,1,2,6,4,5,3 - a=4 b=7
 * 7,8,9,1,2,3,4,5,6 - a=5 b=8
 */
long a,b;
T tmp;

if(n>0)
{
a=0;
b=input.length-n;   

while(a=input.length)
b=input.length-n;
}
}
else
{
a=input.length-1;
long b0=-n-1;
b=b0;   

while(a>=-n)
{
tmp=input[b];
input[b]=input[a];
input[a]=tmp;
--a;
--b;
if(b<0)
b=b0;
}
}   

}

Also, forgot to specify I am using LDC with -05.
Updated benchmark results:

Rotate0: 0.344186s
Rotate1: 1.76369s
Rotate2: 0.169968s
Rotate3: 0.354091s
Rotate4: 0.156231s


Re: About spinlock implementation

2016-09-01 Thread Guillaume Piolat via Digitalmars-d-learn

On Thursday, 1 September 2016 at 07:46:04 UTC, qznc wrote:


I find the documentation on MemoryOrder lacking about the 
semantics of rel. :(


[0] https://dlang.org/library/core/atomic/memory_order.html


What helped me was to read std::memory_order documentation
http://en.cppreference.com/w/cpp/atomic/memory_order


Re: Different array rotation algorithms benchmark

2016-09-01 Thread Miguel L via Digitalmars-d-learn

On Thursday, 1 September 2016 at 09:36:16 UTC, Miguel L wrote:

Hi

I recently needed a very optimized array rotation algorithm, so 
I did this benchmark, hope you find it interesting. I am a bit 
surprised by the poor results of std.algorithm.bringToFront:


[...]


Sorry Rotate4 had a bug, there was an extra for that was not 
neccesary, this is the correct implementation:


void Rotate4(T)(T[] input, long n) pure
{
/* 1,2,3,4,5,6,7,8 - 2 -
 * 7,2,3,4,5,6,1,8 - a=0 b=8-2=6
 * 7,8,3,4,5,6,1,2 - a=1 b=7
 * 7,8,1,4,5,6,3,2 - a=2 b=6
 * 7,8,1,2,5,6,3,4 - a=3 b=7
 * 7,8,1,2,3,6,5,4 - a=4 b=6
 * 7,8,1,2,3,4,5,6 - a=5 b=7

   1,2,3,4,5,6,7,8,9 - 3 -
 * 7,2,3,4,5,6,1,8,9 - a=0 b=9-3=6
 * 7,8,3,4,5,6,1,2,9 - a=1 b=7
 * 7,8,9,4,5,6,1,2,3 - a=2 b=8
 * 7,8,9,1,5,6,4,2,3 - a=3 b=6
 * 7,8,9,1,2,6,4,5,3 - a=4 b=7
 * 7,8,9,1,2,3,4,5,6 - a=5 b=8
 */
if(n<0)
n=input.length+n;

long a=0,b=input.length-n;
T tmp;

while(a=input.length)
{
b=input.length-n;
}
}

}


Re: Error when running vibe.d example application, not sure of the cause.

2016-09-01 Thread Kagamin via Digitalmars-d-learn

Probably LDC issue https://github.com/ldc-developers/ldc/issues


Different array rotation algorithms benchmark

2016-09-01 Thread Miguel L via Digitalmars-d-learn

Hi

I recently needed a very optimized array rotation algorithm, so I 
did this benchmark, hope you find it interesting. I am a bit 
surprised by the poor results of std.algorithm.bringToFront:


These are the different algorithms:


void Rotate0(T)(T[] input, int n) pure
{
if(n>0)input=input[($-n)..$]~input[0..($-n)];
if(n<0)input=input[(-n)..$]~input[0..(-n)];
}

void Rotate(T)(T[] input, int n) pure
{
	if(n>0) 
std.algorithm.bringToFront(input[0..($-n)],input[($-n)..$]);
	else if(n<0) 
std.algorithm.bringToFront(input[0..(-n)],input[(-n)..$]);

}

 void reverse(T)(T[] a, long sz) pure {
long i, j;
for (i = 0, j = sz; i < j; ++i, --j) {
T tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}

void Rotate2(T)(T[] array, long amt) pure  {
/*
the algorithm from Jon Bentley's book, "Programming Pearls 2nd 
Edition"

O(n) time and no extra memory usage (since array was specified),
*/
if (amt < 0)
amt = array.length + amt;
reverse(array, array.length-amt-1);
reverse(array[array.length-amt..$], amt-1);
reverse(array, array.length-1);
}


void Rotate3(T)(T[] input, long n) pure
{
if(n<0)
n=input.length+n;

auto tmp=input[($-n)..$].dup;
for(auto j=input.length-1;j>=n;--j)
input[j]=input[j-n];
input[0..n]=tmp;
}



void Rotate4(T)(T[] input, long n) pure
//No extra memory, just swapping of elements
{
/* 1,2,3,4,5,6,7,8 - 2 -
 * 7,2,3,4,5,6,1,8 - a=0 b=8-2=6
 * 7,8,3,4,5,6,1,2 - a=1 b=7
 * 7,8,1,4,5,6,3,2 - a=2 b=6
 * 7,8,1,2,5,6,3,4 - a=3 b=7
 * 7,8,1,2,3,6,5,4 - a=4 b=6
 * 7,8,1,2,3,4,5,6 - a=5 b=7

   1,2,3,4,5,6,7,8,9 - 2 -
 * 7,2,3,4,5,6,1,8,9 - a=0 b=9-3=6
 * 7,8,3,4,5,6,1,2,9 - a=1 b=7
 * 7,8,9,4,5,6,1,2,3 - a=2 b=8
 * 7,8,9,1,5,6,4,2,3 - a=3 b=6
 * 7,8,9,1,2,6,4,5,3 - a=4 b=7
 * 7,8,9,1,2,3,4,5,6 - a=5 b=8
 */

if(n<0)
n=input.length+n;

long a=0,b=input.length-n;
T tmp;

while(a=input.length)
{
b=input.length-n;
}
}

}

This is the times I got for 400 iterations of each  rotating 
an array of 29 elements 2 positions(200 iterations to the 
left, and 200 iterations to the right).


Rotate0: 0.300493s
Rotate1: 1.60528s
Rotate2: 0.145162s
Rotate3: 0.337595s
Rotate4: 0.0853269s



This is the test/benchmark function code, sorry for the long 
asserts.


void RotateBenchmark()
{
	int[] 
a=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30];


Rotate0(a,2);

assert(a==[29,30,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]);
Rotate0(a,-2);

assert(a==[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]);

Rotate1(a,2);

assert(a==[29,30,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]);
Rotate1(a,-2);

assert(a==[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]);

Rotate2(a,2);

assert(a==[29,30,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]);
Rotate2(a,-2);

assert(a==[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]);

Rotate3(a,2);

assert(a==[29,30,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]);
Rotate3(a,-2);

assert(a==[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]);

Rotate4(a,2);

assert(a==[29,30,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]);
Rotate4(a,-2);

assert(a==[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]);

auto init1 = TickDuration.currSystemTick();
for(auto i=0;i<200;++i)
Rotate0(a,2);
for(auto i=0;i<200;++i)
Rotate0(a,-2);

assert(a==[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]);
	writeln("Rotate0: ",(TickDuration.currSystemTick() - 
init1).to!("seconds",float),"s");


init1 = TickDuration.currSystemTick();
for(auto i=0;i<200;++i)
Rotate1(a,2);
for(auto i=0;i<200;++i)
Rotate1(a,-2);

assert(a==[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]);
	writeln("Rotate1: ",(TickDuration.currSystemTick() - 
init1).to!("seconds",float),"s");


init1 = 

Re: About spinlock implementation

2016-09-01 Thread mogu via Digitalmars-d-learn

On Thursday, 1 September 2016 at 07:46:04 UTC, qznc wrote:


This effectively makes the access to the protected value 
unprotected and nullifies the effect of the spinlock.




So the cas operation implicit an MemoryOrder.acq? Does it make 
any other MemoryOrder guarantee?


Re: About spinlock implementation

2016-09-01 Thread mogu via Digitalmars-d-learn

On Thursday, 1 September 2016 at 07:46:04 UTC, qznc wrote:


I'm not sure I understand rel [0], but raw is too weak. Raw 
means no sequencing barrier, so


  local_var = protected_value;
  spinlock.unlock();

could be transformed (by compiler or CPU) to

  spinlock.unlock();
  local_var = protected_value;

This effectively makes the access to the protected value 
unprotected and nullifies the effect of the spinlock.


I find the documentation on MemoryOrder lacking about the 
semantics of rel. :(


[0] https://dlang.org/library/core/atomic/memory_order.html


Thanks very much. I finally got it. :)


Re: About spinlock implementation

2016-09-01 Thread qznc via Digitalmars-d-learn

On Thursday, 1 September 2016 at 06:44:13 UTC, mogu wrote:

I found an implementation of spinlock in concurrency.d.
```
static shared struct SpinLock
{
void lock() { while (!cas(, false, true)) { 
Thread.yield(); } }
void unlock() { atomicStore!(MemoryOrder.rel)(locked, 
false); }

bool locked;
}
```
Why atomicStore use MemoryOrder.rel instead of MemoryOrder.raw?


I'm not sure I understand rel [0], but raw is too weak. Raw means 
no sequencing barrier, so


  local_var = protected_value;
  spinlock.unlock();

could be transformed (by compiler or CPU) to

  spinlock.unlock();
  local_var = protected_value;

This effectively makes the access to the protected value 
unprotected and nullifies the effect of the spinlock.


I find the documentation on MemoryOrder lacking about the 
semantics of rel. :(


[0] https://dlang.org/library/core/atomic/memory_order.html


About spinlock implementation

2016-09-01 Thread mogu via Digitalmars-d-learn

I found an implementation of spinlock in concurrency.d.
```
static shared struct SpinLock
{
void lock() { while (!cas(, false, true)) { 
Thread.yield(); } }
void unlock() { atomicStore!(MemoryOrder.rel)(locked, false); 
}

bool locked;
}
```
Why atomicStore use MemoryOrder.rel instead of MemoryOrder.raw?