Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPU_* macros #828

Merged
merged 8 commits into from
Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ if not no_headers
'options/internal/include/bits/sigset_t.h',
'options/internal/include/bits/inline-definition.h',
'options/internal/include/bits/ether_addr.h',
'options/internal/include/bits/cpu_set.h',
subdir: 'bits'
)
endif
Expand Down
13 changes: 13 additions & 0 deletions options/internal/include/bits/cpu_set.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef _MLIBC_INTERNAL_CPU_SET_H
#define _MLIBC_INTERNAL_CPU_SET_H

typedef unsigned long __cpu_mask;

#define CPU_SETSIZE 1024
#define __NCPUBITS (8 * sizeof(__cpu_mask))

typedef struct {
__cpu_mask __bits[CPU_SETSIZE / __NCPUBITS];
} cpu_set_t;

#endif /* _MLIBC_INTERNAL_CPU_SET_H */
71 changes: 71 additions & 0 deletions options/linux/generic/cpuset.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <limits.h>
#include <sched.h>
#include <stdlib.h>
#include <string.h>

cpu_set_t *__mlibc_cpu_alloc(int num_cpus) {
return reinterpret_cast<cpu_set_t *>(calloc(1, CPU_ALLOC_SIZE(num_cpus)));
}

#define CPU_MASK_BITS (CHAR_BIT * sizeof(__cpu_mask))

size_t __mlibc_cpu_alloc_size(int num_cpus) {
/* calculate the (unaligned) remainder that doesn't neatly fit in one __cpu_mask; 0 or 1 */
size_t remainder = ((num_cpus % CPU_MASK_BITS) + CPU_MASK_BITS - 1) / CPU_MASK_BITS;
return sizeof(__cpu_mask) * (num_cpus / CPU_MASK_BITS + remainder);
}

void __mlibc_cpu_zero(const size_t setsize, cpu_set_t *set) {
memset(set, 0, CPU_ALLOC_SIZE(setsize));
}

void __mlibc_cpu_set(const int cpu, const size_t setsize, cpu_set_t *set) {
if(cpu >= static_cast<int>(setsize * CHAR_BIT)) {
return;
}

unsigned char *ptr = reinterpret_cast<unsigned char *>(set);
size_t off = cpu / CHAR_BIT;
size_t mask = 1 << (cpu % CHAR_BIT);

ptr[off] |= mask;
}

void __mlibc_cpu_clear(const int cpu, const size_t setsize, cpu_set_t *set) {
if(cpu >= static_cast<int>(setsize * CHAR_BIT)) {
return;
}

unsigned char *ptr = reinterpret_cast<unsigned char *>(set);
size_t off = cpu / CHAR_BIT;
size_t mask = 1 << (cpu % CHAR_BIT);

ptr[off] &= ~mask;
}


int __mlibc_cpu_isset(const int cpu, const size_t setsize, const cpu_set_t *set) {
if(cpu >= static_cast<int>(setsize * CHAR_BIT)) {
return false;
}

const unsigned char *ptr = reinterpret_cast<const unsigned char *>(set);
size_t off = cpu / CHAR_BIT;
size_t mask = 1 << (cpu % CHAR_BIT);

return (ptr[off] & mask);
}

int __mlibc_cpu_count(const size_t setsize, const cpu_set_t *set) {
size_t count = 0;
const unsigned char *ptr = reinterpret_cast<const unsigned char *>(set);

for(size_t i = 0; i < setsize; i++) {
for(size_t bit = 0; bit < CHAR_BIT; bit++) {
if((1 << bit) & ptr[i])
count++;
}
}

return count;
}
29 changes: 29 additions & 0 deletions options/linux/generic/sched.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,32 @@ int setns(int, int) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

int sched_getscheduler(pid_t) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask) {
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getaffinity, -1);
if(int e = mlibc::sys_getaffinity(pid, cpusetsize, mask); e) {
errno = e;
return -1;
}
return 0;
}

int unshare(int) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

int sched_setaffinity(pid_t, size_t, const cpu_set_t *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

int clone(int (*)(void *), void *, int, void *, ...) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
45 changes: 45 additions & 0 deletions options/linux/include/bits/linux/cpu_set.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef _LINUX_CPU_SET_H
#define _LINUX_CPU_SET_H

#ifdef __cplusplus
extern "C" {
#endif

#include <bits/cpu_set.h>
#include <bits/size_t.h>
#include <limits.h>
#include <stdlib.h>

cpu_set_t *__mlibc_cpu_alloc(int num_cpus);
size_t __mlibc_cpu_alloc_size(int num_cpus);

void __mlibc_cpu_zero(const size_t setsize, cpu_set_t *set);
void __mlibc_cpu_set(const int cpu, const size_t setsize, cpu_set_t *set);
void __mlibc_cpu_clear(const int cpu, const size_t setsize, cpu_set_t *set);
int __mlibc_cpu_isset(const int cpu, const size_t setsize, const cpu_set_t *set);
int __mlibc_cpu_count(const size_t setsize, const cpu_set_t *set);

#define CPU_ALLOC_SIZE(n) __mlibc_cpu_alloc_size((n))
#define CPU_ALLOC(n) __mlibc_cpu_alloc((n))
#define CPU_FREE(set) free((set))

#define CPU_ZERO_S(setsize, set) __mlibc_cpu_zero((setsize), (set))
#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t), set)

#define CPU_SET_S(cpu, setsize, set) __mlibc_cpu_set((cpu), (setsize), (set))
#define CPU_SET(cpu, set) CPU_ZERO_S(cpu, sizeof(cpu_set_t), set)

#define CPU_CLR_S(cpu, setsize, set) __mlibc_cpu_clear((cpu), (setsize), (set))
#define CPU_CLR(cpu, set) CPU_CLR_S(cpu, sizeof(cpu_set_t), set)

#define CPU_ISSET_S(cpu, setsize, set) __mlibc_cpu_isset((cpu), (setsize), (set))
#define CPU_ISSET(cpu, set) CPU_ISSET_S(cpu, sizeof(cpu_set_t), set)

#define CPU_COUNT_S(setsize, set) __mlibc_cpu_count((setsize), (set))
#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t), set)

#ifdef __cplusplus
}
#endif

#endif /* _LINUX_CPU_SET_H */
43 changes: 43 additions & 0 deletions options/linux/include/bits/linux/linux_sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,54 @@
#ifndef _LINUX_SCHED_H
#define _LINUX_SCHED_H

#ifdef __cplusplus
extern "C" {
#endif

#include <abi-bits/pid_t.h>
#include <bits/size_t.h>
#include <bits/linux/cpu_set.h>

#define CLONE_VM 0x00000100
#define CLONE_FS 0x00000200
#define CLONE_FILES 0x00000400
#define CLONE_SIGHAND 0x00000800
#define CLONE_PTRACE 0x00002000
#define CLONE_VFORK 0x00004000
#define CLONE_PARENT 0x00008000
#define CLONE_THREAD 0x00010000
#define CLONE_NEWNS 0x00020000
#define CLONE_SYSVSEM 0x00040000
#define CLONE_SETTLS 0x00080000
#define CLONE_PARENT_SETTID 0x00100000
#define CLONE_CHILD_CLEARTID 0x00200000
#define CLONE_DETACHED 0x00400000
#define CLONE_UNTRACED 0x00800000
#define CLONE_CHILD_SETTID 0x01000000
#define CLONE_NEWCGROUP 0x02000000
#define CLONE_NEWUTS 0x04000000
#define CLONE_NEWIPC 0x08000000
#define CLONE_NEWUSER 0x10000000
#define CLONE_NEWPID 0x20000000
#define CLONE_NEWNET 0x40000000
#define CLONE_IO 0x80000000

int sched_getscheduler(pid_t pid);
int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask);
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);

int unshare(int flags);
int clone(int (*)(void *), void *, int, void *, ...);

/* Glibc extension */
int sched_getcpu(void);

#if defined(_GNU_SOURCE)
int setns(int fd, int nstype);
#endif /* _GNU_SOURCE */

#ifdef __cplusplus
}
#endif

#endif /* _LINUX_SCHED_H */
3 changes: 3 additions & 0 deletions options/linux/include/mlibc/linux-sysdeps.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef MLIBC_LINUX_SYSDEPS
#define MLIBC_LINUX_SYSDEPS

#include <sched.h>
#include <stdarg.h>
#include <sys/epoll.h>
#include <sys/sysinfo.h>
Expand Down Expand Up @@ -69,6 +70,8 @@ int sys_write(int fd, const void *buf, size_t count, ssize_t *bytes_written);
[[gnu::weak]] int sys_lremovexattr(const char *path, const char *name);
[[gnu::weak]] int sys_fremovexattr(int fd, const char *name);

[[gnu::weak]] int sys_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);

} // namespace mlibc

#endif // MLIBX_LINUX_SYSDEPS
2 changes: 2 additions & 0 deletions options/linux/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ libc_sources += files(
'generic/sys-klog.cpp',
'generic/sched.cpp',
'generic/sys-quota.cpp',
'generic/cpuset.cpp',
)

if not no_headers
Expand All @@ -46,6 +47,7 @@ if not no_headers
install_headers(
'include/bits/linux/linux_unistd.h',
'include/bits/linux/linux_sched.h',
'include/bits/linux/cpu_set.h',
subdir: 'bits/linux'
)
install_headers(
Expand Down
2 changes: 2 additions & 0 deletions options/posix/generic/pthread-stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ int pthread_attr_setschedpolicy(pthread_attr_t *__restrict attr, int policy) {
return 0;
}

#if __MLIBC_LINUX_OPTION
int pthread_attr_getaffinity_np(const pthread_attr_t *__restrict attr,
size_t cpusetsize, cpu_set_t *__restrict cpusetp) {
if (!attr)
Expand Down Expand Up @@ -316,6 +317,7 @@ int pthread_setaffinity_np(pthread_t, size_t, const cpu_set_t *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}
#endif // __MLIBC_LINUX_OPTION

extern "C" Tcb *__rtdl_allocateTcb();

Expand Down
48 changes: 0 additions & 48 deletions options/posix/generic/sched-stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@ int sched_yield(void) {
return 0;
}

int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask) {
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getaffinity, -1);
if(int e = mlibc::sys_getaffinity(pid, cpusetsize, mask); e) {
errno = e;
return -1;
}
return 0;
}

int sched_get_priority_max(int) {
__ensure(!"Not implemented");
__builtin_unreachable();
Expand All @@ -42,50 +33,11 @@ int sched_get_priority_min(int policy) {
return res;
}

int __mlibc_cpu_isset(int, cpu_set_t *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

int __mlibc_cpu_count(const cpu_set_t *set) {
size_t count = 0;
const unsigned char *ptr = reinterpret_cast<const unsigned char *>(set);

for(size_t i = 0; i < sizeof(cpu_set_t); i++) {
for(size_t bit = 0; bit < CHAR_BIT; bit++) {
if((1 << bit) & ptr[i])
count++;
}
}

return count;
}

int unshare(int) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

int clone(int (*)(void *), void *, int, void *, ...) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

int sched_setscheduler(pid_t, int, const struct sched_param *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

int sched_setaffinity(pid_t, size_t, const cpu_set_t *) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

int sched_getscheduler(pid_t) {
__ensure(!"Not implemented");
__builtin_unreachable();
}

int sched_getparam(pid_t, struct sched_param *) {
__ensure(!"Not implemented");
__builtin_unreachable();
Expand Down
1 change: 0 additions & 1 deletion options/posix/include/mlibc/posix-sysdeps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ int sys_close(int fd);
[[gnu::weak]] int sys_setegid(gid_t egid);
[[gnu::weak]] int sys_getgroups(size_t size, const gid_t *list, int *ret);
[[gnu::weak]] void sys_yield();
[[gnu::weak]] int sys_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
[[gnu::weak]] int sys_sleep(time_t *secs, long *nanos);
[[gnu::weak]] int sys_fork(pid_t *child);
[[gnu::weak]] int sys_clone(void *tcb, pid_t *pid_out, void *stack);
Expand Down
3 changes: 3 additions & 0 deletions options/posix/include/pthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#define _PTHREAD_H

#include <abi-bits/clockid_t.h>
#include <bits/cpu_set.h>
// TODO: pthread is not required to define size_t.
#include <bits/size_t.h>
#include <bits/posix/pthread_t.h>
Expand Down Expand Up @@ -194,6 +195,7 @@ int pthread_attr_setinheritsched(pthread_attr_t *__restrict, int);
int pthread_attr_getschedparam(const pthread_attr_t *__restrict, struct sched_param *__restrict);
int pthread_attr_setschedparam(pthread_attr_t *__restrict, const struct sched_param *__restrict);

#if __MLIBC_LINUX_OPTION
int pthread_attr_getaffinity_np(const pthread_attr_t *__restrict, size_t, cpu_set_t *__restrict);
int pthread_attr_setaffinity_np(pthread_attr_t *__restrict, size_t, const cpu_set_t *__restrict);

Expand All @@ -204,6 +206,7 @@ int pthread_getattr_np(pthread_t, pthread_attr_t *);

int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);
int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);
#endif /* __MLIBC_LINUX_OPTION */

// pthread functions.
int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict,
Expand Down
Loading