Re: Are there any methods like isDestroyed or isDisposed to detect whether some object is destroyed or not?
On Sat, 13 Dec 2014 07:03:22 + Andrey Derzhavin via Digitalmars-d-learn wrote: p.p.s. please-please-please don't invent other hacks with `rt_attachDisposeEvent()`! such hackery will not do you good in the long term. signature.asc Description: PGP signature
Re: Are there any methods like isDestroyed or isDisposed to detect whether some object is destroyed or not?
On Sat, 13 Dec 2014 07:03:22 + Andrey Derzhavin via Digitalmars-d-learn wrote: p.s. you can emulate "weak links" if this is what you want to have. i.e. references to object that will not stop GC to collect that object and which will be auto-nullified if the object was collected. see this module, for example: http://repo.or.cz/w/iv.d.git/blob/HEAD:/weakref.d signature.asc Description: PGP signature
Re: Are there any methods like isDestroyed or isDisposed to detect whether some object is destroyed or not?
On Sat, 13 Dec 2014 07:03:22 + Andrey Derzhavin via Digitalmars-d-learn wrote: > Hello! > > We have object, for example, objA. > > ObjectAType objA = new ObjectAType(...); > > // we have a many references to objA > > void someFunction1(...) > { > // destroying the objA > destroy(one_of_the_refToObjA); > > // > } > > > void someFunction2() > { > // "segmentation fault" if the objA is destroyed > another_refToObjA.method1(); > > // I need a safe way (without using signals) to detect whether > object > // destroyed or not, like this > // if (!isDestroyed(another_refToObjA)) > // another_refToObjA.method1(); > > } > > // call functions > someFunction1(..); > > // . some other operations... > > // the objectA (objA) is destroyed, but debugger shows us a not > null reference > // to that objA. However, when we try to call some methods of > objectA or > // try to use it's variables we get a "segmentation fault" error > (in > // someFunction2, when objA is destroyed). > someFunction2(...); > > Thanks. first. you'd better to not write such code, it's completely unreliable. second. you can check if the block is allocated by using GC.addrOf(). third. and this is completely unreliable, 'cause memory can be reused. so the only right answer is: "don't do that!" use list of free objects, for example, and write `free()` function that will move the object to that list (and possibly set some flags to mark it as "freed"). let me stress it again: you *CAN'T* reliably detect if some object was manually destroyed. don't even think you can do this in working code, you will never made such code fully working. signature.asc Description: PGP signature
Are there any methods like isDestroyed or isDisposed to detect whether some object is destroyed or not?
Hello! We have object, for example, objA. ObjectAType objA = new ObjectAType(...); // we have a many references to objA void someFunction1(...) { // destroying the objA destroy(one_of_the_refToObjA); // } void someFunction2() { // "segmentation fault" if the objA is destroyed another_refToObjA.method1(); // I need a safe way (without using signals) to detect whether object // destroyed or not, like this // if (!isDestroyed(another_refToObjA)) // another_refToObjA.method1(); } // call functions someFunction1(..); // . some other operations... // the objectA (objA) is destroyed, but debugger shows us a not null reference // to that objA. However, when we try to call some methods of objectA or // try to use it's variables we get a "segmentation fault" error (in // someFunction2, when objA is destroyed). someFunction2(...); Thanks.
Re: std.array oddness
On Sat, 13 Dec 2014 05:15:08 + earthfront via Digitalmars-d-learn wrote: > Am I using array incorrectly? no, you are using `.byLine` incorrectly. ;-) `.byLine` reuses it's internal buffer for each line, so you have to copy that buffer. like this: import std.array, std.stdio; void main () { // Converting to "array" borks the thing import std.algorithm : map; auto names = File("names.txt") .byLine!(char,char)(KeepTerminator.no, ',') .map!"a.idup" .array; foreach (name; names) writeln(name); } signature.asc Description: PGP signature
std.array oddness
Hello! I was attempting project euler problem 22 and seeing something weird going on with the array function in std.array. I made the following code to demonstrate. Given names.txt: -- "MARY","PATRICIA","LINDA","BARBARA","ELIZABETH" -- and code: -- import std.array,std.stdio; void main() { { // Correct auto names = File("names.txt","r") .byLine!(char,char)(KeepTerminator.no,','); foreach(char[] name; names ){ writeln( name ); } } { // Converting to "array" borks the thing auto names = File("names.txt","r") .byLine!(char,char)(KeepTerminator.no,',') .array; foreach( char[] name; names){ writeln( name ); } } } -- I get the following output: -- ➜ euler rdmd ./stdArrayBug.d "MARY" "PATRICIA" "LINDA" "BARBARA" "ELIZABETH" "ELIZA "ELIZABETH "ELIZAB "ELIZABET "ELIZABETH" -- Am I using array incorrectly? I searched bugzilla and didn't see anything pertaining to this issue. Should I file a bug? DMD64 D Compiler v2.066.1 Ubuntu Linux Thanks!
The package feature is ignored when the file name is package.di
Is this on purpose? Granted, I almost never use interface files, but I had a whim to use them for what I was working on today. Everything worked fine when I renamed the file to package.d, but apparently package.di is not acceptible.
Re: std.bitmanip - bitshift?
Here's my implementation of <<= and >>= for BitArray: https://github.com/D-Programming-Language/phobos/pull/2797 While working with the code, I found that there are a lot of areas that need improvement. If I have some time I'll file separate PR's for them. T -- VI = Visual Irritation
Re: std.bitmanip - bitshift?
On 12/12/14 2:17 PM, H. S. Teoh via Digitalmars-d-learn wrote: On Fri, Dec 12, 2014 at 11:13:38AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: On 12/12/14 8:39 AM, Trollgeir wrote: http://dlang.org/phobos/std_bitmanip.html Does anyone know how to bit-shift a BitArray? I'm trying to make spikes in a neural network travel along the bits as they have various lengths. That is a surprising omission from a bit-oriented type... You also cannot opSlice a BitArray. Nice for enhancement requests, if you want to add them to the issue tracker. [...] I've started working on an implementation of this... but it's not very clear what the correct semantics should be. For example, if my starting BitArray b is 1101, say, what should be the result after b>>=1? Should it be 0110, 110, or 01101? 0110 In other words, I would assume the same semantics as an unsigned int. In other other words, it's like each bit moves one to the right, and the bit that has no source gets a 0. It may be useful to add some other functions, such as roll, which would move bits that fall off the end back onto the top. And maybe expose shift as a function, which allows you to specify the bit value (or maybe range of bits) that should be shifted in from the other side. Note, I would not allow just opBinary, only opBinaryAssign. No reason to construct temporary BitArrays. -Steve
Re: std.bitmanip - bitshift?
On Fri, Dec 12, 2014 at 11:13:38AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: > On 12/12/14 8:39 AM, Trollgeir wrote: > >http://dlang.org/phobos/std_bitmanip.html > > > >Does anyone know how to bit-shift a BitArray? > > > >I'm trying to make spikes in a neural network travel along the > >bits as they have various lengths. > > That is a surprising omission from a bit-oriented type... > > You also cannot opSlice a BitArray. Nice for enhancement requests, if > you want to add them to the issue tracker. [...] I've started working on an implementation of this... but it's not very clear what the correct semantics should be. For example, if my starting BitArray b is 1101, say, what should be the result after b>>=1? Should it be 0110, 110, or 01101? T -- It is widely believed that reinventing the wheel is a waste of time; but I disagree: without wheel reinventers, we would be still be stuck with wooden horse-cart wheels.
Re: Garbage collector collects live objects
On Friday, 12 December 2014 at 15:50:26 UTC, Steven Schveighoffer wrote: Can I email you at this address? If not, email me at the address from my post to let me know your contact, no reason to work through building issues on the public forum :) -Steve reach me at theambient [] me__com
Re: Allocating aligned memory blocks?
On 12/12/14 2:02 AM, safety0ff wrote: On Friday, 12 December 2014 at 06:17:56 UTC, H. S. Teoh via Digitalmars-d-learn wrote: Is there a way to allocate GC memory blocks in D that are guaranteed to fall on OS page boundaries? I don't know about guarantees, I think that in practice, if your OS page size is 4096, any GC allocation of 4096 or greater will be page aligned. Yes, it's how that will work, and I think it's de-facto guaranteed. Actually technically, you can allocate a block of 2049 or bigger, and it will allocate a page for it. -Steve
Re: std.bitmanip - bitshift?
On 12/12/14 8:39 AM, Trollgeir wrote: http://dlang.org/phobos/std_bitmanip.html Does anyone know how to bit-shift a BitArray? I'm trying to make spikes in a neural network travel along the bits as they have various lengths. That is a surprising omission from a bit-oriented type... You also cannot opSlice a BitArray. Nice for enhancement requests, if you want to add them to the issue tracker. -Steve
Re: Garbage collector collects live objects
On 12/12/14 7:52 AM, Ruslan Mullakhmetov wrote: On Thursday, 11 December 2014 at 18:36:59 UTC, Steven Schveighoffer wrote: My analysis so far: 2. In the array append code, the block attributes are obtained via GC.query, which has this code for getting the attributes: https://github.com/D-Programming-Language/druntime/blob/master/src/gc/gc.d#L1792 Quoting from that function: // reset the offset to the base pointer, otherwise the bits // are the bits for the pointer, which may be garbage offset = cast(size_t)(info.base - pool.baseAddr); info.attr = getBits(pool, cast(size_t)(offset >> pool.shiftBy)); Which should get the correct bits. I suspected there was an issue with getting the wrong bits, but this code looks correct. 3. The runtime caches the block info for thread local data for append speed. A potential issue is that the attributes are cached from a previous use for that block, but the GC (and the runtime itself) SHOULD clear that cache entry when that block is freed, avoiding this issue. A potential way to check this is to assert in a debug build of druntime that the cached block info always equals the actual block info. Are you able to build a debug version of druntime to test this? I can give you the changes you should make. This would explain the great difficulty in reproducing the issue. I will try to build debug version of dmd compiler and check the issue. A debug version of compiler is not necessary, not even a debug version of phobos, just druntime. But it's not going to matter yet, because I need to give you the asserts to put in there. I just wanted to know if you needed help doing it. 4. If your code is multi-threaded, but using __gshared, it can make the cache incorrect. Are you doing this? the app is multi-threaded via std.concurrency. This should be OK, you should not be able to share data that is not marked as shared. there is only one known to me place where __gshared is used: logging library (checked by searching through whole source tree). make stub for this lib and try, so identify whether cache invalidated by _gshared or not. Here is where it might occur: 1. Due to shared data having typeinfo attached to it that it is actually shared, the runtime takes advantage of that. We can use a lock-free cache that is thread-local for anything not marked as shared, because nothing outside the thread can access that data. 2. __gshared gets around this because it is not marked as shared by the compiler. This means, if you, for instance, appended to a __gshared array, the runtime would treat it like a thread-local array. If you did this from multiple threads, the cache may be invalid in one or more of them. 3. Actual 'shared' arrays are not permitted to use the cache, so they should not have this issue. I see that you removed the only instance of __gshared and it did not help. That at least rules that out. But the cache is really the only possible place I can see where the bits are set incorrectly, given that you just verified the bits are correct before the append. Can you just list the version of the compiler you are using? I want to make sure this isn't an issue that has already been fixed. the last. first of all i updated whole toolchain (dmd, dub). $ dmd DMD64 D Compiler v2.066.1 Thanks, this at least gives me a baseline to know what to test and debug with. I do not believe the code has had any significant fixes that would help with this issue since then. I started looking druntime and dmd source code myself before i checked the thread (thsnks for your help and feedback) and i have some questions. could you explain to me something? i_m looking here https://github.com/D-Programming-Language/druntime/blob/v2.066.1/src/rt/lifetime.d#L591 --- line #603 auto size = ti.next.tsize; why `next`? it can be even null if this is last TypeInfo in the linked list. This is the way the compiler constructs the type info. The first TypeInfo is always TypeInfo_Array (or TypeInfo_Shared, or const or whatever), and the .next is the typeinfo for the element type. all this does is get the size of an element. Since we know we are dealing with an array, we know next is always valid. btw, i used suggested trackallocs.d and GC defenetely receives NO_SCAN before tag: 1 len: 2 ptr: 103A78058 root: 103A77000:8192 attr: APPENDABLE gc_qalloc(41, NO_SCAN APPENDABLE ) cc: 29106 asz: 10152603, ti: null ret: BlkInfo_(104423800, 64, 10) after tag: 1 len: 3 ptr: 104423810 root: 104423800:64 attr: NO_SCAN APPENDABLE This is good information, thanks. I will get back to you with a druntime branch to try. Can I email you at this address? If not, email me at the address from my post to let me know your contact, no reason to work through building issues on the public forum :) -Steve
Re: Global array
On Fri, Dec 12, 2014 at 03:04:21PM +, Paul via Digitalmars-d-learn wrote: > On Thursday, 11 December 2014 at 21:35:43 UTC, H. S. Teoh via > Digitalmars-d-learn wrote: > >On Thu, Dec 11, 2014 at 08:56:00PM +, Paul via Digitalmars-d-learn > >wrote: > >>Is there any merit (or folly!) in storing a large array, that > >>frequently needs to be accessed globally, within a class like so: > >> > >>public class classMap{ > >> > >>public static int[MAPSIZE][MAPSIZE] map; > >> > >>} > >> > >>Or is there a proper 'D' way to do this? > >[...] > > > >Why do you need to wrap it inside a class? Why not just put it in > >module-global scope, since it's public anyway? > > > > > >T > > I guess I'm looking for the correct method to create a globally > accessible bunch of data (basically the program state) with associated > functions while trying to provide some measure of safety compared to > ordinary global variables. I suppose putting them in the same module > with that array in the global namespace is no different. Yeah, putting them in module scope is no different. Except that in D, this is still not as global as C: the symbol is still restricted to the module it's defined in, so you won't be able to refer to it unless you import the module, and also D "globals" are actually thread-local, so each thread will get a separate copy of it. This makes it less prone to nasty issues like race conditions where one thread is in the middle of writing to it while another thread is reading it. T -- Tell me and I forget. Teach me and I remember. Involve me and I understand. -- Benjamin Franklin
Re: Global array
On Thursday, 11 December 2014 at 21:35:43 UTC, H. S. Teoh via Digitalmars-d-learn wrote: On Thu, Dec 11, 2014 at 08:56:00PM +, Paul via Digitalmars-d-learn wrote: Is there any merit (or folly!) in storing a large array, that frequently needs to be accessed globally, within a class like so: public class classMap{ public static int[MAPSIZE][MAPSIZE] map; } Or is there a proper 'D' way to do this? [...] Why do you need to wrap it inside a class? Why not just put it in module-global scope, since it's public anyway? T I guess I'm looking for the correct method to create a globally accessible bunch of data (basically the program state) with associated functions while trying to provide some measure of safety compared to ordinary global variables. I suppose putting them in the same module with that array in the global namespace is no different.
std.bitmanip - bitshift?
http://dlang.org/phobos/std_bitmanip.html Does anyone know how to bit-shift a BitArray? I'm trying to make spikes in a neural network travel along the bits as they have various lengths.
Re: Garbage collector collects live objects
On Friday, 12 December 2014 at 12:53:00 UTC, Ruslan Mullakhmetov wrote: On Thursday, 11 December 2014 at 18:36:59 UTC, Steven Schveighoffer wrote: My analysis so far: 4. If your code is multi-threaded, but using __gshared, it can make the cache incorrect. Are you doing this? the app is multi-threaded via std.concurrency. there is only one known to me place where __gshared is used: logging library (checked by searching through whole source tree). make stub for this lib and try, so identify whether cache invalidated by _gshared or not. removing __gshared seems does not helped.
Re: Garbage collector collects live objects
On Thursday, 11 December 2014 at 18:36:59 UTC, Steven Schveighoffer wrote: My analysis so far: 2. In the array append code, the block attributes are obtained via GC.query, which has this code for getting the attributes: https://github.com/D-Programming-Language/druntime/blob/master/src/gc/gc.d#L1792 Quoting from that function: // reset the offset to the base pointer, otherwise the bits // are the bits for the pointer, which may be garbage offset = cast(size_t)(info.base - pool.baseAddr); info.attr = getBits(pool, cast(size_t)(offset >> pool.shiftBy)); Which should get the correct bits. I suspected there was an issue with getting the wrong bits, but this code looks correct. 3. The runtime caches the block info for thread local data for append speed. A potential issue is that the attributes are cached from a previous use for that block, but the GC (and the runtime itself) SHOULD clear that cache entry when that block is freed, avoiding this issue. A potential way to check this is to assert in a debug build of druntime that the cached block info always equals the actual block info. Are you able to build a debug version of druntime to test this? I can give you the changes you should make. This would explain the great difficulty in reproducing the issue. I will try to build debug version of dmd compiler and check the issue. 4. If your code is multi-threaded, but using __gshared, it can make the cache incorrect. Are you doing this? the app is multi-threaded via std.concurrency. there is only one known to me place where __gshared is used: logging library (checked by searching through whole source tree). make stub for this lib and try, so identify whether cache invalidated by _gshared or not. But the cache is really the only possible place I can see where the bits are set incorrectly, given that you just verified the bits are correct before the append. Can you just list the version of the compiler you are using? I want to make sure this isn't an issue that has already been fixed. the last. first of all i updated whole toolchain (dmd, dub). $ dmd DMD64 D Compiler v2.066.1 -Steve I started looking druntime and dmd source code myself before i checked the thread (thsnks for your help and feedback) and i have some questions. could you explain to me something? i_m looking here https://github.com/D-Programming-Language/druntime/blob/v2.066.1/src/rt/lifetime.d#L591 --- line #603 auto size = ti.next.tsize; why `next`? it can be even null if this is last TypeInfo in the linked list. - btw, i used suggested trackallocs.d and GC defenetely receives NO_SCAN before tag: 1 len: 2 ptr: 103A78058 root: 103A77000:8192 attr: APPENDABLE gc_qalloc(41, NO_SCAN APPENDABLE ) cc: 29106 asz: 10152603, ti: null ret: BlkInfo_(104423800, 64, 10) after tag: 1 len: 3 ptr: 104423810 root: 104423800:64 attr: NO_SCAN APPENDABLE