Re: Tracing/Profiling D Applications
On Wednesday, 25 May 2022 at 21:35:07 UTC, Christian Köstlin wrote: Is there also a way to get the "real" threadid? I'm using that functions inside threads: core.sys.windows.winbase.GetCurrentThreadId on Windows core.sys.posix.pthread.pthread_self on Unix (implied pthreads are used)
Re: Tracing/Profiling D Applications
On 5/25/22 14:35, Christian Köstlin wrote: > 1. I went for a singleton for storing tracing/logging information that > needs to be initialized manually. Is __gshared the right way to do that? I think this is where thread-local storage comes in handy. As the D runtime does for dmd's -profile command line switch, you can have a module-level Appender, which collects data for that thread without worrying about race conditions. > to unlock the mutex? You need the mutex only when each thread is exiting to combine their results. Each static ~this() could grab the mutex and add its result to the one global Appender. And that "global" Appender would be 'shared' or __gshared; doesn't matter. Ali
Tracing/Profiling D Applications
I experimented with application level tracing/profiling of d applications similar to what is described in https://dlang.org/blog/2020/03/13/tracing-d-applications/ as the "writef-based approach". Only difference is, that I am emitting json (https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit#heading=h.lpfof2aylapb) that is compatible with https://ui.perfetto.dev/ which gives nice interactive insights of the data. The code is available at https://github.com/gizmomogwai/profiled and can be used as dub package by registering it locally with dub add-local. The github repository also contains one screenshot produced with a patched unit-threaded library to emit the tracing information on a small project of mine. I do have a few question on how to do things in dlang though: 1. I went for a singleton for storing tracing/logging information that needs to be initialized manually. Is __gshared the right way to do that? 2. The data is stored in a std.array.appender protected by a mutex and only later printed as json. Any way to do this more elegantly than with the scope(exit) constructs to unlock the mutex? 3. For the tracing/profiling events I went with subclasses of an abstract event class (I only implemented one kind of event, whereas the tracing json format supports a lot more scenarios). When one is interested in when something happens and how long it takes, one can call `public Unique!CompleteEventProcess start(string name)` on the profiler which an uniquepointer that is then automatically deleted if it goes out of scope (and then takes the time). Is this a reasonable way todo it? E.g. it would be an error if the unique ptr is passed to another thread, because the CompleteEvents of the tracing format expect to be starting and stopping on the same thread. 4. Would something like that be interesting for others as a dub package (ATM its so small, that having it as an external dependency is not worth it IMHO)? 5. The complete event normally expects the real process and thread id as used by the os. Looks like https://dlang.org/phobos/std_process.html#.Pid.processID delivers the process id. Is there also a way to get the "real" threadid? Thanks in advance, Christian
Re: Cannot check function address
On Wednesday, 25 May 2022 at 14:09:31 UTC, Steven Schveighoffer wrote: Yes, he acknowledged that too much was stripped. I also verified similar code works. But the real problem was something else. He is saying in this message "why doesn't the compiler recognize that in comparing a function to null, I really wanted to compare a function *pointer* to null", but I don't see how the compiler can make that leap. Often times, I wish the compiler could just read what I was thinking when I wrote the code, so it could give me thought-contextual errors but alas, it can't. -Steve The real problem was that I was locking my mind that the `fun` symbol was unique. In fact it was not. There was another code version where the `fun` symbol was declared as exported function and some import did read that code. My code was not affected from this bug since the call syntax for function and function pointer was the same. And I honestly never noticed that the compiler may says 'function' or 'function pointer'. It was always the same to me. I should have test it with `__traits(getLocation)` before.
Re: Cannot check function address
On 5/25/22 6:55 AM, user1234 wrote: On Wednesday, 25 May 2022 at 06:04:10 UTC, frame wrote: On Wednesday, 25 May 2022 at 05:56:28 UTC, Steven Schveighoffer wrote: It's a case where the compiler can't divine what you were thinking when you wrote that code ;) I see not in all cases but in mine. If the compiler sees the function isn't callable without arguments and it is inside an if-statement or `assert()` then it could at least suggest a pointer or ask: are you dumb? ;-) As suggested by others, the reduction is not correct, you have stripped too muchbecause this compiles just fine: Yes, he acknowledged that too much was stripped. I also verified similar code works. But the real problem was something else. He is saying in this message "why doesn't the compiler recognize that in comparing a function to null, I really wanted to compare a function *pointer* to null", but I don't see how the compiler can make that leap. Often times, I wish the compiler could just read what I was thinking when I wrote the code, so it could give me thought-contextual errors but alas, it can't. -Steve
Re: Why (v1<<8 + v2) different from (v1<<8 | v2)?
Thanks:) **writeln( (v1<<8) + v2 );** is ok On Wednesday, 25 May 2022 at 12:51:07 UTC, Paul Backus wrote: On Wednesday, 25 May 2022 at 12:42:04 UTC, step8 wrote: I run following test code: int v1 = 22; int v2 = 23; writeln( v1<<8 + v2 ); writeln( v1<<8 | v2 ); result is 0 and 5655 Why ( v1<<8 + v2 ) = 0 ? `+` has a higher precedence than `<<`, so the first line is actually `v1 << (8 + v2)`. (
Re: Why (v1<<8 + v2) different from (v1<<8 | v2)?
On Wednesday, 25 May 2022 at 12:42:04 UTC, step8 wrote: I run following test code: int v1 = 22; int v2 = 23; writeln( v1<<8 + v2 ); writeln( v1<<8 | v2 ); result is 0 and 5655 Why ( v1<<8 + v2 ) = 0 ? `+` has a higher precedence than `<<`, so the first line is actually `v1 << (8 + v2)`.
Why (v1<<8 + v2) different from (v1<<8 | v2)?
I run following test code: int v1 = 22; int v2 = 23; writeln( v1<<8 + v2 ); writeln( v1<<8 | v2 ); result is 0 and 5655 Why ( v1<<8 + v2 ) = 0 ?
Re: Cannot check function address
On Wednesday, 25 May 2022 at 06:04:10 UTC, frame wrote: On Wednesday, 25 May 2022 at 05:56:28 UTC, Steven Schveighoffer wrote: It's a case where the compiler can't divine what you were thinking when you wrote that code ;) I see not in all cases but in mine. If the compiler sees the function isn't callable without arguments and it is inside an if-statement or `assert()` then it could at least suggest a pointer or ask: are you dumb? ;-) As suggested by others, the reduction is not correct, you have stripped too muchbecause this compiles just fine: a.d: ```d alias F = void function(int); F f; static this() { assert(!f); assert(f is null); } ``` b.d: ```d import a; static this() { assert(!f); assert(f is null); } ``` ```sh $ dmd a.d b.d -main $ echo $? $ 0 ```
Re: Cannot check function address
On Wednesday, 25 May 2022 at 05:56:28 UTC, Steven Schveighoffer wrote: It's a case where the compiler can't divine what you were thinking when you wrote that code ;) I see not in all cases but in mine. If the compiler sees the function isn't callable without arguments and it is inside an if-statement or `assert()` then it could at least suggest a pointer or ask: are you dumb? ;-)
Re: Cannot check function address
On 5/25/22 1:40 AM, frame wrote: This would have been more visible if the compiler just says: "function cannot be compared against null, only function pointer". That function vs function pointer is too subtle. It's a case where the compiler can't divine what you were thinking when you wrote that code ;) remember that the expression `fun` where fun is a *function*, and not a *function pointer*, is the equivalent of `fun()`. It can't figure out that you really thought `fun` was a function pointer, maybe it thinks that you are missing an overload? Maybe fun actually is a no-arg function, and the result isn't comparable against null (or maybe it is, and it compiles and does something completely different!). But I'm glad you discovered the issue. -Steve