aboutsummaryrefslogtreecommitdiff
path: root/final/runtime/src/kmp_io.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'final/runtime/src/kmp_io.cpp')
-rw-r--r--final/runtime/src/kmp_io.cpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/final/runtime/src/kmp_io.cpp b/final/runtime/src/kmp_io.cpp
new file mode 100644
index 0000000..24c6e72
--- /dev/null
+++ b/final/runtime/src/kmp_io.cpp
@@ -0,0 +1,230 @@
+/*
+ * kmp_io.cpp -- RTL IO
+ */
+
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.txt for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef __ABSOFT_WIN
+#include <sys/types.h>
+#endif
+
+#include "kmp.h" // KMP_GTID_DNE, __kmp_debug_buf, etc
+#include "kmp_io.h"
+#include "kmp_lock.h"
+#include "kmp_os.h"
+#include "kmp_str.h"
+
+#if KMP_OS_WINDOWS
+#if KMP_MSVC_COMPAT
+#pragma warning(push)
+#pragma warning(disable : 271 310)
+#endif
+#include <windows.h>
+#if KMP_MSVC_COMPAT
+#pragma warning(pop)
+#endif
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+kmp_bootstrap_lock_t __kmp_stdio_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(
+ __kmp_stdio_lock); /* Control stdio functions */
+kmp_bootstrap_lock_t __kmp_console_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(
+ __kmp_console_lock); /* Control console initialization */
+
+#if KMP_OS_WINDOWS
+
+static HANDLE __kmp_stdout = NULL;
+static HANDLE __kmp_stderr = NULL;
+static int __kmp_console_exists = FALSE;
+static kmp_str_buf_t __kmp_console_buf;
+
+static int is_console(void) {
+ char buffer[128];
+ DWORD rc = 0;
+ DWORD err = 0;
+ // Try to get console title.
+ SetLastError(0);
+ // GetConsoleTitle does not reset last error in case of success or short
+ // buffer, so we need to clear it explicitly.
+ rc = GetConsoleTitle(buffer, sizeof(buffer));
+ if (rc == 0) {
+ // rc == 0 means getting console title failed. Let us find out why.
+ err = GetLastError();
+ // err == 0 means buffer too short (we suppose console exists).
+ // In Window applications we usually have err == 6 (invalid handle).
+ }
+ return rc > 0 || err == 0;
+}
+
+void __kmp_close_console(void) {
+ /* wait until user presses return before closing window */
+ /* TODO only close if a window was opened */
+ if (__kmp_console_exists) {
+ __kmp_stdout = NULL;
+ __kmp_stderr = NULL;
+ __kmp_str_buf_free(&__kmp_console_buf);
+ __kmp_console_exists = FALSE;
+ }
+}
+
+/* For windows, call this before stdout, stderr, or stdin are used.
+ It opens a console window and starts processing */
+static void __kmp_redirect_output(void) {
+ __kmp_acquire_bootstrap_lock(&__kmp_console_lock);
+
+ if (!__kmp_console_exists) {
+ HANDLE ho;
+ HANDLE he;
+
+ __kmp_str_buf_init(&__kmp_console_buf);
+
+ AllocConsole();
+ // We do not check the result of AllocConsole because
+ // 1. the call is harmless
+ // 2. it is not clear how to communicate failue
+ // 3. we will detect failure later when we get handle(s)
+
+ ho = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (ho == INVALID_HANDLE_VALUE || ho == NULL) {
+
+ DWORD err = GetLastError();
+ // TODO: output error somehow (maybe message box)
+ __kmp_stdout = NULL;
+
+ } else {
+
+ __kmp_stdout = ho; // temporary code, need new global for ho
+ }
+ he = GetStdHandle(STD_ERROR_HANDLE);
+ if (he == INVALID_HANDLE_VALUE || he == NULL) {
+
+ DWORD err = GetLastError();
+ // TODO: output error somehow (maybe message box)
+ __kmp_stderr = NULL;
+
+ } else {
+
+ __kmp_stderr = he; // temporary code, need new global
+ }
+ __kmp_console_exists = TRUE;
+ }
+ __kmp_release_bootstrap_lock(&__kmp_console_lock);
+}
+
+#else
+#define __kmp_stderr (stderr)
+#define __kmp_stdout (stdout)
+#endif /* KMP_OS_WINDOWS */
+
+void __kmp_vprintf(enum kmp_io out_stream, char const *format, va_list ap) {
+#if KMP_OS_WINDOWS
+ if (!__kmp_console_exists) {
+ __kmp_redirect_output();
+ }
+ if (!__kmp_stderr && out_stream == kmp_err) {
+ return;
+ }
+ if (!__kmp_stdout && out_stream == kmp_out) {
+ return;
+ }
+#endif /* KMP_OS_WINDOWS */
+ auto stream = ((out_stream == kmp_out) ? __kmp_stdout : __kmp_stderr);
+
+ if (__kmp_debug_buf && __kmp_debug_buffer != NULL) {
+
+ int dc = __kmp_debug_count++ % __kmp_debug_buf_lines;
+ char *db = &__kmp_debug_buffer[dc * __kmp_debug_buf_chars];
+ int chars = 0;
+
+#ifdef KMP_DEBUG_PIDS
+ chars = KMP_SNPRINTF(db, __kmp_debug_buf_chars, "pid=%d: ",
+ (kmp_int32)getpid());
+#endif
+ chars += KMP_VSNPRINTF(db, __kmp_debug_buf_chars, format, ap);
+
+ if (chars + 1 > __kmp_debug_buf_chars) {
+ if (chars + 1 > __kmp_debug_buf_warn_chars) {
+#if KMP_OS_WINDOWS
+ DWORD count;
+ __kmp_str_buf_print(&__kmp_console_buf, "OMP warning: Debugging buffer "
+ "overflow; increase "
+ "KMP_DEBUG_BUF_CHARS to %d\n",
+ chars + 1);
+ WriteFile(stream, __kmp_console_buf.str, __kmp_console_buf.used, &count,
+ NULL);
+ __kmp_str_buf_clear(&__kmp_console_buf);
+#else
+ fprintf(stream, "OMP warning: Debugging buffer overflow; "
+ "increase KMP_DEBUG_BUF_CHARS to %d\n",
+ chars + 1);
+ fflush(stream);
+#endif
+ __kmp_debug_buf_warn_chars = chars + 1;
+ }
+ /* terminate string if overflow occurred */
+ db[__kmp_debug_buf_chars - 2] = '\n';
+ db[__kmp_debug_buf_chars - 1] = '\0';
+ }
+ } else {
+#if KMP_OS_WINDOWS
+ DWORD count;
+#ifdef KMP_DEBUG_PIDS
+ __kmp_str_buf_print(&__kmp_console_buf, "pid=%d: ", (kmp_int32)getpid());
+#endif
+ __kmp_str_buf_vprint(&__kmp_console_buf, format, ap);
+ WriteFile(stream, __kmp_console_buf.str, __kmp_console_buf.used, &count,
+ NULL);
+ __kmp_str_buf_clear(&__kmp_console_buf);
+#else
+#ifdef KMP_DEBUG_PIDS
+ fprintf(stream, "pid=%d: ", (kmp_int32)getpid());
+#endif
+ vfprintf(stream, format, ap);
+ fflush(stream);
+#endif
+ }
+}
+
+void __kmp_printf(char const *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+
+ __kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);
+ __kmp_vprintf(kmp_err, format, ap);
+ __kmp_release_bootstrap_lock(&__kmp_stdio_lock);
+
+ va_end(ap);
+}
+
+void __kmp_printf_no_lock(char const *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+
+ __kmp_vprintf(kmp_err, format, ap);
+
+ va_end(ap);
+}
+
+void __kmp_fprintf(enum kmp_io stream, char const *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+
+ __kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);
+ __kmp_vprintf(stream, format, ap);
+ __kmp_release_bootstrap_lock(&__kmp_stdio_lock);
+
+ va_end(ap);
+}