7 Responses

  1. Alex Vulpe says:

    I’m using OmniThreadLibrary, which kinda does the same thing and I find it very helpful.
    https://github.com/gabr42/OmniThreadLibrary

    • Indeed.
      The OmniThread library is far more advanced than what I’ve done here.

      In fact, this video was more about learning and education than providing an actual library.
      I wanted to understand how to do this, and to share the knowledge.

  2. In your video, you stated that an aligned read or write statement is atomic. Is this still the case with multi core and hyper threading processors? The 80486 processor was a single core, single processor, so all read and write operations were always serialised. With modern processors, reads and write’s could be at the same time I guess.

    • Yes it is. The user manual that I was referencing, though it says 486 or higher, was for a recent x86_64 architecture. I am not certain as to why Intel refer to operations as atomic from 486 up, as you are correct that the 486 did not have SMT features. I guess it’s possible that at the time they were preparing to add HT, which appeared in early pentiums and also xeons which were evolutions of the 486. Perhaps some 486 era xeon had threading, or maybe it was related to multi processor boards? Either way, the answer is yes, from what I see in manuals for recent multicore and SMT enabled processors, these operations remain atomic.

  3. Another good question on twitter @saeedkgr ..

    ” If push will be used only by one thread, there’s no need to use local variable because a single thread can’t enters one procedure twice simultaneously . Right? ”

    You still need to ensure that the fPushIndex is only updated at one atomic instant and does not go to an intermediate value (i.e. >length of array), because pull could get the wrong value for fPushIndex when it reads it. So we use a local variable to prep the new index, and then update fPushIndex in one single atomic operation.

  4. On twitter @darianmiller asks a great question.

    “In TMessagePipe.Pull: NewIndex := succ(fPullIndex) There’s some time between that line and the fPullIndex := NexIndex. What stops another thread from executing NewIndex := succ(fPullIndex) and overwriting fPullIndex later? 2 threads will eventually pull the same index”

    Each pipe is intended to be between only two threads, a sending and a receiving thread. If you have two threads which need to message a third, you should have two incoming pipes on that target thread.

Leave a Reply