Skip to content

Commit

Permalink
Merge pull request #828 from no92/cpu-memes
Browse files Browse the repository at this point in the history
  • Loading branch information
Dennisbonke authored Apr 5, 2023
2 parents 10aae9c + 38af3c8 commit 2e4cccd
Show file tree
Hide file tree
Showing 17 changed files with 336 additions and 170 deletions.
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

0 comments on commit 2e4cccd

Please sign in to comment.