God, it's impossible! You just have to convert the entire fucking call stack all the way up to async functions. It could mean refactoring hundreds of functions.
To be fair, there is a logic to this, if you put yourself within the crappiness of the JavaScript threading model. And Python is not that much better with its Global Interpreter Lock.
The problem is that async was introduced relatively late, previously we just had to use infinitely deep callback trees, which was worse:
myAsync().then(ret => myAsync2(ret).then(ret2 => myAsync3(re3)))
compared to the new infinitely more readable:
ret = await myAsync()
ret2 = await myAsync2(ret)
ret3 = await myAsync3(ret3)
But now we are in an endless period of transition between both worlds.
It is also worth mentioning that callbacks are still inescapable if you really want to fan out into a non-linear dependency graph, usually with Promise.all:
await Promise.all([
  myAsync(1).then(ret => myAsync2(ret)),
  myAsync(2).then(ret => myAsync2(ret)),
])
And then, after many many hours of this work, you might notice that the new code is way, way way slower than before, because making small functions async has a large performance impact: madelinemiller.dev/blog/javascript-promise-overhead/. Real world case with a 4x slowdown: github.com/ourbigbook/ourbigbook/tree/async-slow.
Anyways, since you Googled here, you might as well learn the standard pattern to convert callbacks functions into async functions using a promise: stackoverflow.com/questions/4708787/get-password-from-input-using-node-js/71868483#71868483
Figure 1.
async function Teletubbies meme
. Source. TODO find original source.
ARM Cortex-M Updated 2025-07-16
F-Droid Updated 2025-07-16
Ryzen Updated 2025-07-16
This was the CPU architecure that saved AMD in the 2010's, see also: Video "How AMD went from nearly Bankrupt to Booming by Brandon Yen (2021)"
Epyc Updated 2025-07-16
AMD GPU Updated 2025-07-16
Annapurna Labs Updated 2025-07-16
Page contains a good summary of their hardware to date. They seem to still be the centerpiece of silicon development. There are still however people outside of Israel doing it, e.g.: www.linkedin.com/in/laurasharpless/ says as of 2021:
My team develops software for our next-generation Machine Learning accelerators: HAL, firmware, and SoC models.
2021: networking chip reports emerge: www.theverge.com/circuitbreaker/2021/3/30/22358633/amazon-reportedly-custom-network-switch-silicon-aws, presumably contesting with the likes of Cisco?
AWS Graviton Updated 2025-07-16
ARM-based servers.
ATP synthesis mechanism Updated 2025-07-16
ATP is the direct output of all the major forms of "energy generation" in cells:
x86 Paging Tutorial / Sample code Updated 2025-07-16
Like everything else in programming, the only way to really understand this is to play with minimal examples.
What makes this a "hard" subject is that the minimal example is large because you need to make your own small OS.
x86 Paging Tutorial / Intel manual Updated 2025-07-16
Although it is impossible to understand without examples in mind, try to get familiar with the manuals as soon as possible.
Specially interesting is Figure 4-4 "Formats of CR3 and Paging-Structure Entries with 32-Bit Paging", which gives the key data structures.
x86 Paging Tutorial / Application Updated 2025-07-16
Paging makes it easier to compile and run two programs or threads at the same time on a single computer.
For example, when you compile two programs, the compiler does not know if they are going to be running at the same time or not.
So nothing prevents it from using the same RAM address, say, 0x1234, to store a global variable.
And thread stacks, that must be contiguous and keep growing down until they overwrite each other, are an even bigger issue!
But if two programs use the same address and run at the same time, this is obviously going to break them!
Paging solves this problem beautifully by adding one degree of indirection:
(logical) ------------> (physical)
             paging
Where:
  • logical addresses are what userland programs see, e.g. the contents of rsi in mov eax, [rsi].
    They are often called "virtual" addresses as well.
  • physical addresses can be though of the values that go to physical RAM index wires.
    But keep in mind that this is not 100% true because of further indirections such as:
Compilers don't need to worry about other programs: they just use simple logical addresses.
As far as programs are concerned, they think they can use any address between 0 and 4 GiB (2^32, FFFFFFFF) on 32-bit systems.
The OS then sets up paging so that identical logical addresses will go into different physical addresses and not overwrite each other.
This makes it much simpler to compile programs and run them at the same time.
Paging achieves that goal, and in addition:
  • the switch between programs is very fast, because it is implemented by hardware
  • the memory of both programs can grow and shrink as needed without too much fragmentation
  • one program can never access the memory of another program, even if it wanted to.
    This is good both for security, and to prevent bugs in one program from crashing other programs.
Or if you like non-funny jokes:
Figure 1.
Comparison between the Linux kernel userland memory virtualization and The Matrix
. Source. Is this RAM real?
Paging is implemented by the CPU hardware itself.
Paging could be implemented in software, but that would be too slow, because every single RAM memory access uses it!
Operating systems must setup and control paging by communicating to the CPU hardware. This is done mostly via:
Processes can however make requests to the OS that cause the page tables to be modified, notably:
The kernel then decides if the request will be granted or not in a controlled manner.
x86 Paging Tutorial / Segmentation Updated 2025-07-16
In x86 systems, there may actually be 2 address translation steps:
  • first segmentation
  • then paging
like this:
(logical) ------------------> (linear) ------------> (physical)
             segmentation                 paging
The major difference between paging and segmentation is that:
  • paging splits RAM into equal sized chunks called pages
  • segmentation splits memory into chunks of arbitrary sizes
Paging came after segmentation historically, and largely replaced it for the implementation of virtual memory in modern OSs.
Paging has become so much more popular that support for segmentation was dropped in x86-64 in 64-bit mode, the main mode of operation for new software, where it only exists in compatibility mode, which emulates IA-32.

There are unlisted articles, also show them or only show them.