brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 0c52662 Raw
216 lines · cpp
1/*2 * kmp_io.cpp -- RTL IO3 */4 5//===----------------------------------------------------------------------===//6//7// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.8// See https://llvm.org/LICENSE.txt for license information.9// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception10//11//===----------------------------------------------------------------------===//12 13#include <stdarg.h>14#include <stddef.h>15#include <stdio.h>16#include <stdlib.h>17#include <string.h>18#ifndef __ABSOFT_WIN19#include <sys/types.h>20#endif21 22#include "kmp.h" // KMP_GTID_DNE, __kmp_debug_buf, etc23#include "kmp_io.h"24#include "kmp_lock.h"25#include "kmp_os.h"26#include "kmp_str.h"27 28#if KMP_OS_WINDOWS29#if KMP_MSVC_COMPAT30#pragma warning(push)31#pragma warning(disable : 271 310)32#endif33#include <windows.h>34#if KMP_MSVC_COMPAT35#pragma warning(pop)36#endif37#endif38 39/* ------------------------------------------------------------------------ */40 41kmp_bootstrap_lock_t __kmp_stdio_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(42    __kmp_stdio_lock); /* Control stdio functions */43kmp_bootstrap_lock_t __kmp_console_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(44    __kmp_console_lock); /* Control console initialization */45 46#if KMP_OS_WINDOWS47 48static HANDLE __kmp_stdout = NULL;49static HANDLE __kmp_stderr = NULL;50static int __kmp_console_exists = FALSE;51static kmp_str_buf_t __kmp_console_buf;52 53void __kmp_close_console(void) {54  /* wait until user presses return before closing window */55  /* TODO only close if a window was opened */56  if (__kmp_console_exists) {57    __kmp_stdout = NULL;58    __kmp_stderr = NULL;59    __kmp_str_buf_free(&__kmp_console_buf);60    __kmp_console_exists = FALSE;61  }62}63 64/* For windows, call this before stdout, stderr, or stdin are used.65   It opens a console window and starts processing */66static void __kmp_redirect_output(void) {67  __kmp_acquire_bootstrap_lock(&__kmp_console_lock);68 69  if (!__kmp_console_exists) {70    HANDLE ho;71    HANDLE he;72 73    __kmp_str_buf_init(&__kmp_console_buf);74 75    AllocConsole();76    // We do not check the result of AllocConsole because77    //  1. the call is harmless78    //  2. it is not clear how to communicate failue79    //  3. we will detect failure later when we get handle(s)80 81    ho = GetStdHandle(STD_OUTPUT_HANDLE);82    if (ho == INVALID_HANDLE_VALUE || ho == NULL) {83 84      DWORD err = GetLastError();85      // TODO: output error somehow (maybe message box)86      (void)err;87      __kmp_stdout = NULL;88 89    } else {90 91      __kmp_stdout = ho; // temporary code, need new global for ho92    }93    he = GetStdHandle(STD_ERROR_HANDLE);94    if (he == INVALID_HANDLE_VALUE || he == NULL) {95 96      DWORD err = GetLastError();97      // TODO: output error somehow (maybe message box)98      (void)err;99      __kmp_stderr = NULL;100 101    } else {102 103      __kmp_stderr = he; // temporary code, need new global104    }105    __kmp_console_exists = TRUE;106  }107  __kmp_release_bootstrap_lock(&__kmp_console_lock);108}109 110#else111#define __kmp_stderr (stderr)112#define __kmp_stdout (stdout)113#endif /* KMP_OS_WINDOWS */114 115void __kmp_vprintf(enum kmp_io out_stream, char const *format, va_list ap) {116#if KMP_OS_WINDOWS117  if (!__kmp_console_exists) {118    __kmp_redirect_output();119  }120  if (!__kmp_stderr && out_stream == kmp_err) {121    return;122  }123  if (!__kmp_stdout && out_stream == kmp_out) {124    return;125  }126#endif /* KMP_OS_WINDOWS */127  auto stream = ((out_stream == kmp_out) ? __kmp_stdout : __kmp_stderr);128 129  if (__kmp_debug_buf && __kmp_debug_buffer != NULL) {130 131    int dc = __kmp_debug_count++ % __kmp_debug_buf_lines;132    char *db = &__kmp_debug_buffer[dc * __kmp_debug_buf_chars];133    int chars = 0;134 135#ifdef KMP_DEBUG_PIDS136    chars = KMP_SNPRINTF(db, __kmp_debug_buf_chars,137                         "pid=%d: ", (kmp_int32)getpid());138#endif139    chars += KMP_VSNPRINTF(db, __kmp_debug_buf_chars, format, ap);140 141    if (chars + 1 > __kmp_debug_buf_chars) {142      if (chars + 1 > __kmp_debug_buf_warn_chars) {143#if KMP_OS_WINDOWS144        DWORD count;145        __kmp_str_buf_print(&__kmp_console_buf,146                            "OMP warning: Debugging buffer "147                            "overflow; increase "148                            "KMP_DEBUG_BUF_CHARS to %d\n",149                            chars + 1);150        WriteFile(stream, __kmp_console_buf.str, __kmp_console_buf.used, &count,151                  NULL);152        __kmp_str_buf_clear(&__kmp_console_buf);153#else154        fprintf(stream,155                "OMP warning: Debugging buffer overflow; "156                "increase KMP_DEBUG_BUF_CHARS to %d\n",157                chars + 1);158        fflush(stream);159#endif160        __kmp_debug_buf_warn_chars = chars + 1;161      }162      /* terminate string if overflow occurred */163      db[__kmp_debug_buf_chars - 2] = '\n';164      db[__kmp_debug_buf_chars - 1] = '\0';165    }166  } else {167#if KMP_OS_WINDOWS168    DWORD count;169#ifdef KMP_DEBUG_PIDS170    __kmp_str_buf_print(&__kmp_console_buf, "pid=%d: ", (kmp_int32)getpid());171#endif172    __kmp_str_buf_vprint(&__kmp_console_buf, format, ap);173    WriteFile(stream, __kmp_console_buf.str, __kmp_console_buf.used, &count,174              NULL);175    __kmp_str_buf_clear(&__kmp_console_buf);176#else177#ifdef KMP_DEBUG_PIDS178    fprintf(stream, "pid=%d: ", (kmp_int32)getpid());179#endif180    vfprintf(stream, format, ap);181    fflush(stream);182#endif183  }184}185 186void __kmp_printf(char const *format, ...) {187  va_list ap;188  va_start(ap, format);189 190  __kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);191  __kmp_vprintf(kmp_err, format, ap);192  __kmp_release_bootstrap_lock(&__kmp_stdio_lock);193 194  va_end(ap);195}196 197void __kmp_printf_no_lock(char const *format, ...) {198  va_list ap;199  va_start(ap, format);200 201  __kmp_vprintf(kmp_err, format, ap);202 203  va_end(ap);204}205 206void __kmp_fprintf(enum kmp_io stream, char const *format, ...) {207  va_list ap;208  va_start(ap, format);209 210  __kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);211  __kmp_vprintf(stream, format, ap);212  __kmp_release_bootstrap_lock(&__kmp_stdio_lock);213 214  va_end(ap);215}216