diff options
Diffstat (limited to 'ext/syscall.go')
| -rw-r--r-- | ext/syscall.go | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/ext/syscall.go b/ext/syscall.go new file mode 100644 index 00000000..e6d9e9f2 --- /dev/null +++ b/ext/syscall.go @@ -0,0 +1,133 @@ +package ext + +import ( + "encoding" + "strconv" + "sync" + "syscall" +) + +// 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 errno != 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 errno != 0 { + schedPriorityErr[policy][1] = errno + } + }) + return schedPriority[policy][1], schedPriorityErr[policy][1] +} |
