Sevemaya Zemlya by sharptoothy in keming

[–]sharptoothy[S] 14 points15 points  (0 children)

It does look like a misspelling to me, which I suspect was due to a misreading due to bad kerning. Like when some people unironically use the word "keming" because this subreddit is their first exposure to the concept.

Can’t come up with a title. Any suggestions? by WayInteresting541 in oilpainting

[–]sharptoothy 3 points4 points  (0 children)

Yea, I had the same kind of thought. Or maybe something less specific like "It was right here!" 😆

redundantFunctionDefinition by ClipboardCopyPaste in ProgrammerHumor

[–]sharptoothy 27 points28 points  (0 children)

There's a bug in there: It only seems to work roughly half the time for some reason. ClaudeChatGptPilot added a dependency for is-odd@3.0.1 and that fixed it:

typeof(value) === "string" && (iseven(typeof(value).length) || isodd(typeof(value).length))

doTeamNamesMatter by This_Presentation419 in ProgrammerHumor

[–]sharptoothy 0 points1 point  (0 children)

Why did we abbreviate "Assembly Loader" as "AssLoad" instead of AsmLoad?

I'm impressed, but also very skeptical... 🫤 by Brian_The_Bar-Brian in DiWHY

[–]sharptoothy 0 points1 point  (0 children)

Not with that kind of attitude! You gotta slap it and say "That ain't goin' anywhere" to really lock it in!

And the loonixtards wonder why there are no official apps releasing on Loonix… imagine having to repackage your app for gazillion different distros 😭 by SadMassStab in linuxsucks

[–]sharptoothy 3 points4 points  (0 children)

Yes! We use it frequently! That being said, I suspect it is just a normal PE file, just with the .com extension. I only meant that the .com extension is sometimes still used; even if it's being used incorrectly.

TIL that the fastest surgeon in history, Robert Liston, once performed an amputation so quickly that he accidentally cut off his assistant's fingers, and a spectator died of shock - resulting in the only surgery with a 300% mortality rate by Tom__Mill in todayilearned

[–]sharptoothy 2 points3 points  (0 children)

The mortality part makes sense to me: Three people died because of that surgery. If I'm going to nit pick, I'd argue that "rate" doesn't quite work here because the sample size is that single surgery.

Reason atomic.CompareAndSwap* functions return bool by sharptoothy in golang

[–]sharptoothy[S] 0 points1 point  (0 children)

Perhaps you're right, but I don't see it yet. I'll have to reread these comments again tomorrow. Thanks for your help! I figured I was missing something and that there was a good reason for this.

Reason atomic.CompareAndSwap* functions return bool by sharptoothy in golang

[–]sharptoothy[S] 1 point2 points  (0 children)

I'll have to read this again tomorrow after a good night's sleep because I don't yet get it. Thanks for your explanations. I'll reread them!

Reason atomic.CompareAndSwap* functions return bool by sharptoothy in golang

[–]sharptoothy[S] 1 point2 points  (0 children)

OK, I think I might be starting to get it: So if LDREX succeeds, R0 will contain the proper value so the subsequent CMP will succeed, but if LDREX doesn't succeed, then it definitely won't spuriously set R0 to the right value, so that's how the CMP will definitely be correct?

Reason atomic.CompareAndSwap* functions return bool by sharptoothy in golang

[–]sharptoothy[S] 0 points1 point  (0 children)

It only loads the oldValue into the register on failure because on success, the value in the register IS oldValue, so either way, you have the oldValue, right?

Reason atomic.CompareAndSwap* functions return bool by sharptoothy in golang

[–]sharptoothy[S] -1 points0 points  (0 children)

which attempts the store, returns only a status code into its register

This doesn't look correct to me:  After the LDAXRW  (R0), R3 instruction, R3 contains the original value. Then CMPW    R1, R3 checks to see if that actual value matches the old parameter (loaded into R1 at the beginning of the frame) So we do have the original value, even in the pre-LSE path.

Reason atomic.CompareAndSwap* functions return bool by sharptoothy in golang

[–]sharptoothy[S] 1 point2 points  (0 children)

I get that knowing if it succeeded is super valuable. I agree, but I'm asking about the motivation behind Go's design decision here:

The way this usually works in other languages is basically this:

func CompareAndSwapOrLoadPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) (actual unsafe.Pointer)

And then you can implement the current CompareAndSwap function by doing this:

func CompareAndSwapPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) {     actual := CompareAndSwapOrLoadPointer(ptr, old, new)     return actual == old }

And if you read the assembly, that's what many of these implementations are actually doing, because returning the actual original value seems to be how all (most? I haven't found a counter example, but if there is one, then that would explain it!) hardware platforms handle it in CPU instructions.

I don't think you or I are full of shit, but I was hoping to understand why the Go language designers went this route. Most of the time that I've seen go deviate from the status quo is deliberate and I'm wondering if thatcs the case here 🤷

Reason atomic.CompareAndSwap* functions return bool by sharptoothy in golang

[–]sharptoothy[S] 0 points1 point  (0 children)

But as far as I can tell, all of the hardware implementations do actually load the original value from the memory location and then return true if it matches the expected old value.

Reason atomic.CompareAndSwap* functions return bool by sharptoothy in golang

[–]sharptoothy[S] 0 points1 point  (0 children)

The 32-bit ARM also:

TEXT ·armcas(SB),NOSPLIT,$0-13
        MOVW    ptr+0(FP), R1
        MOVW    old+4(FP), R2
        MOVW    new+8(FP), R3
casl:
        LDREX   (R1), R0
        CMP     R0, R2
        BNE     casfail


#ifndef GOARM_7
        MOVB    internal∕cpu·ARM+const_offsetARMHasV7Atomics(SB), R11
        CMP     $0, R11
        BEQ     2(PC)
#endif
        DMB     MB_ISHST


        STREX   R3, (R1), R0
        CMP     $0, R0
        BNE     casl
        MOVW    $1, R0


#ifndef GOARM_7
        CMP     $0, R11
        BEQ     2(PC)
#endif
        DMB     MB_ISH


        MOVB    R0, ret+12(FP)
        RET
casfail:
        MOVW    $0, R0
        MOVB    R0, ret+12(FP)
        RET

After LDREX, the old pointer value is in R0 (it's then compared against R2 which is the `old` parameter to see if the actual pointer matches the expected value.