Skip to content

Commit 4620db7

Browse files
abdullahkiani007gopherbot
authored andcommitted
runtime: use timer_settime64 on 32-bit Linux
Linux introduced new syscalls to fix the year 2038 issue. To still be able to use the old ones, the Kconfig option COMPAT_32BIT_TIME would be necessary. Use the new 64-bit syscall for timer_settime by default. Add a fallback to use the 32-bit syscall when the 64-bit version returns _ENOSYS. Fixes #75133 Change-Id: Iccb8831b67f665067ee526e93c3ff2f4f5392edf GitHub-Last-Rev: 6c3d62d GitHub-Pull-Request: #75957 Reviewed-on: https://go-review.googlesource.com/c/go/+/712642 Reviewed-by: Jorropo <jorropo.pgm@gmail.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Jorropo <jorropo.pgm@gmail.com>
1 parent b31dc77 commit 4620db7

File tree

9 files changed

+113
-10
lines changed

9 files changed

+113
-10
lines changed

src/runtime/defs_linux_386.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,14 @@ type ucontext struct {
237237
uc_sigmask uint32
238238
}
239239

240-
type itimerspec struct {
240+
type itimerspec32 struct {
241241
it_interval timespec32
242242
it_value timespec32
243243
}
244+
type itimerspec struct {
245+
it_interval timespec
246+
it_value timespec
247+
}
244248

245249
type itimerval struct {
246250
it_interval timeval

src/runtime/defs_linux_arm.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,16 @@ func (tv *timeval) set_usec(x int32) {
169169
tv.tv_usec = x
170170
}
171171

172-
type itimerspec struct {
172+
type itimerspec32 struct {
173173
it_interval timespec32
174174
it_value timespec32
175175
}
176176

177+
type itimerspec struct {
178+
it_interval timespec
179+
it_value timespec
180+
}
181+
177182
type itimerval struct {
178183
it_interval timeval
179184
it_value timeval

src/runtime/defs_linux_mipsx.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,16 @@ type siginfo struct {
152152
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
153153
}
154154

155-
type itimerspec struct {
155+
type itimerspec32 struct {
156156
it_interval timespec32
157157
it_value timespec32
158158
}
159159

160+
type itimerspec struct {
161+
it_interval timespec
162+
it_value timespec
163+
}
164+
160165
type itimerval struct {
161166
it_interval timeval
162167
it_value timeval

src/runtime/os_linux.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -435,9 +435,6 @@ func setitimer(mode int32, new, old *itimerval)
435435
//go:noescape
436436
func timer_create(clockid int32, sevp *sigevent, timerid *int32) int32
437437

438-
//go:noescape
439-
func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32
440-
441438
//go:noescape
442439
func timer_delete(timerid int32) int32
443440

src/runtime/os_linux_settime32.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build linux && (386 || arm || mips || mipsle)
6+
7+
package runtime
8+
9+
import "internal/runtime/atomic"
10+
11+
var timer32bitOnly atomic.Bool
12+
13+
//go:noescape
14+
func timer_settime32(timerid int32, flags int32, new, old *itimerspec32) int32
15+
16+
//go:noescape
17+
func timer_settime64(timerid int32, flags int32, new, old *itimerspec) int32
18+
19+
//go:nosplit
20+
func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32 {
21+
if !timer32bitOnly.Load() {
22+
ret := timer_settime64(timerid, flags, new, old)
23+
// timer_settime64 is only supported on Linux 5.0+
24+
if ret != -_ENOSYS {
25+
return ret
26+
}
27+
timer32bitOnly.Store(true)
28+
}
29+
30+
var newts,oldts itimerspec32
31+
var new32,old32 *itimerspec32
32+
33+
if new != nil {
34+
newts.it_interval.setNsec(new.it_interval.tv_sec*1e9 + new.it_interval.tv_nsec)
35+
newts.it_value.setNsec(new.it_value.tv_sec*1e9 + new.it_value.tv_nsec)
36+
new32 = &newts
37+
}
38+
39+
if old != nil {
40+
oldts.it_interval.setNsec(old.it_interval.tv_sec*1e9 + old.it_interval.tv_nsec)
41+
oldts.it_value.setNsec(old.it_value.tv_sec*1e9 + old.it_value.tv_nsec)
42+
old32 = &oldts
43+
}
44+
45+
// Fall back to 32-bit timer
46+
return timer_settime32(timerid, flags, new32, old32)
47+
}

src/runtime/os_linux_settime64.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build linux && !(386 || arm || mips || mipsle)
6+
7+
package runtime
8+
9+
//go:noescape
10+
func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32

src/runtime/sys_linux_386.s

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#define SYS_exit_group 252
5555
#define SYS_timer_create 259
5656
#define SYS_timer_settime 260
57+
#define SYS_timer_settime64 409
5758
#define SYS_timer_delete 263
5859
#define SYS_clock_gettime 265
5960
#define SYS_tgkill 270
@@ -209,7 +210,8 @@ TEXT runtime·timer_create(SB),NOSPLIT,$0-16
209210
MOVL AX, ret+12(FP)
210211
RET
211212

212-
TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
213+
// Linux: kernel/time/posix-timer.c, requiring COMPAT_32BIT_TIME
214+
TEXT runtime·timer_settime32(SB),NOSPLIT,$0-20
213215
MOVL $SYS_timer_settime, AX
214216
MOVL timerid+0(FP), BX
215217
MOVL flags+4(FP), CX
@@ -219,6 +221,16 @@ TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
219221
MOVL AX, ret+16(FP)
220222
RET
221223

224+
TEXT runtime·timer_settime64(SB),NOSPLIT,$0-20
225+
MOVL $SYS_timer_settime64, AX
226+
MOVL timerid+0(FP), BX
227+
MOVL flags+4(FP), CX
228+
MOVL new+8(FP), DX
229+
MOVL old+12(FP), SI
230+
INVOKE_SYSCALL
231+
MOVL AX, ret+16(FP)
232+
RET
233+
222234
TEXT runtime·timer_delete(SB),NOSPLIT,$0-8
223235
MOVL $SYS_timer_delete, AX
224236
MOVL timerid+0(FP), BX

src/runtime/sys_linux_arm.s

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#define SYS_clock_gettime (SYS_BASE + 263)
4545
#define SYS_timer_create (SYS_BASE + 257)
4646
#define SYS_timer_settime (SYS_BASE + 258)
47+
#define SYS_timer_settime64 (SYS_BASE + 409)
4748
#define SYS_timer_delete (SYS_BASE + 261)
4849
#define SYS_pipe2 (SYS_BASE + 359)
4950
#define SYS_access (SYS_BASE + 33)
@@ -231,8 +232,8 @@ TEXT runtime·timer_create(SB),NOSPLIT,$0-16
231232
SWI $0
232233
MOVW R0, ret+12(FP)
233234
RET
234-
235-
TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
235+
// Linux: kernel/time/posix-timer.c, requiring COMPAT_32BIT_TIME.
236+
TEXT runtime·timer_settime32(SB),NOSPLIT,$0-20
236237
MOVW timerid+0(FP), R0
237238
MOVW flags+4(FP), R1
238239
MOVW new+8(FP), R2
@@ -242,6 +243,16 @@ TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
242243
MOVW R0, ret+16(FP)
243244
RET
244245

246+
TEXT runtime·timer_settime64(SB),NOSPLIT,$0-20
247+
MOVW timerid+0(FP), R0
248+
MOVW flags+4(FP), R1
249+
MOVW new+8(FP), R2
250+
MOVW old+12(FP), R3
251+
MOVW $SYS_timer_settime64, R7
252+
SWI $0
253+
MOVW R0, ret+16(FP)
254+
RET
255+
245256
TEXT runtime·timer_delete(SB),NOSPLIT,$0-8
246257
MOVW timerid+0(FP), R0
247258
MOVW $SYS_timer_delete, R7

src/runtime/sys_linux_mipsx.s

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#define SYS_exit_group 4246
4040
#define SYS_timer_create 4257
4141
#define SYS_timer_settime 4258
42+
#define SYS_timer_settime64 4409
4243
#define SYS_timer_delete 4261
4344
#define SYS_clock_gettime 4263
4445
#define SYS_tgkill 4266
@@ -197,7 +198,8 @@ TEXT runtime·timer_create(SB),NOSPLIT,$0-16
197198
MOVW R2, ret+12(FP)
198199
RET
199200

200-
TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
201+
// Linux: kernel/time/posix-timer.c, requiring COMPAT_32BIT_TIME
202+
TEXT runtime·timer_settime32(SB),NOSPLIT,$0-20
201203
MOVW timerid+0(FP), R4
202204
MOVW flags+4(FP), R5
203205
MOVW new+8(FP), R6
@@ -207,6 +209,16 @@ TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
207209
MOVW R2, ret+16(FP)
208210
RET
209211

212+
TEXT runtime·timer_settime64(SB),NOSPLIT,$0-20
213+
MOVW timerid+0(FP), R4
214+
MOVW flags+4(FP), R5
215+
MOVW new+8(FP), R6
216+
MOVW old+12(FP), R7
217+
MOVW $SYS_timer_settime64, R2
218+
SYSCALL
219+
MOVW R2, ret+16(FP)
220+
RET
221+
210222
TEXT runtime·timer_delete(SB),NOSPLIT,$0-8
211223
MOVW timerid+0(FP), R4
212224
MOVW $SYS_timer_delete, R2

0 commit comments

Comments
 (0)