What is Hackers' Pub?

Hackers' Pub is a place for software engineers to share their knowledge and experience with each other. It's also an ActivityPub-enabled social network, so you can follow your favorite hackers in the fediverse and get their latest posts in your feed.

1
0
0
0
0
0
8
0
0
0
0
0
0

Keep optimizing IRQ latency on the STM32H743 @ 480 MHz. I decided to try an event loop using the WFE instruction instead of IRQs, and I managed to get 60 ns input-to-output latency. I suspect this is the best possible latency. Latency did not improve by abusing QSPI controller to generate a write request (in fact it slightly degraded), even if the QSPI controller is physically close to the CPU. Clearly, passively monitoring signals is not the way to go for bus emulation. Perhaps the solution is predicting the clock before it even arrives, by internally generating a phase-shifted version of it.

Oscilloscope trace, showing a 58.80 ns input-to-output latency on the STM32H7.        while (true) {
                __WFE();
                __WFE();
                GPIOB->BSRR = GPIO_PIN_10;
                GPIOB->BSRR = (uint32_t) GPIO_PIN_10 << 16U;
        }        __HAL_RCC_GPIOA_CLK_ENABLE();

        //gpio_params.Mode = GPIO_MODE_INPUT;
        //gpio_params.Mode = GPIO_MODE_IT_RISING;
        gpio_params.Mode = GPIO_MODE_EVT_RISING;
        gpio_params.Pull = GPIO_PULLUP;
        gpio_params.Pin = GPIO_PIN_0;
        HAL_GPIO_Init(GPIOA, &gpio_params);

Keep optimizing IRQ latency on the STM32H743 @ 480 MHz. My "zero-latency IRQ" idea is a success, now I'm getting a 17.30 ns "effective" latency! Upon receiving every rising edge of the clock, the hardware immediately starts a timer that fires after a programmed delay, calculated to be slightly before the next clock rising edge. This way, the firmware is triggered from recovered, phase-shifted version of the clock, a little bit like how analog NTSC TVs got their H/VSYNC. Interrupt latency is completely eliminated for all but the first clock cycle (which is also predictable with pre-enabled outputs, since it's always the reset vector) Perfect bus emulation starts looking feasible.

Oscilloscope trace of the effective input-to-output latency: 17.30 ns. This latency is not a true latency since it's triggered by the clock's previous rising edge.static void timer_config(void)
{
        /*
         * NES master clock: 21.477272 MHz
         * NES CPU clock: 21.477272 / 12 = 1.7897727 MHz
         * NES clock period = 558.7301 ns
         * STM32 IRQ latency: 70 ns
         *
         * To predict the next NES CPU clock rising edge for "zero-latency"
         * IRQ, start a one-shot timer with a delay of 558.7301 - 70 ns =
         * 488.7301 ns timer based on the previous rising edge.
         *
         * STM32 HCLK clock: 237.5 MHz
         * STM32 HCLK period: 4.2105 ns
         * Delay value: 488.7301 // 4.2105 = 116
         */
        static const uint16_t timer_startdelay = 116;

        /*
         * We only care about the timer's rising edge (counter == output
         * compare) for an interrupt, the timer's actual duration doesn't
         * matter, use 1 for a narrow pulse.
         */
        static const uint16_t timer_duration = timer_startdelay + 1;

        __HAL_RCC_TIM2_CLK_ENABLE();

        timer_ctx.Instance = TIM2;
        timer_ctx.Init.Period            = timer_duration;
        timer_ctx.Init.Prescaler         = 0;
        timer_ctx.Init.ClockDivision     = 0;
        timer_ctx.Init.CounterMode       = TIM_COUNTERMODE_UP;
        timer_ctx.Init.RepetitionCounter = 0;

        if (HAL_TIM_OnePulse_Init(&timer_ctx, TIM_OPMODE_SINGLE) != HAL_OK) {
                panic("HAL_TIM_Base_Init() error!\n");
        }

        /* Initialize the timer in single-shot mode */
        TIM_OnePulse_InitTypeDef pulse_ctx;
        pulse_ctx.OCMode       = TIM_OCMODE_PWM2;
        pulse_ctx.OCPolarity   = TIM_OCPOLARITY_HIGH;
        pulse_ctx.Pulse        = timer_startdelay;
        pulse_ctx.ICPolarity   = TIM_ICPOLARITY_RISING;
        pulse_ctx.ICSelection  = TIM_ICSELECTION_DIRECTTI;
        pulse_ctx.ICFilter     = 0;
        pulse_ctx.OCNPolarity  = TIM_OCNPOLARITY_HIGH;
        pulse_ctx.OCIdleState  = TIM_OCIDLESTATE_RESET;
        pulse_ctx.OCNIdleState = TIM_OCNIDLESTATE_RESET;
        if (HAL_TIM_OnePulse_ConfigChannel(&timer_ctx, &pulse_ctx, TIM_CHANNEL_2, TIM_CHANNEL_1) != HAL_OK) {
                panic("HAL_TIM_OnePulse_ConfigChannel() error\n");
        }

        /*
         * Trigger the start of the timer with the external signal TI1,
         * connected to the NES CPU clock.
         */
        TIM_SlaveConfigTypeDef slave_ctx;
        slave_ctx.SlaveMode        = TIM_SLAVEMODE_TRIGGER;
        slave_ctx.InputTrigger     = TIM_TS_TI1FP1;
        slave_ctx.TriggerPolarity  = TIM_TRIGGERPOLARITY_NONINVERTED;
        slave_ctx.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
        slave_ctx.TriggerFilter    = 0;
        if (HAL_TIM_SlaveConfigSynchronization(&timer_ctx, &slave_ctx) != HAL_OK) {
                panic("HAL_TIM_SlaveConfigSynchronization() error!\n");
        }
        /* Use PA0 as the external trigger */
        __HAL_RCC_GPIOA_CLK_ENABLE();

        GPIO_InitTypeDef gpio_ctx;
        gpio_ctx.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        gpio_ctx.Mode = GPIO_MODE_AF_OD;
        gpio_ctx.Pin = GPIO_PIN_0;
        gpio_ctx.Pull = GPIO_PULLDOWN;
        gpio_ctx.Alternate = GPIO_AF1_TIM2;
        HAL_GPIO_Init(GPIOA, &gpio_ctx);

        /*
         * Wait for the output compare event (fires after the external trigger
         * after a timer_startdelay.
         */
        HAL_NVIC_SetPriority(TIM2_IRQn, 0, 1);
        HAL_NVIC_EnableIRQ(TIM2_IRQn);

        if (HAL_TIM_OnePulse_Start_IT(&timer_ctx, TIM_CHANNEL_1) != HAL_OK) {
                panic("HAL_TIM_OC_Start() error!\n");
        }
__attribute__((section (".itcm_text")))
void TIM2_IRQCallback(void)
{
        GPIOB->BSRR = GPIO_PIN_10;
        GPIOB->BSRR = (uint32_t) GPIO_PIN_10 << 16U;
        HAL_TIM_IRQHandler(&timer_ctx);
}__attribute__((section (".itcm_text")))
void TIM2_IRQHandler(void)
{
        TIM2_IRQCallback();
}
0

Good news, everyone! super-save 0.5 is out and it's super awesome emacsredux.com/blog/2026/03/18

super-save 0.5: Modernized and Better Than Ever

It’s been a while since the last super-save release. The last time I wrote about it was back in 2018, when I boldly proclaimed: It seems that now super-save is beyond perfect, so don’t expect the next release any time soon! Famous last words. There was a 0.4 release in 2023 (adding a predicate system, buffer exclusions, silent saving, and trailing whitespace cleanup), but I never got around to writing about it. The package has been rock solid for years and I just didn’t pay it much attention – it quietly did its job, which is kind of the whole point of an auto-save package. A Bit of History The idea behind super-save goes all the way back to a blog post I wrote in 2012 about auto-saving buffers on buffer and window switches. I had been using IntelliJ IDEA for Java development and loved that it would save your files automatically whenever the editor lost focus. No manual C-x C-s, no thinking about it. I wanted the same behavior in Emacs. Back then, the implementation was crude – defadvice on switch-to-buffer, other-window, and the windmove commands. That code lived in Emacs Prelude for a few years before I extracted it into a standalone package in 2015. super-save was born. What Prompted This Release Yesterday I stumbled upon buffer-guardian.el, a package with very similar goals to super-save. Its README has a comparison with super-save that highlighted some valid points – mainly that super-save was still relying on advising specific commands for buffer-switch detection, while newer Emacs hooks like window-buffer-change-functions and window-selection-change-functions could do the job more reliably. The thing is, those hooks didn’t exist when super-save was created, and I didn’t rush to adopt them while Emacs 27 was still new and I wanted to support older Emacsen. But it’s 2026 now – Emacs 27.1 is ancient history. Time to modernize! What’s New in 0.5 This is the biggest super-save release in years! Here are the highlights: Modern buffer/window switch detection Buffer and window switches are now detected via window-buffer-change-functions and window-selection-change-functions, controlled by the new super-save-when-buffer-switched option (enabled by default). This catches all buffer switches – keyboard commands, mouse clicks, custom functions – unlike the old approach of advising individual (yet central) commands. Modern focus handling Frame focus loss is now detected via after-focus-change-function instead of the obsolete focus-out-hook, controlled by super-save-when-focus-lost (also enabled by default). Soft-deprecated trigger system With the new hooks in place, both super-save-triggers and super-save-hook-triggers now default to nil. You can still use them for edge cases, but for the vast majority of users, the built-in hooks cover everything. org-src and edit-indirect support super-save now knows how to save org-src edit buffers (via org-edit-src-save) and edit-indirect buffers (via edit-indirect--commit). Both are enabled by default and controlled by super-save-handle-org-src and super-save-handle-edit-indirect. Safer predicates Two new default predicates prevent data loss: verify-visited-file-modtime avoids overwriting files modified outside Emacs, and a directory existence check prevents errors when a file’s parent directory has been removed. Predicate evaluation is also wrapped in condition-case now, so a broken custom predicate logs a warning instead of silently disabling all auto-saving. Emacs 27.1 required This allowed cleaning up the code and relying on modern APIs. Upgrading For most users, upgrading is seamless – the new defaults just work. If you had a custom super-save-triggers list for buffer-switching commands, you can probably remove it entirely: ;; Before: manually listing every command that switches buffers (setq super-save-triggers '(switch-to-buffer other-window windmove-up windmove-down windmove-left windmove-right next-buffer previous-buffer)) ;; After: the window-system hooks catch all of these automatically ;; Just delete the above and use the defaults! If you need to add triggers for commands that don’t involve a buffer switch (like ace-window), super-save-triggers is still available for that. A clean 0.5 setup looks something like this: (use-package super-save :ensure t :config ;; Save buffers automatically when Emacs is idle (setq super-save-auto-save-when-idle t) ;; Don't display "Wrote file..." messages in the echo area (setq super-save-silent t) ;; Disable the built-in auto-save (backup files) since super-save handles it (setq auto-save-default nil) (super-save-mode +1)) It’s also worth noting that Emacs 26.1 introduced auto-save-visited-mode, which saves file-visiting buffers to their actual files after an idle delay. This overlaps with super-save-auto-save-when-idle, so if you prefer using the built-in for idle saves, you can combine the two: (use-package super-save :ensure t :config ;; Don't display "Wrote file..." messages in the echo area (setq super-save-silent t) ;; Disable the built-in auto-save (backup files) (setq auto-save-default nil) (super-save-mode +1)) ;; Let the built-in auto-save-visited-mode handle idle saves (auto-save-visited-mode +1) Burst-Driven Development Strikes Again Most of my Emacs packages are a fine example of what I like to call burst-driven development – long periods of stability punctuated by short intense bursts of activity. I hadn’t touched super-save in years, then spent a few hours modernizing the internals, adding a test suite, improving the documentation, and cutting a release. It was fun to revisit the package after all this time and bring it up to 2026 standards. If you’ve been using super-save, update to 0.5 and enjoy the improvements. If you haven’t tried it yet – give it a shot. Your poor fingers might thanks for you this, as pressing C-x C-s non-stop is hard work! That’s all I have for you today. Keep hacking!

emacsredux.com · Emacs Redux

0
0

美·이란, 물밑 협상 기류 속 '샅바 싸움'…겉으론 으름장·부인 겉으로는 한치의 양보없는 '치킨 게임'을 외치지만, 도널드 트럼프 미국 대통령과 이란 정권 모두 장기전은 부담인 만큼 대화의 물꼬를 트려는 이중 전략을 취하는 것으로 보인다. ... 이란은 개전 초기에도 협상을 위해 다른 중동국을 거쳐 미국 중앙정보국(CIA)을 접촉했지만 미국이 퇴짜를 놓은 것으로 전해졌다. 등록 2026-03-17 18:33

美·이란, 물밑 협상 기류 속 &#x27;샅바 싸움&#...

0
0
0
0
0
0

 香川県観音寺市で、少女のスカートの下に長さ60メートルの集排水管を設置。集まった地下水を周辺の雨水幹線に流します。背景には、高級感を演出するため、毎回のお手入れも簡単です。1/3ページ

0

New post! Why does everyone in Hawaiʻi speak Japanese? For the same reason everyone only ever talks about the latest AAA video games, which is to say: to experience reality, you need to leave your bubble and talk to other people.

renkotsuban.com/posts/2026-03-

0
3
0

I'm a few months into my experiment with doing OSS development without any use of GitHub whatsoever, and while I had to introduce a minor exception, it's mostly been quite successful. Difficult, but successful.

Tricks I've found:
- Spend money. Maybe not a hell of a lot, but more than zero. What GitHub provides is subsidized in the interest of locking you in. Going without GH means spending some cash.
- Have friends. None of this would be possible without friends lending me infrastructure.

- Be OK with less. There's a lot of features GH provides that I really don't actually use, and so it's OK to go without them.

All in all, I think that as a community, we never should have gotten to where GitHub was an SPOF for all of OSS, but it is possible to undo that. It's harder than it should be, but it's getting easier thanks to groups like Codeberg and people like @whitequark✧✦Catherine✦✧.

0

I'm a few months into my experiment with doing OSS development without any use of GitHub whatsoever, and while I had to introduce a minor exception, it's mostly been quite successful. Difficult, but successful.

Tricks I've found:
- Spend money. Maybe not a hell of a lot, but more than zero. What GitHub provides is subsidized in the interest of locking you in. Going without GH means spending some cash.
- Have friends. None of this would be possible without friends lending me infrastructure.

0
0
1
0
1
0
네 제가 미친놈이었읍니다.. 한때 좋아하던 사람의 같장르를 7개 이상 다 같이 파줬고 연성도 다 해줬습니다 앤솔로지도 내준다고 했습니다 그런데도 아무런 보람이 없었습니다 (밥상을 뒤집으며)
1
0
1
0
0
1
35
1
1
35
1
0
0
0

Kind and cherished FOSS and computing freedom advocate @sleepyowlSchrödinger's Catgirl (Joyce) (Joyce Ng) has gone missing and there is reason to fear she may have been apprehended by authorities, possibly likely even for being framed. Nobody has been able to reach her and many of us are worried for her safety.

Joyce does work on verifiable open source hardware. She also has been an activist pushing against the rise of far-right Christian nationalism globally but especially in Singapore. Because of this and her identity, she has people who would like to see bad things happen to her.

Probably for this reason, she may have been misidentified by Five Eyes as being a threat actor. Joyce wrote about this concern in November, posting a threatening screenshot where she was tipped off. bitowl.online/about

Please spread this wide. Hopefully this is a false alarm but Joyce is a kind-hearted person who fights for human rights and computing freedom; many of us are worried for her safety.

0
6
0
0

Fascinating paper: Your Morals Depend on Language (Costa et al., 2014). People make significantly more utilitarian choices in moral dilemmas when the dilemma is presented in a foreign language, apparently because a foreign language dulls emotional responses and shifts the balance toward deliberative thinking.

It matches my own experience. Thinking in a foreign language feels like rendering graphics without GPU acceleration: everything runs on raw CPU, slower and more laborious. After a full day of conversations in English or Japanese, I'm physically exhausted in a way that Korean never does to me. What I didn't quite register until reading this paper is that the “GPU” doing all that fast, effortless processing is largely the emotional system. When it steps back, you end up doing more of the reasoning yourself. Whether that's a feature or a bug probably depends on what you're deciding.

0
5
0
0
0
0

"몰상식·싸구려"…독기 가득 트럼프, 전쟁 비판 언론에 막말 (미국·이란 전쟁) 트럼프 미국 대통령이 이란 전쟁 비판 여론에 직면하자 언론을 가짜뉴스로 비난하며 압박을 강화했다. 언론 자유 침해 논란과 전쟁 비판 여론, 미 행정부 언론 공격이 집중 조명되고 있다. | 등록 2026-03-17 18:30

&quot;몰상식·싸구려&quot;…독기 가득 트럼프,...

0

【緊急リリース】
温泉マーク - 戦争反対(prod. inuyasha)

3月18日~4月1日までに得た収益の100%を下記リンクからユニセフの「人道危機緊急募金」へと寄付します。

戦争反対(prod. inuyasha) | 温泉マーク(ONSENMARK)
onsenmark.bandcamp.com/track/p

0
1

テキサスでは2月に41.1℃というアメリカの冬の最高気温を観測。3月はどこで40℃超えするんでしょうか。ダラスは35℃を超えそうです。☞ 米西部に極めて異例の熱波襲来、3月に41度予想 cnn.co.jp/usa/35245202.html

0
0

코레일이 서울역~청량리역 간 KTX-이음을 5천원에 이용할 수 있는 특가 상품을 내놓았네요; 운행구간 중 일부인 경의중앙선 구간에 조금이라도 사람을 더 태우기 위해 운영하는 것 같습니다. 빙~ 돌아가는데 누가 이용하겠냐만...찍먹하거나 철덕분들은 좋아하실지도?

korail.com/ticket/guest/notice

0
0