[OpenMP] Introduce new file wrapper class for runtime

Introduce new kmp_safe_raii_file_t class with RAII semantics for file
open/close. It is essentially a wrapper around the C-style FILE* object.
This also unifies the way we error report if a file can't be opened.

Differential Revision: https://reviews.llvm.org/D92604
This commit is contained in:
Peyton, Jonathan L 2020-12-03 13:25:47 -06:00
parent a81db8b315
commit 5aafdd7b88
4 changed files with 85 additions and 54 deletions

View File

@ -4028,4 +4028,63 @@ int __kmp_execute_tasks_oncore(kmp_info_t *thread, kmp_int32 gtid,
#endif /* USE_ITT_BUILD */
kmp_int32 is_constrained);
/// This class safely opens and closes a C-style FILE* object using RAII
/// semantics. There are also methods which allow using stdout or stderr as
/// the underlying FILE* object. With the implicit conversion operator to
/// FILE*, an object with this type can be used in any function which takes
/// a FILE* object e.g., fprintf().
/// No close method is needed at use sites.
class kmp_safe_raii_file_t {
FILE *f;
void close() {
if (f && f != stdout && f != stderr) {
fclose(f);
f = nullptr;
}
}
public:
kmp_safe_raii_file_t() : f(nullptr) {}
kmp_safe_raii_file_t(const char *filename, const char *mode,
const char *env_var = nullptr)
: f(nullptr) {
open(filename, mode, env_var);
}
~kmp_safe_raii_file_t() { close(); }
/// Open filename using mode. This is automatically closed in the destructor.
/// The env_var parameter indicates the environment variable the filename
/// came from if != nullptr.
void open(const char *filename, const char *mode,
const char *env_var = nullptr) {
KMP_ASSERT(!f);
f = fopen(filename, mode);
if (!f) {
int code = errno;
if (env_var) {
__kmp_fatal(KMP_MSG(CantOpenFileForReading, filename), KMP_ERR(code),
KMP_HNT(CheckEnvVar, env_var, filename), __kmp_msg_null);
} else {
__kmp_fatal(KMP_MSG(CantOpenFileForReading, filename), KMP_ERR(code),
__kmp_msg_null);
}
}
}
/// Set the FILE* object to stdout and output there
/// No open call should happen before this call.
void set_stdout() {
KMP_ASSERT(!f);
f = stdout;
}
/// Set the FILE* object to stderr and output there
/// No open call should happen before this call.
void set_stderr() {
KMP_ASSERT(!f);
f = stderr;
}
operator bool() { return bool(f); }
operator FILE *() { return f; }
};
#endif /* KMP_H */

View File

@ -4210,17 +4210,10 @@ static void __kmp_aux_affinity_initialize(void) {
}
}
FILE *f = fopen("/proc/cpuinfo", "r");
if (f == NULL) {
msg_id = kmp_i18n_str_CantOpenCpuinfo;
} else {
file_name = "/proc/cpuinfo";
depth =
__kmp_affinity_create_cpuinfo_map(&address2os, &line, &msg_id, f);
fclose(f);
if (depth == 0) {
KMP_EXIT_AFF_NONE;
}
kmp_safe_raii_file_t f("/proc/cpuinfo", "r");
depth = __kmp_affinity_create_cpuinfo_map(&address2os, &line, &msg_id, f);
if (depth == 0) {
KMP_EXIT_AFF_NONE;
}
}
@ -4313,8 +4306,10 @@ static void __kmp_aux_affinity_initialize(void) {
else if (__kmp_affinity_top_method == affinity_top_method_cpuinfo) {
const char *filename;
const char *env_var = nullptr;
if (__kmp_cpuinfo_file != NULL) {
filename = __kmp_cpuinfo_file;
env_var = "KMP_CPUINFO_FILE";
} else {
filename = "/proc/cpuinfo";
}
@ -4323,20 +4318,9 @@ static void __kmp_aux_affinity_initialize(void) {
KMP_INFORM(AffParseFilename, "KMP_AFFINITY", filename);
}
FILE *f = fopen(filename, "r");
if (f == NULL) {
int code = errno;
if (__kmp_cpuinfo_file != NULL) {
__kmp_fatal(KMP_MSG(CantOpenFileForReading, filename), KMP_ERR(code),
KMP_HNT(NameComesFrom_CPUINFO_FILE), __kmp_msg_null);
} else {
__kmp_fatal(KMP_MSG(CantOpenFileForReading, filename), KMP_ERR(code),
__kmp_msg_null);
}
}
kmp_safe_raii_file_t f(filename, "r", env_var);
int line = 0;
depth = __kmp_affinity_create_cpuinfo_map(&address2os, &line, &msg_id, f);
fclose(f);
if (depth < 0) {
KMP_ASSERT(msg_id != kmp_i18n_null);
if (line > 0) {

View File

@ -1891,20 +1891,6 @@ static float percent(kmp_uint32 count, kmp_uint32 total) {
return (total == 0) ? 0.0 : (100.0 * count) / total;
}
static FILE *__kmp_open_stats_file() {
if (strcmp(__kmp_speculative_statsfile, "-") == 0)
return stdout;
size_t buffLen = KMP_STRLEN(__kmp_speculative_statsfile) + 20;
char buffer[buffLen];
KMP_SNPRINTF(&buffer[0], buffLen, __kmp_speculative_statsfile,
(kmp_int32)getpid());
FILE *result = fopen(&buffer[0], "w");
// Maybe we should issue a warning here...
return result ? result : stdout;
}
void __kmp_print_speculative_stats() {
kmp_adaptive_lock_statistics_t total = destroyedStats;
kmp_adaptive_lock_info_t *lck;
@ -1921,7 +1907,16 @@ void __kmp_print_speculative_stats() {
if (totalSections <= 0)
return;
FILE *statsFile = __kmp_open_stats_file();
kmp_safe_raii_file_t statsFile;
if (strcmp(__kmp_speculative_statsfile, "-") == 0) {
statsFile.set_stdout();
} else {
size_t buffLen = KMP_STRLEN(__kmp_speculative_statsfile) + 20;
char buffer[buffLen];
KMP_SNPRINTF(&buffer[0], buffLen, __kmp_speculative_statsfile,
(kmp_int32)getpid());
statsFile.open(buffer, "w");
}
fprintf(statsFile, "Speculative lock statistics (all approximate!)\n");
fprintf(statsFile, " Lock parameters: \n"
@ -1953,9 +1948,6 @@ void __kmp_print_speculative_stats() {
fprintf(statsFile, " Hard failures : %10d (%5.1f%%)\n",
t->hardFailedSpeculations,
percent(t->hardFailedSpeculations, totalSpeculations));
if (statsFile != stdout)
fclose(statsFile);
}
#define KMP_INC_STAT(lck, stat) (lck->lk.adaptive.stats.stat++)

View File

@ -692,8 +692,7 @@ void kmp_stats_output_module::windupExplicitTimers() {
void kmp_stats_output_module::printPloticusFile() {
int i;
int size = __kmp_stats_list->size();
FILE *plotOut = fopen(plotFileName, "w+");
kmp_safe_raii_file_t plotOut(plotFileName, "w+");
fprintf(plotOut, "#proc page\n"
" pagesize: 15 10\n"
" scale: 1.0\n\n");
@ -746,7 +745,6 @@ void kmp_stats_output_module::printPloticusFile() {
fprintf(plotOut, "#proc legend\n"
" format: down\n"
" location: max max\n\n");
fclose(plotOut);
return;
}
@ -797,14 +795,16 @@ void kmp_stats_output_module::outputStats(const char *heading) {
normal timer stats */
statistic allCounters[COUNTER_LAST];
FILE *statsOut =
!outputFileName.empty() ? fopen(outputFileName.c_str(), "a+") : stderr;
if (!statsOut)
statsOut = stderr;
kmp_safe_raii_file_t statsOut;
if (!outputFileName.empty()) {
statsOut.open(outputFileName.c_str(), "a+");
} else {
statsOut.set_stderr();
}
FILE *eventsOut;
kmp_safe_raii_file_t eventsOut;
if (eventPrintingEnabled()) {
eventsOut = fopen(eventsFileName, "w+");
eventsOut.open(eventsFileName, "w+");
}
printHeaderInfo(statsOut);
@ -855,16 +855,12 @@ void kmp_stats_output_module::outputStats(const char *heading) {
if (eventPrintingEnabled()) {
printPloticusFile();
fclose(eventsOut);
}
fprintf(statsOut, "Aggregate for all threads\n");
printTimerStats(statsOut, &allStats[0], &totalStats[0]);
fprintf(statsOut, "\n");
printCounterStats(statsOut, &allCounters[0]);
if (statsOut != stderr)
fclose(statsOut);
}
/* ************* exported C functions ************** */