So the times before and after leap second get converted the the same date regardless of whether you know about the leap second or not. Edge case is that once second occuring twice. You might have seen that 23:59:60 seconds timestamp somewhere.
29 karma · joined July 4, 2025
So the times before and after leap second get converted the the same date regardless of whether you know about the leap second or not. Edge case is that once second occuring twice. You might have seen that 23:59:60 seconds timestamp somewhere.
New leap second will get to your system through NTP. Sadly NTP only distributes indicator flag that leap second is going to be introduced, but not the offset itself. But the distributed time itself is already affected by leap second, so NTP client doesn't really need to know.
(In contrast the other time sync mechanisms - GPS and PTP - use time scale unaffected by leap seconds and distribute it as an additional information with UTC offset. And it's left on client to modify received time on its end. Kernel has a parameters in clock_adjtime() for leap seconds.)
So if you have a passive system that has NTP client then it's time will change for new leap second on runtime. Linux treats UTC time as the dominant one, so that's the one saved to RTC device and will survive reboot.
There is CLOCK_TAI that sounds like it should return TAI time, but it is such a second class citizen to the point that nothing on regular Linux desktop and server distros even set the offset and it returns the same time as CLOCK_REALTIME.
There is a file in /etc with list of leap seconds that is part of some package, so you need to update the system to update this file. I don't believe traditional NTP software updates this package dynamically. But not many software uses it. If some init service script parsed and set the kernel UTC offset then your system's CLOCK_TAI would be one second late from rest of the world until update. But it doesn't affect UTC time on Linux in any way I know.
Both reads and writes ends take some time, I played with it to see how various programs react to a writer that just hangs or takes a lot of time. If the read is handled synchronously then you can block a UI loop. Some implement timeout and some can be blocked indefinitely.
But handling in asynchronously (either on thread or in nonblocking event loop) isn't an automatic win either. For example the new gnome text editor didn't order other user inputs with clipboard; so you would press Ctrl+V, nothing happened initially, continue writing and suddenly the clipboard content was inserted.
And I don't even remember how the OpenGL hidden window inhibiting worked with wl_data_source. Since the window is stuck in eglSwapBuffers, does it get unblocked to handle the clipboard write?
Surprisingly, even though Gnome compositor doesn't have a clipboard manager, it caches the clipboard content sometimes.
bool DawsonCompare(float af, float bf, int maxDiff)
{
int ai = *reinterpret_cast<int*>(&af);
int bi = *reinterpret_cast<int*>(&bf);
if (ai < 0)
ai = 0x80000000 - ai;
if (bi < 0)
bi = 0x80000000 - bi;
int diff = ai - bi;
if (abs(diff) < maxDiff)
return true;
return false;
}Requires fixed-length keys. Generate random table for each byte position. Then to hash a key, for each position lookup byte in table and XOR the results. This is used in chess/go/shogi/... engines because the board/position representation is fixed-length and you can undo modes easily - XOR-out byte from previous state and XOR-in from new state.
Incorrect, I only assume move/rename of backup to original location doesn't change it's mtime (which it doesn't with default flags or from IDE or file manager). And I don't think this is a weird or obscure workflow, I do it all the time - have two versions of a file or make a backup before some experimental changes, and restore it later.
1) pick a source file and make a copy of it for for later 2) edit selected source file and rebuild 3) move the copy to it's original location 4) try to rebuild, nothing happens
There is no async involved so function coloring argument doesn't really apply here.
I don't share author's hate for them, but they are definitely more verbose than popping form event queue and switch statement on event type ala SDL loop. Plenty of callbacks just set parameters in some state struct and do not propagate further. And you need to fill the vtable structs, and register that as listener. This boilerplate is probably the reason why basic window examples have ~200 lines instead of 40. But in larger project this is barely a problem.
I've been struggling with this initially as well, it's pretty poorly explained in docs. Short explanation:
Wayland-client library implements a queues over the socket. So to get it, you have to think about when is the socket read from and written to, and when are the queues pulled from or pushed to. There is always a default queue, but for example EGL+OpenGL creates it's own queue, which further makes it more confusing.
- `wl_display_dispatch_pending()` only pulls messages from default queue to callbacks
- `wl_display_dispatch()` also tries to do blocking read on the socket if no messages are in queue
- quite recently `wl_display_dispatch_queue_timeout()` was finally added, so you can do non-blocking read from the socket. earlier you had to hack the function yourself
- `wl_display_flush()` writes enqueued messages in queue to socket
- `wl_display_roundtrip()` sends a ping message and does blocking wait for response. the purpose is that you also send all enqueued requests and receive and process all responses. for example during init you call it to create registry and enumerate the objects, and you call it for second time to enumerate further protocol objects that got registered in registry callback, such as seat
- `eglSwapBuffers()` operates on its own queue, but reading from socket also enqueues to default queue, so you should always call `wl_display_dispatch_pending()` (on default queue) afterwards
There is also a way to get around being stuck in `eglSwapBuffers()` during window inhibition: disable the blocking with `eglSwapInterval(0)` and use `wl_surface_frame()` callback, and you get notified in callback when you can redraw and swap again. But you can't do blocking reads with `wl_display_dispatch()` anymore, have to use the timeout variant. After using it this way, you can also easily manage multiple vsynced windows independently on the same thread, and even use wayland socket in epoll event loop. None of this is documented of course.
The clipboard interface is definitely compromised a bit by being shared with drag-and-drop events, but it's not that complicated. Also there is a pitfall when you copy-paste to your own application and don't use any async event loop, you can get deadlocked by being expected to write and read on the same file descriptor at the same time.
The two notable functions are stb_text_locate_coord() and stb_textedit_find_charpos(), which connect the physical x,y coordinates with position in text buffer. They both iterate lines of text - accumulating y position; and the chars of last line - accumulating x position.
For windowing, drawing and OS integration, SDL with SDL_ttf is actually pretty good. SDL3_ttf API got an improvement and no longer requires zero-terminated strings so you don't need to relocate every chunk.
I'm still confused on the SIMD alignment. There are load instructs with alignment requirements (_mm_load_si128) and without (_mm_loadu_si128). Both claim the same latency and throughput. Somewhere I've heard the slowdown of unaligned access comes from using more bandwidth to load two aligned 128-bit lines to compose the unaligned value. But no idea if this affects multiple loads of continuous memory.
Buckets use 16 bytes because sse2 and arm neon SIMD are basically guaranteed.
I was shocked to read on how swiss tables - proclaiming to be the fastest hash tables - work. It's just open-addressing linear probe with no technique to deal with collisions and clustering. Plus the initial version rounded hashes%capacity to bucket size, thus using 4 less bits of hash, leading to even more collisions and clustering. Yet the super fast probe with apparently made it not an issue? Mind-boggling. (Later version allowed to scan from arbitrary position by mirroring first bucket as last.)