Ai
21 Star 49 Fork 0

Gitee 极速下载/julia-language

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/JuliaLang/julia
克隆/下载
sys.c 22.59 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
// This file is a part of Julia. License is MIT: https://julialang.org/license
/*
sys.c
I/O and operating system utility functions
*/
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include "julia.h"
#include "julia_internal.h"
#ifdef _OS_WINDOWS_
#include <psapi.h>
#else
#include <unistd.h>
#if !defined(_SC_NPROCESSORS_ONLN) || defined(_OS_FREEBSD_) || defined(_OS_DARWIN_)
// try secondary location for _SC_NPROCESSORS_ONLN, or for HW_AVAILCPU on BSDs
#include <sys/sysctl.h>
#endif
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <grp.h>
// For `struct termios`
#include <termios.h>
#endif
#ifndef _OS_WINDOWS_
// for getrusage
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#endif
#ifdef __APPLE__
#include <mach-o/dyld.h>
#include <mach-o/nlist.h>
#include <sys/types.h> // for jl_raise_debugger
#elif !defined(_OS_WINDOWS_)
#include <link.h>
#endif
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#ifdef _COMPILER_MSAN_ENABLED_
#include <sanitizer/msan_interface.h>
#endif
#include "julia_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
JL_DLLEXPORT int jl_sizeof_off_t(void) { return sizeof(off_t); }
#ifndef _OS_WINDOWS_
JL_DLLEXPORT int jl_sizeof_mode_t(void) { return sizeof(mode_t); }
JL_DLLEXPORT int jl_ftruncate(int fd, int64_t length)
{
return ftruncate(fd, (off_t)length);
}
JL_DLLEXPORT int64_t jl_lseek(int fd, int64_t offset, int whence)
{
return lseek(fd, (off_t)offset, whence);
}
JL_DLLEXPORT ssize_t jl_pwrite(int fd, const void *buf, size_t count, int64_t offset)
{
return pwrite(fd, buf, count, (off_t)offset);
}
JL_DLLEXPORT void *jl_mmap(void *addr, size_t length, int prot, int flags,
int fd, int64_t offset)
{
return mmap(addr, length, prot, flags, fd, (off_t)offset);
}
#else
JL_DLLEXPORT int64_t jl_lseek(HANDLE fd, int64_t offset, int whence)
{
LARGE_INTEGER tell;
tell.QuadPart = offset;
if (SetFilePointerEx(fd, tell, &tell, whence) == 0)
return -1;
return tell.QuadPart;
}
#endif
JL_DLLEXPORT int jl_sizeof_ios_t(void) { return sizeof(ios_t); }
JL_DLLEXPORT long jl_ios_fd(ios_t *s) { return s->fd; }
JL_DLLEXPORT int32_t jl_nb_available(ios_t *s)
{
return (int32_t)(s->size - s->bpos);
}
// --- dir/file stuff ---
JL_DLLEXPORT char *jl_uv_fs_t_ptr(uv_fs_t *req) { return (char*)req->ptr; }
JL_DLLEXPORT char *jl_uv_fs_t_path(uv_fs_t *req) { return (char*)req->path; }
// --- stat ---
JL_DLLEXPORT int jl_sizeof_stat(void) { return sizeof(uv_stat_t); }
JL_DLLEXPORT int32_t jl_stat(const char *path, char *statbuf) JL_NOTSAFEPOINT
{
uv_fs_t req;
int ret;
// Ideally one would use the statbuf for the storage in req, but
// it's not clear that this is possible using libuv
ret = uv_fs_stat(unused_uv_loop_arg, &req, path, NULL);
if (ret == 0)
memcpy(statbuf, req.ptr, sizeof(uv_stat_t));
uv_fs_req_cleanup(&req);
return ret;
}
JL_DLLEXPORT int32_t jl_lstat(const char *path, char *statbuf)
{
uv_fs_t req;
int ret;
ret = uv_fs_lstat(unused_uv_loop_arg, &req, path, NULL);
if (ret == 0)
memcpy(statbuf, req.ptr, sizeof(uv_stat_t));
uv_fs_req_cleanup(&req);
return ret;
}
JL_DLLEXPORT int32_t jl_fstat(uv_os_fd_t fd, char *statbuf)
{
uv_fs_t req;
int ret;
ret = uv_fs_fstat(unused_uv_loop_arg, &req, fd, NULL);
if (ret == 0)
memcpy(statbuf, req.ptr, sizeof(uv_stat_t));
uv_fs_req_cleanup(&req);
return ret;
}
JL_DLLEXPORT unsigned int jl_stat_dev(char *statbuf)
{
return ((uv_stat_t*)statbuf)->st_dev;
}
JL_DLLEXPORT unsigned int jl_stat_ino(char *statbuf)
{
return ((uv_stat_t*)statbuf)->st_ino;
}
JL_DLLEXPORT unsigned int jl_stat_mode(char *statbuf)
{
return ((uv_stat_t*)statbuf)->st_mode;
}
JL_DLLEXPORT unsigned int jl_stat_nlink(char *statbuf)
{
return ((uv_stat_t*)statbuf)->st_nlink;
}
JL_DLLEXPORT unsigned int jl_stat_uid(char *statbuf)
{
return ((uv_stat_t*)statbuf)->st_uid;
}
JL_DLLEXPORT unsigned int jl_stat_gid(char *statbuf)
{
return ((uv_stat_t*)statbuf)->st_gid;
}
JL_DLLEXPORT unsigned int jl_stat_rdev(char *statbuf)
{
return ((uv_stat_t*)statbuf)->st_rdev;
}
JL_DLLEXPORT uint64_t jl_stat_size(char *statbuf)
{
return ((uv_stat_t*)statbuf)->st_size;
}
JL_DLLEXPORT uint64_t jl_stat_blksize(char *statbuf)
{
return ((uv_stat_t*)statbuf)->st_blksize;
}
JL_DLLEXPORT uint64_t jl_stat_blocks(char *statbuf)
{
return ((uv_stat_t*)statbuf)->st_blocks;
}
/*
// atime is stupid, let's not support it
JL_DLLEXPORT double jl_stat_atime(char *statbuf)
{
uv_stat_t *s;
s = (uv_stat_t*)statbuf;
return (double)s->st_atim.tv_sec + (double)s->st_atim.tv_nsec * 1e-9;
}
*/
JL_DLLEXPORT double jl_stat_mtime(char *statbuf)
{
uv_stat_t *s;
s = (uv_stat_t*)statbuf;
return (double)s->st_mtim.tv_sec + (double)s->st_mtim.tv_nsec * 1e-9;
}
JL_DLLEXPORT double jl_stat_ctime(char *statbuf)
{
uv_stat_t *s;
s = (uv_stat_t*)statbuf;
return (double)s->st_ctim.tv_sec + (double)s->st_ctim.tv_nsec * 1e-9;
}
JL_DLLEXPORT unsigned long jl_getuid(void)
{
#ifdef _OS_WINDOWS_
return -1;
#else
return getuid();
#endif
}
JL_DLLEXPORT unsigned long jl_geteuid(void)
{
#ifdef _OS_WINDOWS_
return -1;
#else
return geteuid();
#endif
}
// --- buffer manipulation ---
JL_DLLEXPORT jl_array_t *jl_take_buffer(ios_t *s)
{
size_t n;
jl_array_t *a;
if (s->buf == &s->local[0]) {
// small data case. copies, but this can be avoided using the
// technique of jl_readuntil below.
a = jl_pchar_to_array(s->buf, s->size);
ios_trunc(s, 0);
}
else {
char *b = ios_take_buffer(s, &n);
a = jl_ptr_to_array_1d(jl_array_uint8_type, b, n-1, 1);
}
return a;
}
// str: if 1 return a string, otherwise return a Vector{UInt8}
// chomp:
// 0 - keep delimiter
// 1 - remove 1 byte delimiter
// 2 - remove 2 bytes \r\n if present
JL_DLLEXPORT jl_value_t *jl_readuntil(ios_t *s, uint8_t delim, uint8_t str, uint8_t chomp)
{
jl_array_t *a;
// manually inlined common case
char *pd = (char*)memchr(s->buf + s->bpos, delim, (size_t)(s->size - s->bpos));
if (pd) {
size_t n = pd - (s->buf + s->bpos) + 1;
size_t nchomp = 0;
if (chomp) {
nchomp = chomp == 2 ? ios_nchomp(s, n) : 1;
}
if (str) {
jl_value_t *str = jl_pchar_to_string(s->buf + s->bpos, n - nchomp);
s->bpos += n;
return str;
}
a = jl_alloc_array_1d(jl_array_uint8_type, n - nchomp);
memcpy(jl_array_data(a, uint8_t), s->buf + s->bpos, n - nchomp);
s->bpos += n;
}
else {
a = jl_alloc_array_1d(jl_array_uint8_type, 80);
ios_t dest;
ios_mem(&dest, 0);
char *mem = jl_array_data(a, char);
ios_setbuf(&dest, (char*)mem, 80, 0);
size_t n = ios_copyuntil(&dest, s, delim, 1);
if (chomp && n > 0 && dest.buf[n - 1] == delim) {
n--;
if (chomp == 2 && n > 0 && dest.buf[n - 1] == '\r') {
n--;
}
int truncret = ios_trunc(&dest, n); // it should always be possible to truncate dest
assert(truncret == 0);
(void)truncret; // ensure the variable is used to avoid warnings
}
if (dest.buf != mem) {
a = jl_take_buffer(&dest);
}
else {
a->dimsize[0] = n;
}
if (str) {
JL_GC_PUSH1(&a);
jl_value_t *st = jl_array_to_string(a);
JL_GC_POP();
return st;
}
}
return (jl_value_t*)a;
}
// read up to buflen bytes, including delim, into buf. returns number of bytes read.
JL_DLLEXPORT size_t jl_readuntil_buf(ios_t *s, uint8_t delim, uint8_t *buf, size_t buflen)
{
// manually inlined common case
size_t avail = (size_t)(s->size - s->bpos);
if (avail > buflen) avail = buflen;
char *pd = (char*)memchr(s->buf + s->bpos, delim, avail);
if (pd) {
size_t n = pd - (s->buf + s->bpos) + 1;
memcpy(buf, s->buf + s->bpos, n);
s->bpos += n;
return n;
}
else {
size_t total = avail;
memcpy(buf, s->buf + s->bpos, avail);
s->bpos += avail;
if (avail == buflen) return total;
// code derived from ios_copyuntil
while (!ios_eof(s)) {
avail = ios_readprep(s, 160); // read LINE_CHUNK_SIZE
if (avail == 0) break;
if (total+avail > buflen) avail = buflen-total;
char *pd = (char*)memchr(s->buf+s->bpos, delim, avail);
if (pd == NULL) {
memcpy(buf+total, s->buf+s->bpos, avail);
s->bpos += avail;
total += avail;
if (buflen == total) return total;
}
else {
size_t ntowrite = pd - (s->buf+s->bpos) + 1;
memcpy(buf+total, s->buf+s->bpos, ntowrite);
s->bpos += ntowrite;
total += ntowrite;
return total;
}
}
s->_eof = 1;
return total;
}
}
JL_DLLEXPORT int jl_ios_buffer_n(ios_t *s, const size_t n)
{
size_t space, ret;
do {
space = (size_t)(s->size - s->bpos);
ret = ios_readprep(s, n);
if (space == ret && ret < n)
return 1;
} while (ret < n);
return 0;
}
JL_DLLEXPORT uint64_t jl_ios_get_nbyte_int(ios_t *s, const size_t n)
{
assert(n <= 8);
uint64_t x = 0;
uint8_t *buf = (uint8_t*)&s->buf[s->bpos];
if (n == 8) {
// expecting loop unrolling optimization
for (size_t i = 0; i < 8; i++)
x |= (uint64_t)buf[i] << (i << 3);
}
else if (n >= 4) {
// expecting loop unrolling optimization
for (size_t i = 0; i < 4; i++)
x |= (uint64_t)buf[i] << (i << 3);
for (size_t i = 4; i < n; i++)
x |= (uint64_t)buf[i] << (i << 3);
}
else {
for (size_t i = 0; i < n; i++)
x |= (uint64_t)buf[i] << (i << 3);
}
s->bpos += n;
return x;
}
// -- syscall utilities --
JL_DLLEXPORT int jl_errno(void) JL_NOTSAFEPOINT { return errno; }
JL_DLLEXPORT void jl_set_errno(int e) JL_NOTSAFEPOINT { errno = e; }
// -- get the number of CPU threads (logical cores) --
#ifdef _OS_WINDOWS_
typedef DWORD (WINAPI *GAPC)(WORD);
#ifndef ALL_PROCESSOR_GROUPS
#define ALL_PROCESSOR_GROUPS 0xffff
#endif
#endif
// Apple's M1 processor is a big.LITTLE style processor, with 4x "performance"
// cores, and 4x "efficiency" cores. Because Julia expects to be able to run
// things like heavy linear algebra workloads on all cores, it's best for us
// to only spawn as many threads as there are performance cores. Once macOS
// 12 is released, we'll be able to query the multiple "perf levels" of the
// cores of a CPU (see this PR [0] to pytorch/cpuinfo for an example) but
// until it's released, we will just recognize the M1 by its CPU family
// identifier, then subtract how many efficiency cores we know it has.
JL_DLLEXPORT int jl_cpu_threads(void) JL_NOTSAFEPOINT
{
#if defined(HW_AVAILCPU) && defined(HW_NCPU)
size_t len = 4;
int32_t count;
int nm[2] = {CTL_HW, HW_AVAILCPU};
sysctl(nm, 2, &count, &len, NULL, 0);
if (count < 1) {
nm[1] = HW_NCPU;
sysctl(nm, 2, &count, &len, NULL, 0);
if (count < 1) { count = 1; }
}
#if defined(__APPLE__) && defined(_CPU_AARCH64_)
//MacOS 12 added a way to query performance cores
char buf[7];
len = 7;
sysctlbyname("kern.osrelease", buf, &len, NULL, 0);
if (buf[0] > 1 && buf[1] > 0){
len = 4;
sysctlbyname("hw.perflevel0.physicalcpu", &count, &len, NULL, 0);
}
else {
int32_t family = 0;
len = 4;
sysctlbyname("hw.cpufamily", &family, &len, NULL, 0);
if (family >= 1 && count > 1) {
if (family == CPUFAMILY_ARM_FIRESTORM_ICESTORM) {
// We know the Apple M1 has 4 efficiency cores, so subtract them out.
count -= 4;
}
}
}
#endif
return count;
#elif defined(_SC_NPROCESSORS_ONLN)
long count = sysconf(_SC_NPROCESSORS_ONLN);
if (count < 1)
return 1;
return count;
#elif defined(_OS_WINDOWS_)
//Try to get WIN7 API method
GAPC gapc;
if (jl_dlsym(jl_kernel32_handle, "GetActiveProcessorCount", (void **)&gapc, 0, 0)) {
return gapc(ALL_PROCESSOR_GROUPS);
}
else { //fall back on GetSystemInfo
SYSTEM_INFO info;
GetSystemInfo(&info);
return info.dwNumberOfProcessors;
}
#else
#warning "cpu core detection not defined for this platform"
return 1;
#endif
}
JL_DLLEXPORT int jl_effective_threads(void) JL_NOTSAFEPOINT
{
// We want the more conservative estimate of the two.
int cpu_threads = jl_cpu_threads();
int available_parallelism = uv_available_parallelism();
return available_parallelism < cpu_threads ? available_parallelism : cpu_threads;
}
// -- high resolution timers --
// Returns time in nanosec
JL_DLLEXPORT uint64_t jl_hrtime(void) JL_NOTSAFEPOINT
{
return uv_hrtime();
}
// -- iterating the environment --
#ifdef __APPLE__
#include <crt_externs.h>
#else
#if !defined(_OS_WINDOWS_) || (defined(_COMPILER_GCC_) && defined(_POSIX_C_SOURCE))
extern JL_DLLIMPORT char **environ;
#endif
#endif
JL_DLLEXPORT jl_value_t *jl_environ(int i)
{
#ifdef __APPLE__
char **environ = *_NSGetEnviron();
#endif
char *env = environ[i];
return env ? jl_pchar_to_string(env, strlen(env)) : jl_nothing;
}
// -- child process status --
#if defined _OS_WINDOWS_
/* Native Woe32 API. */
#include <process.h>
#define waitpid(pid,statusp,options) _cwait (statusp, pid, WAIT_CHILD)
#define WAIT_T int
#define WTERMSIG(x) ((x) & 0xff) /* or: SIGABRT ?? */
#define WCOREDUMP(x) 0
#define WEXITSTATUS(x) (((x) >> 8) & 0xff) /* or: (x) ?? */
#define WIFSIGNALED(x) (WTERMSIG (x) != 0) /* or: ((x) == 3) ?? */
#define WIFEXITED(x) (WTERMSIG (x) == 0) /* or: ((x) != 3) ?? */
#define WIFSTOPPED(x) 0
#define WSTOPSIG(x) 0 //Is this correct?
#endif
int jl_process_exited(int status) { return WIFEXITED(status); }
int jl_process_signaled(int status) { return WIFSIGNALED(status); }
int jl_process_stopped(int status) { return WIFSTOPPED(status); }
int jl_process_exit_status(int status) { return WEXITSTATUS(status); }
int jl_process_term_signal(int status) { return WTERMSIG(status); }
int jl_process_stop_signal(int status) { return WSTOPSIG(status); }
// -- access to std filehandles --
JL_STREAM *JL_STDIN = (JL_STREAM*)STDIN_FILENO;
JL_STREAM *JL_STDOUT = (JL_STREAM*)STDOUT_FILENO;
JL_STREAM *JL_STDERR = (JL_STREAM*)STDERR_FILENO;
JL_DLLEXPORT JL_STREAM *jl_stdin_stream(void) { return JL_STDIN; }
JL_DLLEXPORT JL_STREAM *jl_stdout_stream(void) { return JL_STDOUT; }
JL_DLLEXPORT JL_STREAM *jl_stderr_stream(void) { return JL_STDERR; }
JL_DLLEXPORT int jl_termios_size(void) {
#if defined(_OS_WINDOWS_)
return 0;
#else
return sizeof(struct termios);
#endif
}
// -- processor native alignment information --
JL_DLLEXPORT void jl_native_alignment(uint_t *int8align, uint_t *int16align, uint_t *int32align,
uint_t *int64align, uint_t *float32align, uint_t *float64align)
{
*int8align = __alignof(uint8_t);
*int16align = __alignof(uint16_t);
*int32align = __alignof(uint32_t);
*int64align = __alignof(uint64_t);
*float32align = __alignof(float);
*float64align = __alignof(double);
}
JL_DLLEXPORT jl_value_t *jl_is_char_signed(void)
{
return ((char)255) < 0 ? jl_true : jl_false;
}
// -- misc sysconf info --
#ifdef _OS_WINDOWS_
static long cachedPagesize = 0;
JL_DLLEXPORT long jl_getpagesize(void)
{
if (!cachedPagesize) {
SYSTEM_INFO systemInfo;
GetSystemInfo (&systemInfo);
cachedPagesize = systemInfo.dwPageSize;
}
return cachedPagesize;
}
#else
JL_DLLEXPORT long jl_getpagesize(void)
{
long page_size = sysconf(_SC_PAGESIZE);
assert(page_size != -1);
return page_size;
}
#endif
#ifdef _OS_WINDOWS_
static long cachedAllocationGranularity = 0;
JL_DLLEXPORT long jl_getallocationgranularity(void) JL_NOTSAFEPOINT
{
if (!cachedAllocationGranularity) {
SYSTEM_INFO systemInfo;
GetSystemInfo (&systemInfo);
cachedAllocationGranularity = systemInfo.dwAllocationGranularity;
}
return cachedAllocationGranularity;
}
#else
JL_DLLEXPORT long jl_getallocationgranularity(void) JL_NOTSAFEPOINT
{
return jl_getpagesize();
}
#endif
JL_DLLEXPORT long jl_gethugepagesize(void) JL_NOTSAFEPOINT
{
#if defined(_OS_LINUX_)
long detected = 0;
FILE *f = fopen("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", "r");
if (f) {
unsigned long long size = 0;
if (fscanf(f, "%llu", &size) == 1 && size > 0) {
detected = (long)size;
}
fclose(f);
}
if (detected == 0) {
f = fopen("/proc/meminfo", "r");
if (f) {
char line[256];
while (fgets(line, sizeof(line), f)) {
unsigned long long kb = 0;
if (sscanf(line, "Hugepagesize:%llu kB", &kb) == 1 && kb > 0) {
detected = (long)(kb * 1024ULL);
break;
}
}
fclose(f);
}
}
if (detected == 0) {
detected = 2 * 1024 * 1024; // 2 MiB fallback
}
return detected;
#else
return 0;
#endif
}
JL_DLLEXPORT long jl_SC_CLK_TCK(void)
{
#ifndef _OS_WINDOWS_
return sysconf(_SC_CLK_TCK);
#else
return 1000; /* uv_cpu_info returns times in ms on Windows */
#endif
}
#ifdef _OS_OPENBSD_
// Helper for jl_pathname_for_handle()
struct dlinfo_data {
void *searched;
const char *result;
};
static int dlinfo_helper(struct dl_phdr_info *info, size_t size, void *vdata)
{
struct dlinfo_data *data = (struct dlinfo_data *)vdata;
void *handle;
/* ensure dl_phdr_info at compile-time to be compatible with the one at runtime */
if (sizeof(*info) < size)
return -1;
/* dlopen the name */
handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD);
if (handle == NULL)
return 0;
/* check if the opened library is the same as the searched handle */
if (data->searched == handle)
data->result = info->dlpi_name;
dlclose(handle);
/* continue if still not found */
return (data->result != NULL);
}
#endif
// Takes a handle (as returned from dlopen()) and returns the absolute path to the image loaded
JL_DLLEXPORT const char *jl_pathname_for_handle(void *handle)
{
if (!handle)
return NULL;
#ifdef __APPLE__
// Iterate through all images currently in memory
for (int32_t i = _dyld_image_count() - 1; i >= 0 ; i--) {
// dlopen() each image, check handle
const char *image_name = _dyld_get_image_name(i);
void *probe_lib = jl_load_dynamic_library(image_name, JL_RTLD_DEFAULT | JL_RTLD_NOLOAD, 0);
jl_dlclose(probe_lib);
// If the handle is the same as what was passed in (modulo mode bits), return this image name
if (((intptr_t)handle & (-4)) == ((intptr_t)probe_lib & (-4)))
return image_name;
}
#elif defined(_OS_WINDOWS_)
wchar_t *pth16 = (wchar_t*)malloc_s(32768 * sizeof(*pth16)); // max long path length
DWORD n16 = GetModuleFileNameW((HMODULE)handle, pth16, 32768);
if (n16 <= 0) {
free(pth16);
return NULL;
}
pth16[n16] = L'\0';
DWORD n8 = WideCharToMultiByte(CP_UTF8, 0, pth16, -1, NULL, 0, NULL, NULL);
if (n8 == 0) {
free(pth16);
return NULL;
}
char *filepath = (char*)malloc_s(++n8);
if (!WideCharToMultiByte(CP_UTF8, 0, pth16, -1, filepath, n8, NULL, NULL)) {
free(pth16);
free(filepath);
return NULL;
}
free(pth16);
return filepath;
#elif defined(_OS_OPENBSD_)
struct dlinfo_data data = {
.searched = handle,
.result = NULL,
};
dl_iterate_phdr(&dlinfo_helper, &data);
return data.result;
#else // Linux, FreeBSD, ...
struct link_map *map;
dlinfo(handle, RTLD_DI_LINKMAP, &map);
#ifdef _COMPILER_MSAN_ENABLED_
__msan_unpoison(&map,sizeof(struct link_map*));
if (map) {
__msan_unpoison(map, sizeof(struct link_map));
__msan_unpoison_string(map->l_name);
}
#endif
if (map)
return map->l_name;
#endif
return NULL;
}
#ifdef _OS_WINDOWS_
// Get a list of all the modules in this process.
JL_DLLEXPORT int jl_dllist(jl_array_t *list)
{
DWORD cb, cbNeeded;
HMODULE *hMods = NULL;
unsigned int i;
cbNeeded = 1024 * sizeof(*hMods);
do {
cb = cbNeeded;
hMods = (HMODULE*)realloc_s(hMods, cb);
if (!EnumProcessModulesEx(GetCurrentProcess(), hMods, cb, &cbNeeded, LIST_MODULES_ALL)) {
free(hMods);
return FALSE;
}
} while (cb < cbNeeded);
for (i = 0; i < cbNeeded / sizeof(HMODULE); i++) {
const char *path = jl_pathname_for_handle(hMods[i]);
if (path == NULL)
continue;
jl_array_grow_end((jl_array_t*)list, 1);
jl_value_t *v = jl_cstr_to_string(path);
free((char*)path);
jl_array_ptr_set(list, jl_array_dim0(list) - 1, v);
}
free(hMods);
return TRUE;
}
#endif
JL_DLLEXPORT void jl_raise_debugger(void)
{
#if defined(_OS_WINDOWS_)
if (IsDebuggerPresent() == 1)
DebugBreak();
#else
raise(SIGTRAP);
#endif // _OS_WINDOWS_
}
JL_DLLEXPORT jl_sym_t *jl_get_UNAME(void) JL_NOTSAFEPOINT
{
return jl_symbol(JL_BUILD_UNAME);
}
JL_DLLEXPORT jl_sym_t *jl_get_ARCH(void) JL_NOTSAFEPOINT
{
return jl_symbol(JL_BUILD_ARCH);
}
JL_DLLEXPORT size_t jl_maxrss(void)
{
uv_rusage_t rusage;
if (uv_getrusage(&rusage) == 0) {
return rusage.ru_maxrss * 1024;
}
return 0;
}
// Simple `rand()` like function, with global seed and added thread-safety
// (but slow and insecure)
static _Atomic(uint64_t) g_rngseed;
JL_DLLEXPORT uint64_t jl_rand(void) JL_NOTSAFEPOINT
{
uint64_t max = UINT64_MAX;
uint64_t rngseed0 = jl_atomic_load_relaxed(&g_rngseed);
uint64_t rngseed;
uint64_t rnd;
do {
rngseed = rngseed0;
rnd = cong(max, &rngseed);
} while (!jl_atomic_cmpswap_relaxed(&g_rngseed, &rngseed0, rngseed));
return rnd;
}
JL_DLLEXPORT void jl_srand(uint64_t rngseed) JL_NOTSAFEPOINT
{
jl_atomic_store_relaxed(&g_rngseed, rngseed);
}
void jl_init_rand(void) JL_NOTSAFEPOINT
{
uint64_t rngseed;
if (uv_random(NULL, NULL, &rngseed, sizeof(rngseed), 0, NULL)) {
ios_puts("WARNING: Entropy pool not available to seed RNG; using ad-hoc entropy sources.\n", ios_stderr);
rngseed = uv_hrtime();
rngseed ^= int64hash(uv_os_getpid());
}
jl_srand(rngseed);
srand(rngseed);
}
#ifdef __cplusplus
}
#endif
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/mirrors/julia-language.git
git@gitee.com:mirrors/julia-language.git
mirrors
julia-language
julia-language
master

搜索帮助