123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- #ifndef _WIN32
- # error You should only be including windows/port.cc in a windows environment!
- #endif
- #define NOMINMAX
- #include <config.h>
- #include <string.h> // for strlen(), memset(), memcmp()
- #include <assert.h>
- #include <stdarg.h> // for va_list, va_start, va_end
- #include <algorithm> // for std:{min,max}
- #include <windows.h>
- #include "port.h"
- #include "base/logging.h"
- #include "base/spinlock.h"
- #include "internal_logging.h"
- PERFTOOLS_DLL_DECL
- int getpagesize() {
- static int pagesize = 0;
- if (pagesize == 0) {
- SYSTEM_INFO system_info;
- GetSystemInfo(&system_info);
- pagesize = std::max(system_info.dwPageSize,
- system_info.dwAllocationGranularity);
- }
- return pagesize;
- }
- extern "C" PERFTOOLS_DLL_DECL void* __sbrk(ptrdiff_t increment) {
- LOG(FATAL, "Windows doesn't implement sbrk!\n");
- return NULL;
- }
- extern "C" PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len) {
-
- for (int i = 0; i < len; i += 80) {
- write(STDERR_FILENO, buf + i, std::min(80, len - i));
- }
- }
- #ifdef _MSC_VER
- #if defined(_M_IX86)
- #pragma comment(linker, "/INCLUDE:__tls_used")
- #pragma comment(linker, "/INCLUDE:_p_thread_callback_tcmalloc")
- #pragma comment(linker, "/INCLUDE:_p_process_term_tcmalloc")
- #elif defined(_M_X64)
- #pragma comment(linker, "/INCLUDE:_tls_used")
- #pragma comment(linker, "/INCLUDE:p_thread_callback_tcmalloc")
- #pragma comment(linker, "/INCLUDE:p_process_term_tcmalloc")
- #endif
- #endif
- struct DestrFnClosure {
- void (*destr_fn)(void*);
- pthread_key_t key_for_destr_fn_arg;
- };
- static DestrFnClosure destr_fn_info;
- static int on_process_term(void) {
- if (destr_fn_info.destr_fn) {
- void *ptr = TlsGetValue(destr_fn_info.key_for_destr_fn_arg);
-
-
-
- TlsSetValue(destr_fn_info.key_for_destr_fn_arg, NULL);
- if (ptr)
- (*destr_fn_info.destr_fn)(ptr);
- }
- return 0;
- }
- static void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv) {
- if (dwReason == DLL_THREAD_DETACH) {
- on_process_term();
- }
- }
- #ifdef _MSC_VER
- extern "C" {
- #pragma data_seg(push, old_seg)
- #pragma data_seg(".CRT$XLB")
- void (NTAPI *p_thread_callback_tcmalloc)(
- HINSTANCE h, DWORD dwReason, PVOID pv) = on_tls_callback;
- #pragma data_seg(".CRT$XTU")
- int (*p_process_term_tcmalloc)(void) = on_process_term;
- #pragma data_seg(pop, old_seg)
- }
- #else
- BOOL WINAPI DllMain(HINSTANCE h, DWORD dwReason, PVOID pv) {
- if (dwReason == DLL_THREAD_DETACH)
- on_tls_callback(h, dwReason, pv);
- else if (dwReason == DLL_PROCESS_DETACH)
- on_process_term();
- return TRUE;
- }
- #endif
- extern "C" pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)) {
-
-
-
- pthread_key_t key = TlsAlloc();
- if (destr_fn) {
-
- assert(destr_fn_info.destr_fn == NULL);
- destr_fn_info.destr_fn = destr_fn;
- destr_fn_info.key_for_destr_fn_arg = key;
- }
- return key;
- }
- extern "C" int perftools_pthread_once(pthread_once_t *once_control,
- void (*init_routine)(void)) {
-
-
- if (*once_control != 1) {
- while (true) {
- switch (InterlockedCompareExchange(once_control, 2, 0)) {
- case 0:
- init_routine();
- InterlockedExchange(once_control, 1);
- return 0;
- case 1:
-
- return 0;
- default:
-
- SwitchToThread();
- }
- }
- }
- return 0;
- }
- void DeleteMatchingFiles(const char* prefix, const char* full_glob) {
- WIN32_FIND_DATAA found;
- HANDLE hFind = FindFirstFileA(full_glob, &found);
- if (hFind != INVALID_HANDLE_VALUE) {
- const int prefix_length = strlen(prefix);
- do {
- const char *fname = found.cFileName;
- if ((strlen(fname) >= prefix_length) &&
- (memcmp(fname, prefix, prefix_length) == 0)) {
- RAW_VLOG(0, "Removing old heap profile %s\n", fname);
-
- _unlink(fname);
- }
- } while (FindNextFileA(hFind, &found) != FALSE);
- FindClose(hFind);
- }
- }
|