#include #include #include #include #include #include #include #include "kforker.h" using namespace std; #define FATOR 4 bool getcol(FILE *, string &); bool getline(FILE *, string &); bool getsomething(FILE *, string &, char); int mfree(void); int musage(void); //---------------------------------------------------------------------- pid_t kfork(void) { /* * Sobrescreve fork() de unistd.h * * Só faz fork se houver sobra de memória. */ int proclen = musage() * FATOR; if (proclen == 0) // ocupação de memória não detectada return -1; if (proclen > mfree()) // memória insuficiente return -1; return fork(); // executa fork }// pid_t kfork(void) //---------------------------------------------------------------------- bool getcol(FILE *fd, string &s) { /* * Obtém uma coluna de um arquivo */ return getsomething(fd, s, ' '); }// string getline(FILE *) bool getline(FILE *fd, string &s) { /* * Obtém uma linha de um arquivo */ return getsomething(fd, s, '\n'); }// string getline(FILE *) bool getsomething(FILE *fd, string &s, char something) { /* * Obtém n caracteres até encontrar um carácter de parada * (something) */ s.erase(); // esvazia a string bool ok = false; char *aux = new char[2]; // recebe cada carácter while (not feof(fd)) { fread(static_cast(aux), 1, 1, fd); // lê um caráter if (aux[0] == something) { ok = true; // encontrou break; } else s += aux[0]; // acrescenta à string } delete aux; // limpa memória usada return ok; }// string getline(FILE *) int mfree(void) { /* * Determina memória livre em KiB * * Para tanto, lê /proc/meminfo */ int mem = 0; FILE *fd; if ((fd = fopen("/proc/meminfo", "r")) != NULL) { bool ok = false; string line; while (getline(fd, line)) if (line.find("MemFree:") == 0) { ok = true; break; } fclose(fd); if (ok) { // Isola somente o campo relevante da linha line.erase(0, line.find_first_of(" ")); line.erase(0, line.find_first_not_of(" ")); int fst = line.find_first_of(" "); line.erase(fst, line.length() - fst + 1); mem = atoi(line.c_str()); } } return mem; }// int mfree(void) int musage(void) { /* * Determina quantidade de memória usada pelo processo atual */ stringstream ss; string filename; int mem = 0; // Obtém informação de /proc/$$/statm ss << "/proc/"; ss << getpid(); ss << "/statm"; ss >> filename; FILE *fd; if ((fd = fopen(filename.c_str(), "r")) != NULL) { string rec; if (getcol(fd, rec)) mem = atoi(rec.c_str()); fclose(fd); } return mem; }// int musage(void)