Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
use dynamic memory allocation
Browse files Browse the repository at this point in the history
  • Loading branch information
rahul committed Mar 22, 2017
1 parent 391e8d3 commit b24a9a1
Show file tree
Hide file tree
Showing 3 changed files with 217 additions and 107 deletions.
165 changes: 106 additions & 59 deletions src/gc/unix/cgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,73 +21,103 @@ Module Name:
#include <sys/resource.h>
#include <errno.h>

#define MAX_PATH 1024
#define SIZE_T_MAX (~(size_t)0)
#define PROC_MOUNTINFO_FILENAME "/proc/self/mountinfo"
#define PROC_CGROUP_FILENAME "/proc/self/cgroup"
#define PROC_STATM_FILENAME "/proc/self/statm"
#define MEM_LIMIT_FILENAME "/memory.limit_in_bytes"
#define _countof(_array) (sizeof(_array)/sizeof(_array[0]))

class CGroup
{
char m_memory_cgroup_path[MAX_PATH];
char* m_memory_cgroup_path;
public:
CGroup()
{
if (!FindMemoryHierarchyMount(m_memory_cgroup_path, MAX_PATH))
{
m_memory_cgroup_path[0] = '\0';
return;
}
char cgroup_path_relative_to_mount[MAX_PATH];
if (!FindCGroupPathForMemorySubsystem(cgroup_path_relative_to_mount, MAX_PATH))
{
m_memory_cgroup_path[0] = '\0';
return;
}
strncat(m_memory_cgroup_path, cgroup_path_relative_to_mount,
MAX_PATH-strlen(m_memory_cgroup_path)-1);
m_memory_cgroup_path = nullptr;
char* memoryHierarchyMount = nullptr;
char *cgroup_path_relative_to_mount = nullptr;
size_t len;
memoryHierarchyMount = FindMemoryHierarchyMount();
if (memoryHierarchyMount == nullptr)
goto done;

cgroup_path_relative_to_mount = FindCGroupPathForMemorySubsystem();
if (cgroup_path_relative_to_mount == nullptr)
goto done;

len = strlen(memoryHierarchyMount);
len += strlen(cgroup_path_relative_to_mount);
m_memory_cgroup_path = (char*)malloc(len+1);
if (m_memory_cgroup_path == nullptr)
goto done;

strcpy(m_memory_cgroup_path, memoryHierarchyMount);
strcat(m_memory_cgroup_path, cgroup_path_relative_to_mount);

done:
free(memoryHierarchyMount);
free(cgroup_path_relative_to_mount);
}


~CGroup()
{
free(m_memory_cgroup_path);
}

bool GetPhysicalMemoryLimit(size_t *val)
{
char mem_limit_filename[MAX_PATH];

if (m_memory_cgroup_path[0] == 0)
return false;

char *mem_limit_filename = nullptr;
bool result = false;

if (m_memory_cgroup_path == nullptr)
return result;

size_t len = strlen(m_memory_cgroup_path);
len += strlen(MEM_LIMIT_FILENAME);
mem_limit_filename = (char*)malloc(len+1);
if (mem_limit_filename == nullptr)
return result;

strcpy(mem_limit_filename, m_memory_cgroup_path);
strncat(mem_limit_filename, MEM_LIMIT_FILENAME,
MAX_PATH-strlen(mem_limit_filename)-1);
return ReadMemoryValueFromFile(mem_limit_filename, val);
strcat(mem_limit_filename, MEM_LIMIT_FILENAME);
result = ReadMemoryValueFromFile(mem_limit_filename, val);
free(mem_limit_filename);
return result;
}

private:
bool FindMemoryHierarchyMount(char* mountpath, size_t mountpathsize)
char* FindMemoryHierarchyMount()
{
bool retval = false;
char *line = nullptr;
size_t lineLen = 0;
size_t lineLen = 0, maxLineLen = 0;
char *filesystemType = nullptr;
char *options = nullptr;
char* mountpath = nullptr;

FILE *mountinfofile = fopen(PROC_MOUNTINFO_FILENAME, "r");
if (mountinfofile == NULL)
goto done;

while (!retval && getline(&line, &lineLen, mountinfofile) != -1)
while (getline(&line, &lineLen, mountinfofile) != -1)
{
char filesystemType[100];
char options[MAX_PATH];
char format[50];

if (filesystemType == nullptr || lineLen > maxLineLen)
{
free(filesystemType);
free(options);
filesystemType = (char*)malloc(lineLen+1);
if (filesystemType == nullptr)
goto done;
options = (char*)malloc(lineLen+1);
if (options == nullptr)
goto done;
maxLineLen = lineLen;
}

char* separatorChar = strchr(line, '-');

sprintf(format, "- %%%lus %%*s %%%lus",
_countof(filesystemType)-1,
_countof(options)-1);

// See man page of proc to get format for /proc/self/mountinfo file
int sscanfRet = sscanf(separatorChar,
format,
"- %s %*s %s",
filesystemType,
options);
if (sscanfRet != 2)
Expand All @@ -104,54 +134,66 @@ class CGroup
{
if (strncmp("memory", strTok, 6) == 0)
{
sprintf(format, "%%*d %%*d %%*s %%*s %%%lus ",
mountpathsize-1);
mountpath = (char*)malloc(lineLen+1);
if (mountpath == nullptr)
goto done;

sscanfRet = sscanf(line,
format,
"%*d %*d %*s %*s %s ",
mountpath);
if (sscanfRet != 1)
{
free(mountpath);
mountpath = nullptr;
assert(!"Failed to parse mount info file contents with sscanf.");
goto done;
}
retval = true;
break;
goto done;
}
strTok = strtok_r(NULL, ",", &context);
}
}
}
done:
free(filesystemType);
free(options);
if (line)
free(line);
if (mountinfofile)
fclose(mountinfofile);
return retval;
return mountpath;
}

bool FindCGroupPathForMemorySubsystem(char* cgrouppath, size_t cgrouppathsize)
char* FindCGroupPathForMemorySubsystem()
{
bool retval = false;
char *line = nullptr;
size_t lineLen = 0;
size_t maxLineLen = 0;
char *subsystem_list = nullptr;
char *cgroup_path = nullptr;
bool result = false;

FILE *cgroupfile = fopen(PROC_CGROUP_FILENAME, "r");
if (cgroupfile == NULL)
goto done;

while (!retval && getline(&line, &lineLen, cgroupfile) != -1)
while (!result && getline(&line, &lineLen, cgroupfile) != -1)
{
char subsystem_list[100];
char cgroup_path[MAX_PATH];
char format[50];

sprintf(format, "%%*[^:]:%%%lu[^:]:%%%lus",
_countof(subsystem_list)-1,
_countof(cgroup_path)-1);
if (subsystem_list == nullptr || lineLen > maxLineLen)
{
free(subsystem_list);
free(cgroup_path);
subsystem_list = (char*)malloc(lineLen+1);
if (subsystem_list == nullptr)
goto done;
cgroup_path = (char*)malloc(lineLen+1);
if (cgroup_path == nullptr)
goto done;
maxLineLen = lineLen;
}

// See man page of proc to get format for /proc/self/cgroup file
int sscanfRet = sscanf(line,
format,
"%*[^:]:%[^:]:%s",
subsystem_list,
cgroup_path);
if (sscanfRet != 2)
Expand All @@ -166,19 +208,24 @@ class CGroup
{
if (strncmp("memory", strTok, 6) == 0)
{
strcpy(cgrouppath, cgroup_path);
retval = true;
result = true;
break;
}
strTok = strtok_r(NULL, ",", &context);
}
}
done:
free(subsystem_list);
if (!result)
{
free(cgroup_path);
cgroup_path = nullptr;
}
if (line)
free(line);
if (cgroupfile)
fclose(cgroupfile);
return retval;
return cgroup_path;
}

bool ReadMemoryValueFromFile(const char* filename, size_t* val)
Expand Down
Loading

0 comments on commit b24a9a1

Please sign in to comment.