6 ms·
Side question : could anyone recommend exercises for mid-experienced developer that really has troubles spotting potential race conditions, and generally strugg
by bsaul 4y ago
Side question : could anyone recommend exercises for mid-experienced developer that really has troubles spotting potential race conditions, and generally struggle with concurrency ? I’ve realized i’m spending a lot of time reviewing his PR, and i’d like to help him improve faster on that topic.
- neilparikh 4y agoI enjoyed http://deadlockempire.github.io/ http://deadlockempire.github.io/
- avgcorrection 4y agoBased on the dragon this Deadlock Empire must be Wales.
- maldev 4y agoIt's actually really easy. Traditional threading has a very obvious design pattern, where if someone isn't doing this you can be sure there's an issue. TL;DR, if you don't have a "getter/setter" you're doing it wrong and it's a sign of bad code. Firstly, make sure that there's only ONE place to write. Write being changing the variable in anyway(Obviously make sure you have a lock or other primitive here). If there's multiple places, that's a big smell for a race condition, and a massive turd for a shitty design pattern. Secondly, just like the write, all reads should be done from a single place. And then for the advance developer, you also may need to make sure that the cache is synchronized. Pretty much all libraries will do this for you, but if you ever need to dive into internals that alot of "guides" or papers DON'T cover, you need Fences or whatever your architecture provides. I have this page bookmarked for when I need a quick refresher https://stackoverflow.com/questions/27627969/why-is-or-isnt-sfence-lfence-equivalent-to-mfence https://stackoverflow.com/questions/27627969/why-is-or-isnt-...
- gpderetta 4y agoSorry but it is not easy at all. Getter and setters do not help and can give a false sense of security. And caches do not need to be explicitly synchronized. On all common platforms the hardware will do it for you without user intervention. Fences have a different purpose.
- deleted 4y ago[deleted]
- maldev 4y agoHonestly just to prove how wrong you are and what you're saying is blatant misinformation, i'll correct you, since I don't think you're talking in good faith, or have any idea what you're saying. Regarding fences, In the intel system programming guide, section 8.1.3 " Handling Self- and Cross-Modifying Code The act of a processor writing data into a currently executing code segment with the intent of executing that data as code is called self-modifying code. IA-32 processors exhibit model-specific behavior when executing selfmodified code, depending upon how far ahead of the current execution pointer the code has been modified. As processor microarchitectures become more complex and start to speculatively execute code ahead of the retirement point (as in P6 and more recent processor families), the rules regarding which code should execute, pre- or post-modification, become blurred. To write self-modifying code and ensure that it is compliant with current and future versions of the IA-32 architectures, use one of the following coding options: (* OPTION 1 ) Store modified code (as data) into code segment; Jump to new code or an intermediate location; Execute new code; Vol. 3A 8-5 MULTIPLE-PROCESSOR MANAGEMENT ( OPTION 2 ) Store modified code (as data) into code segment; Execute a serializing instruction; ( For example, CPUID instruction ) Execute new code;" It further states, "The act of one processor writing data into the currently executing code segment of a second processor with the intent of having the second processor execute that data as code is called cross-modifying code. As with selfmodifying code, IA-32 processors exhibit model-specific behavior when executing cross-modifying code, depending upon how far ahead of the executing processors current execution pointer the code has been modified. To write cross-modifying code and ensure that it is compliant with current and future versions of the IA-32 architecture, the following processor synchronization algorithm must be implemented: ( Action of Modifying Processor ) Memory_Flag := 0; ( Set Memory_Flag to value other than 1 ) Store modified code (as data) into code segment; Memory_Flag := 1; ( Action of Executing Processor ) WHILE (Memory_Flag ≠ 1) Wait for code to update; ELIHW; Execute serializing instruction; ( For example, CPUID instruction *) Begin executing modified code;" So please tell me how the intel developer manual is wrong, how i'm wrong, and how they all server a "Different purpose" than what is given. I can link more instances from the Intel Developer manual if you want. I assume you've read it if you're trying to talk about the subject.