package std import ( "encoding" "iter" "strconv" "sync" "syscall" ) // Syscalls returns an iterator over all wired syscalls. func Syscalls() iter.Seq2[string, ScmpSyscall] { return func(yield func(string, ScmpSyscall) bool) { for name, num := range syscallNum { if !yield(name, num) { return } } for name, num := range syscallNumExtra { if !yield(name, num) { return } } } } // SyscallResolveName resolves a syscall number from its string representation. func SyscallResolveName(name string) (num ScmpSyscall, ok bool) { if num, ok = syscallNum[name]; ok { return } num, ok = syscallNumExtra[name] return } // SchedPolicy denotes a scheduling policy defined in include/uapi/linux/sched.h. type SchedPolicy int // include/uapi/linux/sched.h const ( SCHED_NORMAL SchedPolicy = iota SCHED_FIFO SCHED_RR SCHED_BATCH _SCHED_ISO // SCHED_ISO: reserved but not implemented yet SCHED_IDLE SCHED_DEADLINE SCHED_EXT SCHED_LAST SchedPolicy = iota - 1 ) var _ encoding.TextMarshaler = SCHED_LAST var _ encoding.TextUnmarshaler = new(SCHED_LAST) // String returns a unique representation of policy, also used in encoding. func (policy SchedPolicy) String() string { switch policy { case SCHED_NORMAL: return "" case SCHED_FIFO: return "fifo" case SCHED_RR: return "rr" case SCHED_BATCH: return "batch" case SCHED_IDLE: return "idle" case SCHED_DEADLINE: return "deadline" case SCHED_EXT: return "ext" default: return "invalid policy " + strconv.Itoa(int(policy)) } } // MarshalText performs bounds checking and returns the result of String. func (policy SchedPolicy) MarshalText() ([]byte, error) { if policy == _SCHED_ISO || policy < 0 || policy > SCHED_LAST { return nil, syscall.EINVAL } return []byte(policy.String()), nil } // InvalidSchedPolicyError is an invalid string representation of a [SchedPolicy]. type InvalidSchedPolicyError string func (InvalidSchedPolicyError) Unwrap() error { return syscall.EINVAL } func (e InvalidSchedPolicyError) Error() string { return "invalid scheduling policy " + strconv.Quote(string(e)) } // UnmarshalText is the inverse of MarshalText. func (policy *SchedPolicy) UnmarshalText(text []byte) error { switch string(text) { case "fifo": *policy = SCHED_FIFO case "rr": *policy = SCHED_RR case "batch": *policy = SCHED_BATCH case "idle": *policy = SCHED_IDLE case "deadline": *policy = SCHED_DEADLINE case "ext": *policy = SCHED_EXT case "": *policy = 0 return nil default: return InvalidSchedPolicyError(text) } return nil } // for sched_get_priority_max and sched_get_priority_min var ( schedPriority [SCHED_LAST + 1][2]Int schedPriorityErr [SCHED_LAST + 1][2]error schedPriorityOnce [SCHED_LAST + 1][2]sync.Once ) // GetPriorityMax returns the maximum priority value that can be used with the // scheduling algorithm identified by policy. func (policy SchedPolicy) GetPriorityMax() (Int, error) { schedPriorityOnce[policy][0].Do(func() { priority, _, errno := syscall.Syscall( syscall.SYS_SCHED_GET_PRIORITY_MAX, uintptr(policy), 0, 0, ) schedPriority[policy][0] = Int(priority) if schedPriority[policy][0] < 0 { schedPriorityErr[policy][0] = errno } }) return schedPriority[policy][0], schedPriorityErr[policy][0] } // GetPriorityMin returns the minimum priority value that can be used with the // scheduling algorithm identified by policy. func (policy SchedPolicy) GetPriorityMin() (Int, error) { schedPriorityOnce[policy][1].Do(func() { priority, _, errno := syscall.Syscall( syscall.SYS_SCHED_GET_PRIORITY_MIN, uintptr(policy), 0, 0, ) schedPriority[policy][1] = Int(priority) if schedPriority[policy][1] < 0 { schedPriorityErr[policy][1] = errno } }) return schedPriority[policy][1], schedPriorityErr[policy][1] }