Path: blob/main/contrib/llvm-project/openmp/runtime/src/kmp_io.cpp
35258 views
/*1* kmp_io.cpp -- RTL IO2*/34//===----------------------------------------------------------------------===//5//6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.7// See https://llvm.org/LICENSE.txt for license information.8// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception9//10//===----------------------------------------------------------------------===//1112#include <stdarg.h>13#include <stddef.h>14#include <stdio.h>15#include <stdlib.h>16#include <string.h>17#ifndef __ABSOFT_WIN18#include <sys/types.h>19#endif2021#include "kmp.h" // KMP_GTID_DNE, __kmp_debug_buf, etc22#include "kmp_io.h"23#include "kmp_lock.h"24#include "kmp_os.h"25#include "kmp_str.h"2627#if KMP_OS_WINDOWS28#if KMP_MSVC_COMPAT29#pragma warning(push)30#pragma warning(disable : 271 310)31#endif32#include <windows.h>33#if KMP_MSVC_COMPAT34#pragma warning(pop)35#endif36#endif3738/* ------------------------------------------------------------------------ */3940kmp_bootstrap_lock_t __kmp_stdio_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(41__kmp_stdio_lock); /* Control stdio functions */42kmp_bootstrap_lock_t __kmp_console_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(43__kmp_console_lock); /* Control console initialization */4445#if KMP_OS_WINDOWS4647static HANDLE __kmp_stdout = NULL;48static HANDLE __kmp_stderr = NULL;49static int __kmp_console_exists = FALSE;50static kmp_str_buf_t __kmp_console_buf;5152void __kmp_close_console(void) {53/* wait until user presses return before closing window */54/* TODO only close if a window was opened */55if (__kmp_console_exists) {56__kmp_stdout = NULL;57__kmp_stderr = NULL;58__kmp_str_buf_free(&__kmp_console_buf);59__kmp_console_exists = FALSE;60}61}6263/* For windows, call this before stdout, stderr, or stdin are used.64It opens a console window and starts processing */65static void __kmp_redirect_output(void) {66__kmp_acquire_bootstrap_lock(&__kmp_console_lock);6768if (!__kmp_console_exists) {69HANDLE ho;70HANDLE he;7172__kmp_str_buf_init(&__kmp_console_buf);7374AllocConsole();75// We do not check the result of AllocConsole because76// 1. the call is harmless77// 2. it is not clear how to communicate failue78// 3. we will detect failure later when we get handle(s)7980ho = GetStdHandle(STD_OUTPUT_HANDLE);81if (ho == INVALID_HANDLE_VALUE || ho == NULL) {8283DWORD err = GetLastError();84// TODO: output error somehow (maybe message box)85(void)err;86__kmp_stdout = NULL;8788} else {8990__kmp_stdout = ho; // temporary code, need new global for ho91}92he = GetStdHandle(STD_ERROR_HANDLE);93if (he == INVALID_HANDLE_VALUE || he == NULL) {9495DWORD err = GetLastError();96// TODO: output error somehow (maybe message box)97(void)err;98__kmp_stderr = NULL;99100} else {101102__kmp_stderr = he; // temporary code, need new global103}104__kmp_console_exists = TRUE;105}106__kmp_release_bootstrap_lock(&__kmp_console_lock);107}108109#else110#define __kmp_stderr (stderr)111#define __kmp_stdout (stdout)112#endif /* KMP_OS_WINDOWS */113114void __kmp_vprintf(enum kmp_io out_stream, char const *format, va_list ap) {115#if KMP_OS_WINDOWS116if (!__kmp_console_exists) {117__kmp_redirect_output();118}119if (!__kmp_stderr && out_stream == kmp_err) {120return;121}122if (!__kmp_stdout && out_stream == kmp_out) {123return;124}125#endif /* KMP_OS_WINDOWS */126auto stream = ((out_stream == kmp_out) ? __kmp_stdout : __kmp_stderr);127128if (__kmp_debug_buf && __kmp_debug_buffer != NULL) {129130int dc = __kmp_debug_count++ % __kmp_debug_buf_lines;131char *db = &__kmp_debug_buffer[dc * __kmp_debug_buf_chars];132int chars = 0;133134#ifdef KMP_DEBUG_PIDS135chars = KMP_SNPRINTF(db, __kmp_debug_buf_chars,136"pid=%d: ", (kmp_int32)getpid());137#endif138chars += KMP_VSNPRINTF(db, __kmp_debug_buf_chars, format, ap);139140if (chars + 1 > __kmp_debug_buf_chars) {141if (chars + 1 > __kmp_debug_buf_warn_chars) {142#if KMP_OS_WINDOWS143DWORD count;144__kmp_str_buf_print(&__kmp_console_buf,145"OMP warning: Debugging buffer "146"overflow; increase "147"KMP_DEBUG_BUF_CHARS to %d\n",148chars + 1);149WriteFile(stream, __kmp_console_buf.str, __kmp_console_buf.used, &count,150NULL);151__kmp_str_buf_clear(&__kmp_console_buf);152#else153fprintf(stream,154"OMP warning: Debugging buffer overflow; "155"increase KMP_DEBUG_BUF_CHARS to %d\n",156chars + 1);157fflush(stream);158#endif159__kmp_debug_buf_warn_chars = chars + 1;160}161/* terminate string if overflow occurred */162db[__kmp_debug_buf_chars - 2] = '\n';163db[__kmp_debug_buf_chars - 1] = '\0';164}165} else {166#if KMP_OS_WINDOWS167DWORD count;168#ifdef KMP_DEBUG_PIDS169__kmp_str_buf_print(&__kmp_console_buf, "pid=%d: ", (kmp_int32)getpid());170#endif171__kmp_str_buf_vprint(&__kmp_console_buf, format, ap);172WriteFile(stream, __kmp_console_buf.str, __kmp_console_buf.used, &count,173NULL);174__kmp_str_buf_clear(&__kmp_console_buf);175#else176#ifdef KMP_DEBUG_PIDS177fprintf(stream, "pid=%d: ", (kmp_int32)getpid());178#endif179vfprintf(stream, format, ap);180fflush(stream);181#endif182}183}184185void __kmp_printf(char const *format, ...) {186va_list ap;187va_start(ap, format);188189__kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);190__kmp_vprintf(kmp_err, format, ap);191__kmp_release_bootstrap_lock(&__kmp_stdio_lock);192193va_end(ap);194}195196void __kmp_printf_no_lock(char const *format, ...) {197va_list ap;198va_start(ap, format);199200__kmp_vprintf(kmp_err, format, ap);201202va_end(ap);203}204205void __kmp_fprintf(enum kmp_io stream, char const *format, ...) {206va_list ap;207va_start(ap, format);208209__kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);210__kmp_vprintf(stream, format, ap);211__kmp_release_bootstrap_lock(&__kmp_stdio_lock);212213va_end(ap);214}215216217