RLIM_INFINITY for loong64 has a special type.

159 views
Skip to first unread message

莫胜文

unread,
Mar 24, 2023, 1:14:45 PM3/24/23
to golang-nuts
RLIM_INFINITY is a constant generated by mkerrors.sh. Its value is 0xffffffffffffffff (uint64) in loong64 but -0x1(int64) in other architectures.

I'm not sure if it is necessary but it will cause some troubles for applications such as prometheus.

Bryan C. Mills

unread,
Apr 3, 2023, 3:40:33 PM4/3/23
to golang-nuts
POSIX specifies that RLIM_INFINITY in C has type rlim_t and that type rlim_t is an “unsigned integral type”, so the `uint64` value seems appropriate.

And it appears that syscall.RLIM_INFINITY has the correct (unsigned) value on most non-Linux platforms already. I wonder why the other Linux architectures use a signed value for an unsigned type? 🤔

莫胜文

unread,
Apr 3, 2023, 9:57:05 PM4/3/23
to golang-nuts
This is indeed a problem. Although there is no essential difference between useing `-0x1` or `0xffffffffffffffff`, but `-1` is usually used to represent infinity for developers.

Now there are two different types on the linux platform, this seems unnecessary.

peterGo

unread,
Apr 5, 2023, 10:17:20 AM4/5/23
to golang-nuts
The issue seems clear. syscall.RLIM_INFINITY for loong64 does not have a special type. syscall.RLIM_INFINITY for loong64 (0xffffffffffffffff) is a reasonable ordinary value for type rlim_t (uint64). Prometheus has a bug.

---

The Open Group Base Specifications Issue 7, 2018 edition    
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_resource.h.html    

sys/resource.h - definitions for XSI resource operations

rlim_t    
Unsigned integer type used for limit values.    

RLIM_INFINITY    
A value of rlim_t indicating no limit.    

---

The Go Programming Language    
https://github.com/golang/go    

go/src/syscall/zerrors_linux_loong64.go:    

const RLIM_INFINITY = 0xffffffffffffffff

go/src/syscall/zerrors_linux_amd64.go:    

const RLIM_INFINITY = -0x1

These operating system and architecture dependent values are generated (mkerrors.sh) from the respective C header (#include <sys/resource.h>) files.

---

Prometheus
https://github.com/prometheus/prometheus

https://github.com/prometheus/prometheus/blob/main/util/runtime/limits_default.go#L27

// syscall.RLIM_INFINITY is a constant and its default type is int.    
// It needs to be converted to an int64 variable to be compared with uint64 values.    
// See https://golang.org/ref/spec#Conversions    
var unlimited int64 = syscall.RLIM_INFINITY

func limitToString(v uint64, unit string) string {
    if v == uint64(unlimited) {
        return "unlimited"
    }
    return fmt.Sprintf("%d%s", v, unit)
}


For const RLIM_INFINITY = 0xffffffffffffffff, a bug:

https://go.dev/play/p/FvRPJer_UN1

cannot use RLIM_INFINITY as int64 value (overflows)

---

A fix for the Prometheus bug.

The RLIM_INFINITY C constant integer values generate Go constant untyped values which convert to Go constant type uint64 values.

const unlimited uint64 = syscall.RLIM_INFINITY & 0xffffffffffffffff

func limitToString(v uint64, unit string) string {
    if v == unlimited {
        return "unlimited"
    }
    return fmt.Sprintf("%d%s", v, unit)
}


https://go.dev/play/p/SZEJj9gSQ-t

A test for const RLIM_INFINITY = 0xffffffffffffffff

https://go.dev/play/p/2t95X_-QRWj

18446744073709551615 unlimited

A test for const RLIM_INFINITY = -1

https://go.dev/play/p/Q7aRtW1pWAz

18446744073709551615 unlimited

peter
Reply all
Reply to author
Forward
0 new messages