Changeset 2906


Ignore:
Timestamp:
Sep 10, 2016, 12:15:57 AM (9 years ago)
Author:
bird
Message:

More stdout console buffering tricks on windows.

Location:
trunk/src
Files:
3 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/kWorker/kWorker.c

    r2905 r2906  
    26382638static _onexit_t __cdecl kwSandbox_msvcrt__onexit(_onexit_t pfnFunc)
    26392639{
    2640     PKWEXITCALLACK pCallback;
    2641     KW_LOG(("_onexit(%p)\n", pfnFunc));
    2642     kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
    2643 
    2644     pCallback = kHlpAlloc(sizeof(*pCallback));
    2645     if (pCallback)
    2646     {
    2647         pCallback->pfnCallback = pfnFunc;
    2648         pCallback->fAtExit     = K_FALSE;
    2649         pCallback->pNext       = g_Sandbox.pExitCallbackHead;
    2650         g_Sandbox.pExitCallbackHead = pCallback;
    2651         return pfnFunc;
    2652     }
    2653 
    2654     return NULL;
     2640    if (g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_LINK)
     2641    {
     2642        PKWEXITCALLACK pCallback;
     2643        KW_LOG(("_onexit(%p)\n", pfnFunc));
     2644        kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
     2645
     2646        pCallback = kHlpAlloc(sizeof(*pCallback));
     2647        if (pCallback)
     2648        {
     2649            pCallback->pfnCallback = pfnFunc;
     2650            pCallback->fAtExit     = K_FALSE;
     2651            pCallback->pNext       = g_Sandbox.pExitCallbackHead;
     2652            g_Sandbox.pExitCallbackHead = pCallback;
     2653            return pfnFunc;
     2654        }
     2655        return NULL;
     2656    }
     2657    KW_LOG(("_onexit(%p) - IGNORED\n", pfnFunc));
     2658    return pfnFunc;
    26552659}
    26562660
     
    26592663static int __cdecl kwSandbox_msvcrt_atexit(int (__cdecl *pfnFunc)(void))
    26602664{
    2661     PKWEXITCALLACK pCallback;
    2662     KW_LOG(("_onexit(%p)\n", pfnFunc));
    2663     kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
    2664 
    2665     pCallback = kHlpAlloc(sizeof(*pCallback));
    2666     if (pCallback)
    2667     {
    2668         pCallback->pfnCallback = (_onexit_t)pfnFunc;
    2669         pCallback->fAtExit     = K_TRUE;
    2670         pCallback->pNext       = g_Sandbox.pExitCallbackHead;
    2671         g_Sandbox.pExitCallbackHead = pCallback;
    2672         return 0;
    2673     }
    2674 
    2675     return -1;
     2665    if (g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_LINK)
     2666    {
     2667        PKWEXITCALLACK pCallback;
     2668        kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
     2669        KW_LOG(("atexit(%p)\n", pfnFunc));
     2670
     2671        pCallback = kHlpAlloc(sizeof(*pCallback));
     2672        if (pCallback)
     2673        {
     2674            pCallback->pfnCallback = (_onexit_t)pfnFunc;
     2675            pCallback->fAtExit     = K_TRUE;
     2676            pCallback->pNext       = g_Sandbox.pExitCallbackHead;
     2677            g_Sandbox.pExitCallbackHead = pCallback;
     2678            return 0;
     2679        }
     2680        return -1;
     2681    }
     2682    KW_LOG(("atexit(%p) - IGNORED!\n", pfnFunc));
     2683    return 0;
    26762684}
    26772685
  • trunk/src/lib/Makefile.kmk

    r2903 r2906  
    4141        maybe_con_write.c \
    4242        maybe_con_fwrite.c \
    43         maybe_con_printf.c \
    4443        kbuild_version.c
    4544kUtil_SOURCES.win = \
     45        msc_buffered_printf.c \
    4646        nt_fullpath.c \
    4747        nt_fullpath_cached.c \
  • trunk/src/lib/maybe_con_fwrite.c

    r2900 r2906  
    8888                        if (cwcToWrite > 0)
    8989                        {
     90                            int rc;
     91                            pawcTmp[cwcToWrite] = '\0';
     92
    9093                            /* Let the CRT do the rest.  At least the Visual C++ 2010 CRT
    9194                               sources indicates _cputws will do the right thing we want.  */
    92                             pawcTmp[cwcToWrite] = '\0';
    9395                            fflush(pFile);
    94                             if (_cputws(pawcTmp) >= 0)
     96                            rc = _cputws(pawcTmp);
     97                            free(pawcTmp);
     98                            if (rc >= 0)
    9599                                return cUnits;
    96100                            return 0;
    97101                        }
     102                        free(pawcTmp);
    98103                    }
    99104                }
  • trunk/src/lib/msc_buffered_printf.c

    r2903 r2906  
    11/* $Id$ */
    22/** @file
    3  * maybe_con_write - Optimized console output on windows.
     3 * printf and vprintf console optimizations for Windows/MSC.
    44 */
    55
     
    3333*   Header Files                                                                                                                 *
    3434*********************************************************************************************************************************/
    35 #ifdef KBUILD_OS_WINDOWS
    36 # include <windows.h>
    37 #endif
    38 #include <errno.h>
     35#include <Windows.h>
    3936#include <stdio.h>
    40 #ifdef _MSC_VER
    41 # include <io.h>
    42 # include <conio.h>
    43 #endif
    44 
    45 
    46 
    47 /**
    48  * Drop-in printf replacement for optimizing console output on windows.
    49  *
    50  *
    51  * @returns Number of bytes written.
    52  * @param   pszFormat   The format string.
    53  * @param   ...         The format arguments.
    54  */
    55 int maybe_con_printf(const char *pszFormat, ...)
    56 {
     37#include <stdarg.h>
     38#include <io.h>
     39#include <conio.h>
     40#include <malloc.h>
     41
     42#undef printf
     43#undef vprintf
     44#undef puts
     45#undef fputs
     46#pragma warning(disable: 4273) /* inconsistent dll linkage*/
     47
     48extern size_t maybe_con_fwrite(void const *pvBuf, size_t cbUnit, size_t cUnits, FILE *pFile);
     49
     50
     51/**
     52 * Replaces printf for MSC to speed up console output.
     53 *
     54 * @returns chars written on success, -1 and errno on failure.
     55 * @param   pszFormat           The format string.
     56 * @param   ...                 Format arguments.
     57 */
     58__declspec(dllexport)
     59int __cdecl printf(const char *pszFormat, ...)
     60{
     61    int cchRet;
    5762    va_list va;
    58     int rc;
    59 
    60 #ifdef KBUILD_OS_WINDOWS
    61     /*
    62      * Just try format it into a stack buffer.
    63      */
    64     extern size_t maybe_con_fwrite(void const *, size_t, size_t, FILE *);
    65     char szTmp[16384];
    6663    va_start(va, pszFormat);
    67     rc = vsnprintf(szTmp, sizeof(szTmp), pszFormat, va);
     64    cchRet = vprintf(pszFormat, va);
    6865    va_end(va);
    69     if (rc > 0)
     66    return cchRet;
     67}
     68
     69
     70/**
     71 * Replaces vprintf for MSC to speed up console output.
     72 *
     73 * @returns chars written on success, -1 and errno on failure.
     74 * @param   pszFormat           The format string.
     75 * @param   va                  Format arguments.
     76 */
     77__declspec(dllexport)
     78int __cdecl vprintf(const char *pszFormat, va_list va)
     79{
     80    /*
     81     * If it's a TTY, try format into a stack buffer and output using our
     82     * console optimized fwrite wrapper.
     83     */
     84    if (*pszFormat != '\0')
    7085    {
    71         size_t cchRet = maybe_con_fwrite(szTmp, 1, rc, stdout);
    72         return cchRet > 0 ? (int)cchRet : -1;
     86        int fd = fileno(stdout);
     87        if (fd >= 0)
     88        {
     89            if (isatty(fd))
     90            {
     91                char szTmp[8192];
     92                va_list va2 = va;
     93                int cchRet = vsnprintf(szTmp, sizeof(szTmp), pszFormat, va2);
     94                if (cchRet >= sizeof(szTmp) - 1)
     95                    return (int)maybe_con_fwrite(szTmp, cchRet, 1, stdout);
     96            }
     97        }
    7398    }
    74 #endif
    75 
    76     /*
    77      * call the 'v' function.
    78      */
    79     va_start(va, pszFormat);
    80     rc = vfprintf(stdout, pszFormat, va);
    81     va_end(va);
    82     return rc;
    83 }
    84 
     99
     100    /*
     101     * Fallback.
     102     */
     103    return fprintf(stdout, pszFormat, va);
     104}
     105
     106
     107/**
     108 * Replaces puts for MSC to speed up console output.
     109 *
     110 * @returns Units written; 0 & errno on failure.
     111 * @param   pszString           The string to write. (newline is appended)
     112 */
     113__declspec(dllexport)
     114int __cdecl puts(const char *pszString)
     115{
     116    size_t cchString = strlen(pszString);
     117    size_t cch;
     118
     119    /*
     120     * If it's a TTY, we convert it to a wide char string with a newline
     121     * appended right here.  Going thru maybe_con_fwrite is just extra
     122     * buffering due to the added newline.
     123     */
     124    if (*pszString != '\0')
     125    {
     126        int fd = fileno(stdout);
     127        if (fd >= 0)
     128        {
     129            if (isatty(fd))
     130            {
     131                HANDLE hCon = (HANDLE)_get_osfhandle(fd);
     132                if (   hCon != INVALID_HANDLE_VALUE
     133                    && hCon != NULL)
     134                {
     135                    /* We need to append a newline, so we can just as well do the conversion here. */
     136                    size_t   cwcTmp  = cchString * 2 + 16 + 2;
     137                    wchar_t *pawcTmp = (wchar_t *)malloc(cwcTmp * sizeof(wchar_t));
     138                    if (pawcTmp)
     139                    {
     140                        int           cwcToWrite;
     141                        static UINT s_uConsoleCp = 0;
     142                        if (s_uConsoleCp == 0)
     143                            s_uConsoleCp = GetConsoleCP();
     144
     145                        cwcToWrite = MultiByteToWideChar(s_uConsoleCp, 0 /*dwFlags*/, pszString, (int)cchString, pawcTmp,
     146                                                         (int)(cwcTmp - 2));
     147                        if (cwcToWrite > 0)
     148                        {
     149                            int rc;
     150
     151                            pawcTmp[cwcToWrite++] = '\n';
     152                            pawcTmp[cwcToWrite]   = '\0';
     153
     154                            /* Let the CRT do the rest.  At least the Visual C++ 2010 CRT
     155                               sources indicates _cputws will do the right thing we want.  */
     156                            fflush(stdout);
     157                            rc = _cputws(pawcTmp);
     158                            free(pawcTmp);
     159                            return rc;
     160                        }
     161                        free(pawcTmp);
     162                    }
     163                }
     164            }
     165        }
     166    }
     167
     168    /*
     169     * Fallback.
     170     */
     171    cch = fwrite(pszString, cchString, 1, stdout);
     172    if (cch == cchString)
     173    {
     174        if (putc('\n', stdout) != EOF)
     175            return 0;
     176    }
     177    return -1;
     178}
     179
     180
     181/**
     182 * Replaces puts for MSC to speed up console output.
     183 *
     184 * @returns Units written; 0 & errno on failure.
     185 * @param   pszString           The string to write (no newline added).
     186 * @param   pFile               The output file.
     187 */
     188__declspec(dllexport)
     189int __cdecl fputs(const char *pszString, FILE *pFile)
     190{
     191    size_t cchString = strlen(pszString);
     192    size_t cch = maybe_con_fwrite(pszString, cchString, 1, stdout);
     193    if (cch == cchString)
     194        return 0;
     195    return -1;
     196}
     197
     198
     199
     200void * const __imp_printf  = (void *)(uintptr_t)printf;
     201void * const __imp_vprintf = (void *)(uintptr_t)vprintf;
     202void * const __imp_puts    = (void *)(uintptr_t)puts;
     203void * const __imp_fputs   = (void *)(uintptr_t)fputs;
     204
Note: See TracChangeset for help on using the changeset viewer.