Record pthread routine address in clone(), keep helper threads on caller CPU core (workaround for Fugaku)
Change-Id: I29d1589e430dc1396558cdf3df4d068c27173612
This commit is contained in:
committed by
Masamichi Takagi
parent
97b107f61c
commit
3328ce03d9
@ -1,6 +1,7 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sched.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
@ -27,3 +28,110 @@ int sched_yield(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef pthread_create
|
||||
|
||||
typedef int (*__pthread_create_fn)(pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *),
|
||||
void *arg);
|
||||
|
||||
static __pthread_create_fn orig_pthread_create = 0;
|
||||
|
||||
|
||||
int pthread_create(pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *),
|
||||
void *arg)
|
||||
{
|
||||
if (!orig_pthread_create) {
|
||||
orig_pthread_create =
|
||||
(__pthread_create_fn)dlsym(RTLD_NEXT, "pthread_create");
|
||||
}
|
||||
|
||||
/* CLONE_VM and newsp == parent_tidptr impiles pthread start routine addr */
|
||||
syscall(__NR_clone, CLONE_VM, start_routine, start_routine, 0, 0, 0);
|
||||
|
||||
return orig_pthread_create(thread, attr, start_routine, arg);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define PROCMAPS_MAX_LEN 131072
|
||||
|
||||
char *addr_to_lib(void *addr, unsigned long *offset_in_lib)
|
||||
{
|
||||
char maps_path[PATH_MAX];
|
||||
char buf[PROCMAPS_MAX_LEN];
|
||||
int fd;
|
||||
void *start, *end;
|
||||
char perms[4];
|
||||
unsigned long offset;
|
||||
unsigned long dev[2];
|
||||
int inode;
|
||||
char path[PATH_MAX];
|
||||
char *line;
|
||||
|
||||
sprintf(maps_path,"/proc/self/maps");
|
||||
fd = open(maps_path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr,"error: cannot open the memory maps, %s\n",
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(buf, 0, PROCMAPS_MAX_LEN);
|
||||
read(fd, buf, PROCMAPS_MAX_LEN);
|
||||
line = strtok(buf, "\n");
|
||||
while (line) {
|
||||
memset(path, 0, sizeof(path));
|
||||
sscanf(line, "%012lx-%012lx %4s %lx %lx:%lx %d\t\t\t%[^\n]",
|
||||
&start, &end, perms, &offset, &dev[0], &dev[1], &inode, path);
|
||||
|
||||
if (start <= addr && end > addr) {
|
||||
close(fd);
|
||||
if (offset_in_lib)
|
||||
*offset_in_lib = (unsigned long)(addr - start);
|
||||
return strlen(path) > 0 ? strdup(path) : NULL;
|
||||
}
|
||||
|
||||
line = strtok(NULL, "\n");
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *),
|
||||
void *arg)
|
||||
{
|
||||
char *lib = NULL;
|
||||
int util_thread = 1;
|
||||
unsigned long offset;
|
||||
|
||||
if (!orig_pthread_create) {
|
||||
orig_pthread_create =
|
||||
(__pthread_create_fn)dlsym(RTLD_NEXT, "pthread_create");
|
||||
}
|
||||
|
||||
lib = addr_to_lib(start_routine, &offset);
|
||||
if (lib)
|
||||
printf("%s: 0x%lx is in %s @ 0x%lx\n",
|
||||
__func__, start_routine, lib, offset);
|
||||
|
||||
if (lib && (strstr(lib, "iomp") || strstr(lib, "psm"))) {
|
||||
util_thread = 0;
|
||||
}
|
||||
|
||||
if (util_thread) {
|
||||
/* McKernel util_indicate_clone() */
|
||||
syscall(731);
|
||||
}
|
||||
|
||||
if (lib)
|
||||
free(lib);
|
||||
|
||||
return orig_pthread_create(thread, attr, start_routine, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user