Dconf 2015 talks...

Era Scarecrow via Digitalmars-d digitalmars-d at puremagic.com
Mon Jan 25 14:06:31 PST 2016


On Monday, 25 January 2016 at 21:22:13 UTC, Joseph Rushton 
Wakeling wrote:
> On Monday, 25 January 2016 at 20:26:12 UTC, Era Scarecrow wrote:
>>  What about an alternative allocator? Specifically I'm 
>> thinking in C's equivalent which is alloca (allocates directly 
>> on the stack with the rest of the variables). If the 
>> constructor is a function then that won't work; but if it's 
>> inlined then it should work.
>
> I have been wondering about how allocators could help to deal 
> with these problems.  Could you put forward a minimal example 
> of how you would see it working?

  Most likely alloca would have to be built into the compiler. 
Here's a crash course in how the stack memory management works. 
sp=stack pointer, bp=base pointer (more relevant pre 386).

  When you prepare to enter a function (or block) the bp register 
is backed up, the sp is saved in the bp register, then you add 
your arguments, then the function is entered. After the function 
is entered it adds to the sp register which give it a block of 
space for all known local variables at once; then does any 
assignments it needs to. When you leave the function/block you 
simply replace the sp register with your backup the bp register. 
Once you return you restore the old bp register.

  So something close to this:
[code]
   ...
   push bp
   push calling_argument(s)
   call func
   sub sp, -N //size of total arguments pushed
   pop bp //completely done with function call.
   ...


   func: mov bp, sp
   add sp, +N //size of local variables
   // setup variables
   // code

   // cleanup/return
   mov sp, bp
   ret
[/code]

  Technically alloca simply returns the current sp, then adds to 
it the number of bytes you requested. This means you have to run 
it at the function stack where you want to use it (and not in a 
called function, otherwise corruption). So inlined functions 
where alloca's data would remain would be a must. Then it comes 
down to a simple:

[code]
struct RNG {
   int *state; //add assert to functions that this isn't null
   this(int seed) {
     state = alloca(sizeof(int));
     *state = seed;
   }
}
[/code]

>>  I suppose the alternate is an option to skip/throw-away some 
>> numbers that should've been consumed (assuming you want to 
>> keep using the same seed), or seeding each per use.
>
> I'm not sure I follow what you mean here or why you think this 
> would work?  Could you give a concrete example?

certainly.

[code]
struct RNG {
   ...

   void skip(int x) {assert(x>0); while(x--) popfront();}
}

RNG rnd = RND(seed);
rnd.take(10).writeln;  //loosely based on talk examples
rnd.skip(10);          //skips the 'consumed' numbers.
rnd.take(10).writeln;  //won't have identical output

[/code]



More information about the Digitalmars-d mailing list