Skip to content
Draft
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
7 changes: 7 additions & 0 deletions echion/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ inline unsigned int max_fds = 16;
// Pipe name (where mode IPC)
inline std::string pipe_name;

// Which VM reading mode to use
// 1 - process_vm_readv (default)
// 2 - sigtrap
// -1 - error (cannot be set by user)
// else - writev (failover)
inline int vm_read_mode = 1;

// ----------------------------------------------------------------------------
static PyObject *
set_interval(PyObject *Py_UNUSED(m), PyObject *args)
Expand Down
1 change: 1 addition & 0 deletions echion/coremodule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ static PyMethodDef echion_core_methods[] = {
{"set_where", set_where, METH_VARARGS, "Set whether to use where mode"},
{"set_pipe_name", set_pipe_name, METH_VARARGS, "Set the pipe name"},
{"set_max_fds", set_max_fds, METH_VARARGS, "Set the maximum number of file descriptors to use"},
{"set_vm_read_mode", set_vm_read_mode, METH_VARARGS, "Set the virtual memory read mode"},
{NULL, NULL, 0, NULL} /* Sentinel */
};

Expand Down
91 changes: 6 additions & 85 deletions echion/threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,64 +28,6 @@
#include <echion/tasks.h>
#include <echion/timing.h>


#if defined PL_LINUX
#include <atomic>

class FileD8r
{
public:
using Ptr = std::unique_ptr<FileD8r>;

class Error : public std::exception
{
public:
const char *what() const noexcept override
{
return "Cannot create file descriptor object";
}
};

FileD8r(int fd) {
if (fd < 0)
throw Error();

if (fd_count >= max_fds) {
close(fd);

throw Error();
}

fd_count++;

fd_ = fd;
}

~FileD8r()
{
close(fd_);

fd_count--;
}

operator int() const { return fd_; }

private:
int fd_ = -1;

static std::atomic<int> fd_count;
};

std::atomic<int> FileD8r::fd_count = 0;

static inline int
open_proc_stat(unsigned long native_id) {
char buffer[64];
snprintf(buffer, sizeof(buffer), "/proc/self/task/%lu/stat", native_id);
return open(buffer, O_RDONLY);
}
#endif

class ThreadInfo
{
public:
Expand All @@ -107,7 +49,6 @@ class ThreadInfo

#if defined PL_LINUX
clockid_t cpu_clock_id;
FileD8r::Ptr stat_fd = nullptr;
#elif defined PL_DARWIN
mach_port_t mach_port;
#endif
Expand All @@ -126,12 +67,6 @@ class ThreadInfo
: thread_id(thread_id), native_id(native_id), name(name)
{
#if defined PL_LINUX
try {
stat_fd = std::make_unique<FileD8r>(open_proc_stat(native_id));
} catch (FileD8r::Error&) {
stat_fd = nullptr;
}

pthread_getcpuclockid((pthread_t)thread_id, &cpu_clock_id);
#elif defined PL_DARWIN
mach_port = pthread_mach_thread_np((pthread_t)thread_id);
Expand Down Expand Up @@ -166,30 +101,16 @@ void ThreadInfo::update_cpu_time()
bool ThreadInfo::is_running()
{
#if defined PL_LINUX
char buffer[2048];
int fd = (stat_fd != nullptr) ? ((int)*stat_fd) : open_proc_stat(native_id);

if (fd < 0)
return false;
struct timespec ts1, ts2;

auto result = pread(fd, buffer, sizeof(buffer), 0);

if (stat_fd == nullptr)
close(fd);

if (result <= 0) {
// Get two back-to-back times
if (clock_gettime(cpu_clock_id, &ts1) != 0)
return false;
}

char *p = strchr(buffer, ')');
if (p == NULL)
if (clock_gettime(cpu_clock_id, &ts2) != 0)
return false;

p += 2;
if (*p == ' ')
p++;

return (*p == 'R');
// If the CPU time has advanced, the thread is running
return (ts1.tv_sec != ts2.tv_sec || ts1.tv_nsec != ts2.tv_nsec);

#elif defined PL_DARWIN
thread_basic_info_data_t info;
Expand Down
Loading
Loading