Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cellframe/libdap
1 result
Show changes
Showing
with 2023 additions and 6 deletions
......@@ -2,7 +2,7 @@
* Authors:
* Anatolii Kurotych <akurotych@gmail.com>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://github.com/demlabsinc
* DeM Labs Open source community https://gitlab.demlabs.net/cellframe
* Copyright (c) 2017-2019
* All rights reserved.
......
......@@ -2,7 +2,7 @@
* Authors:
* Anatolii Kurotych <akurotych@gmail.com>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://github.com/demlabsinc
* DeM Labs Open source community https://gitlab.demlabs.net/cellframe
* Copyright (c) 2017-2019
* All rights reserved.
......
......@@ -2,7 +2,7 @@
* Authors:
* Anatolii Kurotych <akurotych@gmail.com>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://github.com/demlabsinc
* DeM Labs Open source community https://gitlab.demlabs.net/cellframe
* Copyright (c) 2017-2019
* All rights reserved.
......
/*
Copyright (c) 2017-2019 (c) Project "DeM Labs Inc" https://gitlab.demlabs.net/cellframe
All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <memory.h>
#include <windows.h>
#define WM_SETCONSOLEINFO (WM_USER + 201)
#pragma pack(push, 1)
typedef struct _CONSOLE_INFO
{
DWORD Length;
COORD ScreenBufferSize;
COORD WindowSize;
DWORD WindowPosX;
DWORD WindowPosY;
COORD FontSize;
DWORD FontFamily;
DWORD FontWeight;
WCHAR FaceName[32];
DWORD CursorSize;
DWORD FullScreen;
DWORD QuickEdit;
DWORD AutoPosition;
DWORD InsertMode;
USHORT ScreenColors;
USHORT PopupColors;
DWORD HistoryNoDup;
DWORD HistoryBufferSize;
DWORD NumberOfHistoryBuffers;
COLORREF ColorTable[16];
DWORD CodePage;
HWND Hwnd;
WCHAR ConsoleTitle[0x100];
} CONSOLE_INFO;
#pragma pack(pop)
static uint32_t palette[ 16 ] = {
RGB( 0, 0, 0 ), // 0 black
RGB( 0, 0, 128 ), // 1 blue
RGB( 0, 128, 0 ), // 2 green
RGB( 128, 128, 0 ), // 3 cyan
RGB( 128, 0, 0 ), // 4 red
RGB( 128, 0, 128 ), // 5 magenta
RGB( 0, 128, 128 ), // 6 yellow / brown
RGB( 192, 192, 192 ), // 7 white / light gray
RGB( 128, 128, 128 ), // 8 dark gray / bright black
RGB( 0, 0, 255 ), // 9 bright blue
RGB( 0, 255, 0 ), // 10 bright green
RGB( 0, 255, 255 ), // 11 bright cyan
RGB( 255, 0, 0 ), // 12 bright red
RGB( 255, 0, 255 ), // 13 bright magenta
RGB( 255, 255, 0 ), // 14 bright yellow
RGB( 255, 255, 255 ) // 15 bright white
};
static void GetConsoleSizeInfo( CONSOLE_INFO *pci, HANDLE hConOut )
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo( hConOut, &csbi );
pci->ScreenBufferSize = csbi.dwSize;
pci->WindowSize.X = csbi.srWindow.Right - csbi.srWindow.Left + 1;
pci->WindowSize.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
pci->WindowPosX = csbi.srWindow.Left;
pci->WindowPosY = csbi.srWindow.Top;
}
static BOOL SetConsoleInfo( HWND hwndConsole, CONSOLE_INFO *pci )
{
DWORD dwConsoleOwnerPid;
HANDLE hProcess;
HANDLE hSection, hDupSection;
PVOID ptrView = 0;
HANDLE hThread;
GetWindowThreadProcessId( hwndConsole, &dwConsoleOwnerPid );
hProcess = OpenProcess( MAXIMUM_ALLOWED, FALSE, dwConsoleOwnerPid );
hSection = CreateFileMapping( INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, pci->Length, 0 );
ptrView = MapViewOfFile( hSection, FILE_MAP_WRITE|FILE_MAP_READ, 0, 0, pci->Length );
memcpy( ptrView, pci, pci->Length );
UnmapViewOfFile( ptrView );
DuplicateHandle( GetCurrentProcess(), hSection, hProcess, &hDupSection, 0, FALSE, DUPLICATE_SAME_ACCESS );
SendMessage( hwndConsole, WM_SETCONSOLEINFO, (WPARAM)hDupSection, 0 );
hThread = CreateRemoteThread( hProcess, 0, 0, (LPTHREAD_START_ROUTINE)CloseHandle, hDupSection, 0, 0 );
CloseHandle( hThread );
CloseHandle( hSection );
CloseHandle( hProcess );
return TRUE;
}
typedef BOOL (WINAPI *PGetCurrentConsoleFontEx)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
typedef BOOL (WINAPI *PSetCurrentConsoleFontEx)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
typedef BOOL (WINAPI *PGetConsoleScreenBufferInfoEx)(HANDLE hConsoleOutput, PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx);
typedef BOOL (WINAPI *PSetConsoleScreenBufferInfoEx)(HANDLE hConsoleOutput, PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx);
////Lucida Console 12 20
void SetupConsole( const char *title, const uint16_t *fontName, int fontx, int fonty )
{
HANDLE hConOut;
HANDLE hConIn;
HWND hwndConsole = GetConsoleWindow( );
if ( !hwndConsole ) { // daemon ?
return;
}
uint32_t console_owner_proc_id;
GetWindowThreadProcessId( hwndConsole, (LPDWORD)&console_owner_proc_id );
if ( console_owner_proc_id != GetCurrentProcessId() ) {
return;
}
SetConsoleTitleA( (LPCSTR)title );
hConOut = GetStdHandle( STD_OUTPUT_HANDLE );
hConIn = GetStdHandle( STD_INPUT_HANDLE );
int sx = GetSystemMetrics( SM_CXSCREEN );
int sy = GetSystemMetrics( SM_CYSCREEN );
// COORD conmax = GetLargestConsoleWindowSize( hConOut );
PGetCurrentConsoleFontEx pGetCurrentConsoleFontEx = (PGetCurrentConsoleFontEx)
GetProcAddress( GetModuleHandleA("kernel32.dll"), "GetCurrentConsoleFontEx" );
PSetCurrentConsoleFontEx pSetCurrentConsoleFontEx = (PSetCurrentConsoleFontEx)
GetProcAddress( GetModuleHandleA("kernel32.dll"), "SetCurrentConsoleFontEx" );
PGetConsoleScreenBufferInfoEx pGetConsoleScreenBufferInfoEx = (PGetConsoleScreenBufferInfoEx)
GetProcAddress( GetModuleHandleA("kernel32.dll"), "GetConsoleScreenBufferInfoEx" );
PSetConsoleScreenBufferInfoEx pSetConsoleScreenBufferInfoEx = (PSetConsoleScreenBufferInfoEx)
GetProcAddress( GetModuleHandleA("kernel32.dll"), "SetConsoleScreenBufferInfoEx" );
if ( pGetCurrentConsoleFontEx && pSetCurrentConsoleFontEx &&
pGetConsoleScreenBufferInfoEx && pSetConsoleScreenBufferInfoEx )
{
CONSOLE_SCREEN_BUFFER_INFOEX conBufferInfo;
CONSOLE_FONT_INFOEX conFontInfo = {sizeof(CONSOLE_FONT_INFOEX)};
conFontInfo.cbSize = sizeof( CONSOLE_FONT_INFOEX );
pGetCurrentConsoleFontEx( hConOut, TRUE, &conFontInfo );
// printf("conFontInfo.nFont %u \n", conFontInfo.nFont );
// printf("conFontInfo.dwFontSize.X %u \n", conFontInfo.dwFontSize.X );
// printf("conFontInfo.dwFontSize.Y %u \n", conFontInfo.dwFontSize.Y );
// printf("conFontInfo.FontFamily %u \n", conFontInfo.FontFamily );
// printf("conFontInfo.FontWeight %u \n", conFontInfo.FontWeight );
conFontInfo.nFont = 20;
conFontInfo.dwFontSize.X = 12;
conFontInfo.dwFontSize.Y = 20;
conFontInfo.FontFamily = 0;
conFontInfo.FontWeight = 0;
lstrcpyW( conFontInfo.FaceName, fontName );
pSetCurrentConsoleFontEx( hConOut, TRUE, &conFontInfo );
conBufferInfo.cbSize = sizeof( CONSOLE_SCREEN_BUFFER_INFOEX );
pGetConsoleScreenBufferInfoEx( hConOut, &conBufferInfo );
memcpy( &conBufferInfo.ColorTable[0], &palette[0], 4 * 16 );
pSetConsoleScreenBufferInfoEx( hConOut, &conBufferInfo );
}
else {
// printf("XP ?...\n" );
CONSOLE_INFO ci = { sizeof(ci) };
GetConsoleSizeInfo( &ci, hConOut );
ci.FontSize.X = 12;
ci.FontSize.Y = 20;
ci.FontFamily = 0;
ci.FontWeight = 0;
lstrcpyW( ci.FaceName, fontName );
// ci.CursorSize = 100;
ci.FullScreen = FALSE;
ci.QuickEdit = FALSE;
ci.AutoPosition = 0x10000;
ci.InsertMode = TRUE;
ci.ScreenColors = MAKEWORD(0x7, 0x0);
ci.PopupColors = MAKEWORD(0x5, 0xf);
ci.HistoryNoDup = TRUE;
ci.HistoryBufferSize = 50;
ci.NumberOfHistoryBuffers = 4;
memcpy( &ci.ColorTable[0], &palette[0], 4 * 16 );
ci.CodePage = 0;
ci.Hwnd = hwndConsole;
SetConsoleInfo( hwndConsole, &ci );
}
int bx = sx / 12;
int by = sy / 20;
SMALL_RECT Rect = { 0, 0, bx, by };
COORD coord = { bx, by };
SetConsoleWindowInfo( hConOut, TRUE, &Rect );
SetConsoleScreenBufferSize( hConOut, coord );
SetWindowPos( hwndConsole, HWND_TOP, 0, 0, sx-1, sy-1, SWP_NOSIZE );
ShowWindow( hwndConsole, SW_MAXIMIZE );
}
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void SetupConsole( const char *title, const uint16_t *fontName, int fontx, int fonty );
#ifdef __cplusplus
}
#endif
/*
Copyright (c) 2017-2019 (c) Project "DeM Labs Inc" https://gitlab.demlabs.net/cellframe
All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#include <windows.h>
#include <winnt.h>
#include <winternl.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "dap_cpu_monitor.h"
#include "dap_common.h"
#define LOG_TAG "dap_cpu_monitor"
//static FILE * _proc_stat = NULL;
static dap_cpu_stats_t _cpu_stats = {0};
static dap_cpu_t _cpu_old_stats[MAX_CPU_COUNT] = {0};
static dap_cpu_t _cpu_summary_old = {0};
typedef struct proc_stat_line
{
/* http://man7.org/linux/man-pages/man5/proc.5.html */
char cpu[10];
uint64_t user;
uint64_t nice;
uint64_t system;
uint64_t idle;
uint64_t iowait;
uint64_t irq;
uint64_t softirq;
uint64_t steal;
uint64_t guest;
uint64_t guest_nice;
uint64_t total; // summary all parameters
} proc_stat_line_t;
int dap_cpu_monitor_init()
{
SYSTEM_INFO si;
GetSystemInfo( &si );
_cpu_stats.cpu_cores_count = si.dwNumberOfProcessors;
log_it( L_DEBUG, "dap_cpu_monitor_init(): Cpu core count: %d", _cpu_stats.cpu_cores_count );
dap_cpu_get_stats( ); // init prev parameters
return 0;
}
void dap_cpu_monitor_deinit()
{
}
/*
static void _deserealize_proc_stat(char *line, proc_stat_line_t *stat)
{
sscanf(line,"%s %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu",
stat->cpu, &stat->user, &stat->nice, &stat->system, &stat->idle,
&stat->iowait, &stat->irq, &stat->softirq, &stat->steal,
&stat->guest, &stat->guest_nice);
stat->total = stat->user + stat->system + stat->idle +
stat->iowait + stat->irq + stat->softirq +
stat->steal + stat->guest + stat->guest_nice;
}
*/
static float _calculate_load( uint64_t idle_time, uint64_t prev_idle_time,
uint64_t total_time, uint64_t prev_total_time ) {
return ( 1 - (1.0 * idle_time - prev_idle_time) / (total_time - prev_total_time) ) * 100.0;
}
dap_cpu_stats_t dap_cpu_get_stats()
{
FILETIME idleTime, kernelTime, userTime;
GetSystemTimes( &idleTime, &kernelTime, &userTime );
#define WINNT_FILETIME_TO_UINT64(t) (((uint64_t)(t.dwHighDateTime)<<32) | (uint64_t)(t.dwLowDateTime))
_cpu_stats.cpu_summary.idle_time = WINNT_FILETIME_TO_UINT64(idleTime);
_cpu_stats.cpu_summary.total_time = WINNT_FILETIME_TO_UINT64(kernelTime) + WINNT_FILETIME_TO_UINT64(userTime);
/*********************************************/
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION pinfo[64];
ULONG outsize;
uint32_t ntstatus_error;
ntstatus_error = NtQuerySystemInformation( SystemProcessorPerformanceInformation, &pinfo,
sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * 64, &outsize );
if ( ntstatus_error ) {
log_it(L_ERROR, "NtQuerySystemInformation returned an error %u", ntstatus_error );
return (dap_cpu_stats_t){0};
}
if ( outsize < sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * _cpu_stats.cpu_cores_count ) {
log_it(L_WARNING, "NtQuerySystemInformation: data size less than expected");
}
for( uint32_t i = 0; i < _cpu_stats.cpu_cores_count; i++ ) {
_cpu_stats.cpus[i].idle_time = pinfo[i].IdleTime.QuadPart;
_cpu_stats.cpus[i].total_time = pinfo[i].KernelTime.QuadPart + pinfo[i].UserTime.QuadPart;
_cpu_stats.cpus[i].ncpu = i;
_cpu_stats.cpus[i].load = _calculate_load(_cpu_stats.cpus[i].idle_time,
_cpu_old_stats[i].idle_time,
_cpu_stats.cpus[i].total_time,
_cpu_old_stats[i].total_time);
// log_it(L_WARNING, "CPU %d %f", i, _cpu_stats.cpus[i].load);
}
_cpu_stats.cpu_summary.load = _calculate_load(_cpu_stats.cpu_summary.idle_time,
_cpu_summary_old.idle_time,
_cpu_stats.cpu_summary.total_time,
_cpu_summary_old.total_time);
// log_it(L_WARNING, "%f", _cpu_stats.cpu_summary.load);
memcpy(&_cpu_summary_old, &_cpu_stats.cpu_summary, sizeof (dap_cpu_t));
memcpy(_cpu_old_stats, _cpu_stats.cpus,
sizeof (dap_cpu_t) * _cpu_stats.cpu_cores_count);
return _cpu_stats;
}
#pragma once
#define MAX_CPU_COUNT 64
typedef struct dap_cpu {
uint32_t ncpu; // number of cpu core
float load; // percent of load
uint64_t total_time;
uint64_t idle_time;
} dap_cpu_t;
typedef struct dap_cpu_stats
{
uint32_t cpu_cores_count;
dap_cpu_t cpu_summary; // average statistic for all cpu
dap_cpu_t cpus[MAX_CPU_COUNT]; // list of cpu with stat
} dap_cpu_stats_t;
/**
* @brief dap_cpu_monitor_init Monitor CPU initialization
* @return
*/
int dap_cpu_monitor_init(void);
/**
* @brief dap_cpu_monitor_deinit Monitor CPU deinitialization
*/
void dap_cpu_monitor_deinit(void);
/**
* @brief dap_cpu_get_stats Getting processor information
* @return
*/
dap_cpu_stats_t dap_cpu_get_stats(void);
/*
* Authors:
* Anatolii Kurotych <akurotych@gmail.com>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://gitlab.demlabs.net/cellframe
* Copyright (c) 2017-2019
* All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef __cplusplus
extern "C" {
#endif
#pragma once
#include <stdint.h>
#include <stdbool.h>
//#include <net/if.h>
//#include <linux/rtnetlink.h>
#define MAX_IP_STR_LEN 15
#define DAP_ADRESS_UNDEFINED (uint64_t)-1
typedef enum {
// like in rtnetlink defines
IP_ADDR_ADD,
IP_ADDR_REMOVE,
IP_ROUTE_ADD,
IP_ROUTE_REMOVE,
IP_LINK_NEW,
IP_LINK_DEL
} dap_network_monitor_notification_type_t;
typedef struct {
dap_network_monitor_notification_type_t type;
union {
struct {
char interface_name[IF_NAMESIZE];
char s_ip[MAX_IP_STR_LEN + 1];
uint32_t ip; // inet_ntoa(*((struct in_addr *)&ipaddr)) for cast to char*
} addr; // for IP_ADDR_ADD, IP_ADDR_REMOVE
struct {
uint64_t destination_address; // 64 bit for checking -1 like not filled variable
char s_destination_address[MAX_IP_STR_LEN + 1];
uint64_t gateway_address;
char s_gateway_address[MAX_IP_STR_LEN + 1];
uint8_t protocol;
uint8_t netmask;
} route; // for IP_ROUTE_ADD, IP_ROUTE_REMOVE
struct {
char interface_name[IF_NAMESIZE];
bool is_up;
bool is_running;
} link; // for RTM_NEWLINK, RTM_DELLINK
};
} dap_network_notification_t;
typedef void (*dap_network_monitor_notification_callback_t)
(const dap_network_notification_t notification);
/**
* @brief dap_network_monitor_init
* @param callback
* @details starts network monitorting
* @return 0 if successful
*/
int dap_network_monitor_init(dap_network_monitor_notification_callback_t callback);
/**
* @brief dap_network_monitor_deinit
*/
void dap_network_monitor_deinit(void);
#ifdef __cplusplus
}
#endif
/*
Copyright (c) 2017-2019 (c) Project "DeM Labs Inc" https://gitlab.demlabs.net/cellframe
All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#include <windows.h>
#include <winnt.h>
#include <winternl.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "dap_process_manager.h"
#include "dap_common.h"
#undef LOG_TAG
#define LOG_TAG "dap_process_manager"
/**
* @brief is_process_running Check whether the process is running
* @param[in] pid PID
* @return
*/
bool is_process_running( pid_t pid ) {
DWORD ExitCode = 0;
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
if ( !hProcess )
return false;
if ( !GetExitCodeProcess( hProcess, &ExitCode ) || ExitCode != STILL_ACTIVE ) {
CloseHandle( hProcess );
return false;
}
CloseHandle( hProcess );
return true;
}
/**
* @brief save_process_pid_in_file Saves process pid into file by file_path
* @param[in] file_path File path
* @return Execution result
*
* Saves process pid into file by file_path.
* If file exists he will be overwritten
*/
bool save_process_pid_in_file( const char* file_path )
{
FILE *fpid = fopen( file_path, "wb" );
if ( fpid == NULL ) {
log_it( L_ERROR, "Cant create/open file by path %s",file_path );
return false;
}
fprintf( fpid, "%u", GetCurrentProcessId() );
fclose( fpid );
return true;
}
/**
* @brief get_pid_from_file File must consist only PID. Return 0 if file is clear.
* @param[in] file_path File path
* @return Execution result
*/
pid_t get_pid_from_file( const char* file_path ) {
FILE *fpid = fopen( file_path, "rb");
if ( fpid == NULL ) {
log_it( L_ERROR, "Cant create/open file by path %s", file_path );
return false;
}
pid_t f_pid = 0;
fscanf( fpid, "%u", &f_pid );
fclose( fpid );
return f_pid;
}
/**
* @brief daemonize_process Demonizes current process and exit from program
* @return
*/
bool daemonize_process( ) {
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
char fn_exe[256];
DWORD status;
memset( &start_info, 0, sizeof(STARTUPINFO) );
memset( &proc_info, 0, sizeof(PROCESS_INFORMATION) );
memset( &fn_exe[0], 0, 256 );
status = GetModuleFileName( NULL, fn_exe, sizeof(fn_exe) );
if ( !status || status == sizeof(fn_exe) ) {
return false;
}
GetStartupInfo( &start_info );
if ( CreateProcess(fn_exe, NULL, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &start_info, &proc_info) ) {
CloseHandle( proc_info.hThread );
CloseHandle( proc_info.hProcess );
ExitProcess( 0 );
}
return false;
}
/**
* @brief kill_process Sends SIGKILL to process
* @param[in] pid
* @return
*/
bool kill_process( pid_t pid ) {
DWORD ExitCode;
bool rezult = false;
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_TERMINATE, FALSE, pid );
if ( !hProcess ) {
return false;
}
if ( !GetExitCodeProcess( hProcess, &ExitCode ) ) {
return false;
CloseHandle( hProcess );
}
if ( ExitCode == STILL_ACTIVE ) {
rezult = TerminateProcess( hProcess, 0 );
}
CloseHandle( hProcess );
return rezult;
}
#include <stdbool.h>
#include <unistd.h>
#include <stdint.h>
/* Saves process pid into file by file_path.
* If file exists he will be overwritten */
extern bool save_process_pid_in_file( const char* file_path );
/* File must consist only PID. Return 0 if file is clear. */
extern pid_t get_pid_from_file( const char* file_path );
/* Return true if process running */
extern bool is_process_running( pid_t pid );
/* Demonizes current process and exit from program */
extern bool daemonize_process( void );
/* Sends SIGKILL to process */
extern bool kill_process( pid_t pid );
/*
Copyright (c) 2017-2019 (c) Project "DeM Labs Inc" https://gitlab.demlabs.net/cellframe
All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#include <windows.h>
#include <winnt.h>
#include <winternl.h>
#include <stdint.h>
#include <pdh.h>
#include <stdio.h>
#include <psapi.h>
#include "dap_process_memory.h"
#include "dap_common.h"
#define LOG_TAG "dap_process_mem"
static dap_process_memory_t _get_process_memory( uint32_t pid )
{
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
dap_process_memory_t proc_mem = { 0, 0 };
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
if ( !hProcess )
return proc_mem;
if ( !GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) {
CloseHandle( hProcess );
return proc_mem;
}
proc_mem.vsz = pmc.PagefileUsage;
proc_mem.rss = pmc.WorkingSetSize;
CloseHandle( hProcess );
return proc_mem;
}
dap_process_memory_t get_proc_mem_current( void )
{
return _get_process_memory( GetCurrentProcessId() );
}
dap_process_memory_t get_proc_mem_by_pid( uint32_t pid )
{
return _get_process_memory( pid );
}
//#include <stdint.h>
//#include <sys/types.h>
typedef struct dap_process_memory {
size_t vsz; // virtual memory (kb)
size_t rss; // physical memory (kb)
} dap_process_memory_t;
/**
* @brief get_proc_mem_current Get information about the amount of RAM consumed for the current process
* @return
*/
dap_process_memory_t get_proc_mem_current(void);
/**
* @brief get_proc_mem_by_pid Obtain information about the amount of RAM consumed for a particular process
* @param[in] pid PID
* @return
*/
dap_process_memory_t get_proc_mem_by_pid( uint32_t pid );
......@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0)
project(core_test)
file(GLOB SRCS *.c)
set(CMAKE_C_STANDARD 11)
file(GLOB SRCS *.c)
add_subdirectory(libdap-test)
......@@ -11,15 +11,55 @@ if(UNIX)
file(GLOB PLATROFM_DEP_SRC unix/*.c unix/*.h)
endif()
add_executable(${PROJECT_NAME} ${SRCS} ${PLATROFM_DEP_SRC})
add_executable(${PROJECT_NAME} ${SRCS} ${PLATROFM_DEP_SRC})
target_link_libraries(core_test dap_test dap_core pthread)
add_executable(rpmalloc_test
rpmalloc/test/main.c
rpmalloc/test/thread.c
rpmalloc/test/timer.c
)
target_link_libraries(rpmalloc_test dap_core pthread)
target_include_directories(rpmalloc_test PRIVATE rpmalloc/test/)
add_executable(rpmalloc_bench
rpmalloc/benchmark/main.c
rpmalloc/benchmark/benchmark.c
rpmalloc/test/thread.c
rpmalloc/test/timer.c
)
if(WIN32)
target_link_libraries(rpmalloc_bench dap_core m pthread ntdll psapi Shlwapi)
endif()
if(UNIX)
target_link_libraries(rpmalloc_bench dap_core m pthread)
endif()
target_include_directories(rpmalloc_bench PRIVATE rpmalloc/benchmark/ rpmalloc/test/)
add_executable(crtmalloc_bench
rpmalloc/benchmark/main.c
rpmalloc/benchmark/crt_benchmark.c
rpmalloc/test/thread.c
rpmalloc/test/timer.c
)
if(WIN32)
target_link_libraries(crtmalloc_bench dap_core m pthread ntdll psapi Shlwapi)
endif()
if(UNIX)
target_link_libraries(crtmalloc_bench dap_core m pthread)
endif()
target_include_directories(crtmalloc_bench PRIVATE rpmalloc/benchmark/ rpmalloc/test/)
add_test(
NAME core-test
COMMAND core_test
)
add_test(
NAME rpm-test
COMMAND rpmalloc
)
if(UNIX)
target_include_directories(${PROJECT_NAME} PRIVATE unix)
target_include_directories(${PROJECT_NAME} PRIVATE unix/linux)
......
#ifndef _WIN32
#include "dap_circular_test.h"
#include "dap_circular_buffer.h"
......@@ -212,3 +213,4 @@ void dap_circular_test_run()
dap_circular_load_test();
#endif
}
#endif
\ No newline at end of file
#include "dap_config_test.h"
#include "dap_common_test.h"
#ifndef _WIN32
#include "dap_network_monitor_test.h"
#endif
#include "dap_strfuncs_test.h"
#include "dap_common.h"
......
#include <rpmalloc.h>
#include <benchmark.h>
int
benchmark_initialize() {
return rpmalloc_initialize();
}
int
benchmark_finalize(void) {
rpmalloc_finalize();
return 0;
}
int
benchmark_thread_initialize(void) {
rpmalloc_thread_initialize();
return 0;
}
int
benchmark_thread_finalize(void) {
rpmalloc_thread_finalize();
return 0;
}
void
benchmark_thread_collect(void) {
rpmalloc_thread_collect();
}
void*
benchmark_malloc(size_t alignment, size_t size) {
//return rpmemalign(alignment, size);
return rpmalloc(size);
}
extern void
benchmark_free(void* ptr) {
rpfree(ptr);
}
const char*
benchmark_name(void) {
#if defined(ENABLE_UNLIMITED_CACHE)
return "rpmalloc-unlimit";
#elif defined(DISABLE_CACHE)
return "rpmalloc-nocache";
#elif defined(ENABLE_SPACE_PRIORITY_CACHE)
return "rpmalloc-size";
#else
return "rpmalloc";
#endif
}
#include <stdint.h>
#include <stddef.h>
#ifdef _MSC_VER
# define FORCENOINLINE __declspec(noinline)
#else
# define FORCENOINLINE __attribute__((__noinline__))
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern FORCENOINLINE int
benchmark_initialize(void);
extern FORCENOINLINE int
benchmark_finalize(void);
extern FORCENOINLINE int
benchmark_thread_initialize(void);
extern FORCENOINLINE int
benchmark_thread_finalize(void);
extern FORCENOINLINE void
benchmark_thread_collect(void);
extern FORCENOINLINE void*
benchmark_malloc(size_t alignment, size_t size);
extern FORCENOINLINE void
benchmark_free(void* ptr);
extern FORCENOINLINE const char*
benchmark_name(void);
#undef FORCENOINLINE
#ifdef __cplusplus
}
#endif
#include <benchmark.h>
#include <string.h>
#include <stdlib.h>
#ifndef __APPLE__
# include <malloc.h>
#endif
int
benchmark_initialize() {
return 0;
}
int
benchmark_finalize(void) {
return 0;
}
int
benchmark_thread_initialize(void) {
return 0;
}
int
benchmark_thread_finalize(void) {
return 0;
}
void*
benchmark_malloc(size_t alignment, size_t size) {
/*
#ifdef _WIN32
return _aligned_malloc(size, alignment ? alignment : 4);
#elif defined(__APPLE__)
if (alignment) {
void* ptr = 0;
posix_memalign(&ptr, alignment, size);
return ptr;
}
return malloc(size);
#else
return alignment ? memalign(alignment, size) : malloc(size);
#endif
*/
return malloc(size);
}
extern void
benchmark_free(void* ptr) {
/*
#ifdef _WIN32
_aligned_free(ptr);
#else
free(ptr);
#endif
*/
free(ptr);
}
const char*
benchmark_name(void) {
return "crt";
}
void
benchmark_thread_collect(void) {
}
#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)
# define _CRT_SECURE_NO_WARNINGS
#endif
#include <benchmark.h>
#include <thread.h>
#include <timer.h>
#include <atomic.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef _MSC_VER
# define PRIsize "Iu"
#else
# define PRIsize "zu"
#endif
#define MODE_RANDOM 0
#define MODE_FIXED 1
#define SIZE_MODE_EVEN 0
#define SIZE_MODE_LINEAR 1
#define SIZE_MODE_EXP 2
typedef struct benchmark_arg benchmark_arg;
typedef struct thread_pointers thread_pointers;
struct benchmark_arg {
size_t numthreads;
size_t index;
size_t mode;
size_t size_mode;
size_t cross_rate;
size_t loop_count;
size_t alloc_count;
size_t min_size;
size_t max_size;
size_t accumulator;
uint64_t ticks;
uint64_t mops;
atomicptr_t foreign;
atomic32_t allocated;
int32_t peak_allocated;
thread_arg thread_arg;
benchmark_arg* args;
};
struct thread_pointers {
void** pointers;
size_t count;
void* next;
atomic32_t* allocated;
};
static int benchmark_start;
static atomic32_t benchmark_threads_sync;
static atomic32_t cross_thread_counter;
static size_t alloc_scatter;
static size_t free_scatter;
//Fixed set of random numbers
static size_t random_size[2000] = {
42301, 6214, 74627, 93605, 82351, 93731, 23458, 99146, 63110, 22890, 29895, 62570, 91269, 60237, 99940, 64028, 95252, 82540, 20157, 90844,
80126, 82425, 74582, 70716, 69905, 55267, 81755, 85685, 17895, 97983, 39747, 45772, 71311, 84679, 10633, 96622, 15408, 38774, 31383, 79884,
59907, 69840, 70483, 1296, 30221, 32374, 1250, 6347, 55189, 30819, 88155, 18121, 34568, 90285, 27466, 21037, 54054, 3219, 32951, 78141,
45307, 29446, 68281, 95416, 58882, 67815, 98134, 2339, 97192, 32586, 89181, 84327, 21090, 73236, 34831, 66699, 98076, 76431, 82647, 94073,
97868, 72757, 1078, 60005, 57151, 30003, 22000, 71102, 87440, 77764, 28581, 20434, 10655, 3167, 50417, 88166, 76793, 14801, 90802, 74376,
31055, 49270, 1811, 99060, 66802, 94820, 37732, 40916, 89868, 46639, 91529, 74982, 44250, 89547, 91703, 93058, 71578, 85890, 77997, 36514,
31241, 56600, 45720, 69069, 83887, 4396, 91279, 86956, 69816, 79329, 94753, 80730, 71401, 34363, 28333, 90214, 54635, 78220, 89331, 46985,
57244, 31825, 55509, 56620, 53052, 93569, 5047, 96610, 39491, 66722, 42181, 58022, 47908, 48366, 50190, 25365, 77605, 87328, 33861, 95641,
17634, 5996, 23188, 97862, 14954, 47887, 39062, 43748, 21261, 68198, 33379, 84240, 73622, 80466, 11015, 56289, 79325, 49658, 79713, 43863,
60814, 24277, 19592, 89493, 82630, 95915, 48588, 16, 52733, 90874, 13240, 10894, 53813, 36264, 52999, 63240, 24143, 14198, 49899, 49364,
6764, 24958, 92996, 64150, 15801, 51305, 24669, 29519, 25870, 1776, 58258, 6464, 87940, 20386, 25, 70486, 98172, 11585, 10171, 5157,
7026, 38703, 63684, 86195, 95216, 78626, 79196, 67688, 56185, 8529, 41126, 16917, 70005, 82329, 67929, 68971, 10460, 29003, 8395, 24405,
3895, 93557, 34560, 71824, 44131, 48196, 87466, 34517, 17289, 67171, 47857, 98431, 34300, 75002, 32113, 46694, 50866, 31554, 46622, 83785,
79479, 58018, 58379, 28308, 97161, 67403, 85605, 60156, 82077, 9349, 8124, 76999, 99456, 17139, 91334, 932, 6836, 87864, 36635, 67900,
1529, 25061, 99041, 29110, 13974, 6517, 25337, 62714, 70512, 26081, 51977, 73938, 33913, 37983, 62940, 35631, 58798, 28189, 24009, 43543,
70222, 27381, 52259, 73386, 76069, 44347, 20046, 77165, 16347, 71345, 22879, 50230, 37429, 68115, 70002, 89613, 69316, 60787, 58923, 51295,
40284, 96998, 35508, 87173, 30133, 12407, 28667, 40805, 74633, 43303, 45342, 37778, 20934, 42910, 52266, 90173, 90947, 92460, 48039, 74023,
72091, 69029, 18019, 4521, 18104, 93795, 52380, 75881, 74698, 22760, 74315, 47044, 98770, 3146, 20657, 8725, 53817, 23967, 84651, 36005,
5331, 90981, 94529, 14026, 70400, 50286, 96587, 50844, 81796, 61110, 36776, 22624, 93962, 12909, 2490, 63451, 16560, 72472, 73436, 52307,
3521, 21280, 4160, 41326, 118, 52625, 78163, 91680, 97730, 44749, 72617, 6735, 38840, 30276, 21979, 3013, 98953, 38592, 63622, 14286,
26609, 45281, 96512, 1266, 15845, 13075, 63503, 55194, 57552, 347, 28896, 66327, 27818, 18314, 36467, 32685, 79917, 67475, 6482, 27502,
27895, 81645, 88851, 63447, 97801, 59402, 61663, 62266, 11723, 53664, 31123, 50583, 52561, 93801, 60911, 95186, 1523, 13959, 75972, 83397,
98867, 13677, 26462, 60373, 50646, 29253, 69891, 23620, 97227, 70196, 685, 46204, 72222, 76264, 79291, 32699, 88327, 950, 86803, 67946,
65417, 68473, 34521, 81124, 29656, 78884, 84, 11889, 93078, 63564, 93310, 73297, 11835, 14176, 9106, 51926, 49470, 90576, 54176, 79782,
68503, 65790, 25873, 71786, 48914, 1729, 81335, 59162, 96305, 46442, 19220, 64437, 80518, 59209, 56079, 83046, 2171, 11606, 65951, 44268,
75604, 75013, 336, 46693, 56101, 69968, 26795, 55351, 2926, 51530, 4574, 65148, 36917, 70077, 82638, 53513, 36907, 4469, 94792, 1248,
62907, 93233, 44798, 35998, 28031, 86786, 15581, 9546, 3067, 65953, 42127, 93017, 73500, 47493, 34152, 42566, 99077, 63233, 43072, 12191,
94924, 46953, 3641, 58957, 2971, 11982, 13551, 69306, 82293, 25723, 36647, 71048, 76501, 58174, 33792, 14359, 6882, 46120, 14201, 36645,
61886, 99622, 58258, 70316, 66228, 53947, 32478, 36276, 43902, 37878, 67333, 764, 83139, 86356, 7510, 61421, 45025, 9383, 38610, 93338,
36981, 85186, 53596, 18730, 11841, 79036, 61283, 86019, 87281, 71951, 95833, 84380, 19627, 9626, 97079, 72846, 20890, 29832, 93108, 7976,
62701, 17762, 21406, 70085, 40096, 19644, 57467, 25989, 32652, 23781, 591, 17087, 98696, 22640, 89961, 48544, 52682, 85931, 44827, 84419,
13891, 82403, 25915, 64876, 1092, 63868, 85965, 92472, 90590, 6645, 82417, 12635, 44125, 17017, 28025, 98728, 21429, 83742, 74565, 94388,
64814, 56266, 5530, 82469, 32833, 78753, 76171, 82758, 44987, 58705, 75785, 22708, 26724, 77955, 84443, 55066, 44605, 92125, 1225, 78907,
92345, 27374, 74731, 66764, 16133, 18429, 82040, 57794, 75229, 63230, 84688, 40516, 64711, 52314, 88591, 45887, 24727, 89863, 48026, 60643,
89466, 74838, 84712, 87291, 9805, 38722, 26550, 88896, 12322, 89245, 97273, 26602, 68253, 42065, 13831, 80784, 63967, 10057, 48370, 90991,
22164, 36692, 74691, 99469, 45153, 92702, 71622, 24003, 37475, 34155, 49983, 42747, 95163, 38986, 16633, 71055, 64068, 51835, 90775, 64181,
41674, 52152, 86065, 5176, 34552, 11045, 95891, 37901, 50122, 85359, 78631, 67931, 37636, 86730, 25850, 61677, 40015, 71019, 44850, 40945,
41041, 35159, 424, 53685, 97795, 77347, 31533, 94160, 27348, 63354, 26319, 40107, 93098, 87100, 85148, 95354, 7848, 26932, 59006, 12235,
17688, 81474, 78287, 84516, 61413, 68919, 38238, 57286, 54401, 18562, 25023, 88031, 54460, 58083, 83677, 18915, 31861, 85374, 87576, 59732,
38534, 65960, 54797, 77939, 38196, 87986, 75270, 10987, 96933, 43058, 82075, 75153, 13907, 74334, 35358, 53207, 83535, 54154, 70746, 2441,
51129, 32650, 97619, 91451, 76454, 16015, 40537, 14889, 16211, 63991, 97437, 32730, 5189, 79601, 67330, 95751, 62744, 19292, 75233, 18084,
37573, 40609, 42724, 93700, 33349, 20980, 40936, 94332, 22383, 1416, 72096, 52578, 50442, 30252, 11023, 46171, 36137, 65402, 99112, 67145,
22003, 54711, 69025, 10911, 26043, 60371, 38943, 23493, 88350, 71488, 58854, 18883, 21344, 86625, 58563, 41158, 18495, 48188, 942, 66045,
31255, 60368, 97474, 57619, 71639, 33064, 46735, 35467, 20637, 5041, 83609, 38123, 49670, 76412, 66878, 68287, 85916, 91311, 60061, 36099,
28495, 90856, 80025, 43741, 69408, 83471, 36181, 95935, 35330, 50544, 62083, 43570, 89033, 33867, 36027, 15254, 30197, 34458, 39364, 74865,
24812, 37022, 5954, 72980, 17251, 38420, 25210, 22888, 98643, 24684, 21543, 61874, 33534, 3202, 52652, 9661, 54900, 57117, 10607, 65871,
36892, 96446, 73068, 42280, 98969, 18166, 92463, 14979, 89072, 87142, 70769, 19354, 28149, 4840, 80852, 6332, 82116, 76515, 31224, 98426,
49973, 14581, 41012, 67269, 13159, 17895, 23331, 89950, 33053, 59052, 75888, 37680, 33410, 64278, 86775, 58344, 56445, 94767, 73347, 68064,
15906, 55708, 90978, 50676, 8131, 78335, 18423, 42033, 16784, 77371, 1779, 48452, 68259, 20383, 84196, 99516, 24988, 39436, 84941, 53532,
82934, 56012, 86532, 26276, 50102, 95350, 92394, 72824, 91468, 51207, 46677, 74147, 17396, 73951, 61050, 84191, 83137, 53207, 71850, 73087,
60066, 58680, 40205, 40903, 88778, 70023, 52889, 58243, 33085, 94965, 57111, 99423, 67011, 83618, 95835, 20599, 11034, 24152, 25380, 27540,
73219, 64152, 42450, 45985, 75245, 86575, 70394, 62669, 51370, 96295, 59743, 85700, 64532, 3403, 50481, 60582, 54875, 92772, 74427, 75038,
30668, 93071, 8085, 14688, 67282, 80982, 5324, 94615, 19268, 218, 63596, 74942, 8766, 48092, 7247, 35807, 1617, 67115, 39693, 31807,
50062, 43147, 24706, 80094, 75012, 10409, 4959, 51613, 24339, 41384, 68303, 29069, 9971, 66575, 71694, 54059, 47732, 76043, 13003, 71451,
72224, 31273, 66756, 52916, 73991, 22734, 41818, 15810, 28867, 44316, 74895, 60210, 92030, 54114, 98692, 92327, 60861, 64847, 44885, 53175,
40713, 66802, 194, 58710, 76645, 20203, 66546, 98777, 5418, 38879, 5263, 25406, 77388, 20914, 53056, 73849, 19265, 22355, 39435, 85914,
494, 19760, 20364, 903, 31617, 85835, 9835, 42381, 2442, 29412, 69033, 84184, 91987, 64246, 75227, 25048, 7900, 45999, 10019, 41123,
90308, 72412, 90235, 47141, 93995, 76257, 96004, 52493, 91642, 30038, 85834, 57092, 50095, 66871, 3419, 41040, 80452, 92769, 61837, 30941,
46436, 67831, 82636, 82534, 31242, 19962, 61308, 19447, 37538, 28143, 49442, 418, 5697, 91278, 75828, 23803, 99969, 95404, 54686, 10389,
49364, 57913, 23776, 37305, 99796, 52566, 55563, 34806, 81928, 74742, 59961, 8783, 78909, 5754, 53610, 46793, 75199, 39462, 41905, 86633,
2510, 17823, 11402, 57000, 71562, 57163, 12648, 73365, 24722, 1369, 33470, 24342, 60541, 98872, 83077, 28367, 28518, 17001, 76839, 48127,
98368, 49622, 21930, 59294, 81371, 14056, 20446, 90327, 9004, 31843, 35487, 93502, 19142, 17218, 43677, 42361, 8538, 24342, 45545, 17763,
95904, 83989, 93051, 86548, 17700, 40673, 30548, 25636, 84204, 85583, 48442, 45686, 57349, 67781, 99236, 60399, 26916, 20719, 12654, 29727,
54503, 21347, 15072, 65239, 73085, 97065, 34856, 57254, 20993, 87740, 2358, 7401, 34081, 84586, 77782, 38801, 66088, 71230, 97174, 50108,
25173, 62865, 87387, 90522, 60616, 82589, 19470, 66429, 72246, 30131, 99837, 38489, 83145, 87510, 78816, 99793, 1713, 93034, 63952, 14964,
99553, 6925, 8645, 90572, 49178, 38455, 97624, 91051, 39833, 11584, 50823, 52915, 37241, 38347, 51895, 97465, 37295, 86221, 69851, 12563,
63686, 6783, 23498, 9999, 48545, 99429, 36814, 20903, 13473, 89449, 55533, 30269, 92525, 78863, 32798, 98799, 6993, 37376, 24058, 82949,
19363, 26898, 58435, 40545, 21173, 24598, 74477, 80100, 82134, 10642, 91659, 45488, 77142, 12812, 5135, 30842, 52189, 38228, 57309, 17403,
11373, 21568, 60916, 36950, 55835, 55785, 23423, 89045, 42861, 98577, 27943, 75686, 59340, 20697, 23929, 59319, 87107, 34460, 71684, 26064,
77777, 89852, 7287, 31625, 35375, 92061, 43376, 26687, 44255, 28676, 97442, 55313, 31523, 65877, 9220, 55068, 99424, 18327, 66865, 37648,
28095, 61967, 28769, 81395, 3143, 90859, 37048, 40894, 64647, 23697, 79689, 62952, 28921, 37991, 21013, 86140, 1116, 56753, 93196, 16310,
98576, 72886, 46453, 8654, 50373, 99234, 6113, 97632, 62708, 61101, 33931, 87983, 30152, 45779, 98494, 55851, 76132, 32239, 87613, 55196,
2918, 12991, 44375, 69565, 49627, 17472, 60832, 5379, 47572, 45556, 74889, 95921, 62036, 96059, 3909, 52552, 55285, 20199, 25930, 99967,
68458, 7181, 61674, 18479, 80956, 29791, 25413, 91060, 99125, 23566, 51800, 50744, 89097, 31911, 70605, 42816, 66700, 46028, 48770, 63851,
64023, 35792, 27000, 52926, 1263, 87504, 42319, 90060, 22659, 6024, 99993, 88029, 99170, 72740, 15197, 90232, 59519, 92011, 84116, 17503,
33985, 45034, 2771, 59768, 20541, 76922, 97173, 59769, 70795, 10877, 25759, 64087, 96456, 76387, 25410, 82611, 47991, 94311, 18423, 23087,
20096, 59066, 7965, 29232, 37590, 32338, 74190, 16061, 87403, 86026, 26953, 24574, 18596, 53276, 81813, 84669, 59980, 26175, 35430, 10620,
50992, 46236, 57904, 56494, 23357, 93792, 42763, 43735, 39952, 53049, 94826, 68957, 62419, 30629, 72587, 76494, 66848, 95907, 6380, 98019,
81166, 82102, 86605, 15449, 6687, 69255, 56751, 52925, 84112, 67773, 59353, 15543, 36601, 3387, 79601, 83257, 49246, 76874, 56185, 793,
59738, 52149, 26613, 66307, 8234, 24065, 92988, 71189, 79064, 71518, 32203, 67702, 9543, 98621, 93075, 34932, 15937, 87714, 71486, 75270,
35729, 41826, 34535, 41952, 14408, 89411, 25440, 34547, 64653, 1052, 2091, 55795, 24536, 50576, 61768, 25630, 48362, 74274, 82782, 37429,
26345, 45185, 69504, 68905, 64931, 44057, 69869, 76963, 38003, 25727, 93730, 4799, 87357, 88156, 95203, 33217, 45889, 57727, 37421, 89580,
18862, 49760, 11881, 41838, 35387, 83063, 26361, 328, 6753, 87380, 70890, 28029, 74084, 42224, 8151, 29816, 90197, 76425, 14733, 82706,
59843, 98843, 74236, 7062, 61936, 69254, 64153, 72080, 72850, 88695, 5871, 72131, 1032, 4002, 99201, 7426, 88307, 3533, 34065, 72500,
44972, 97675, 72795, 8365, 37366, 62425, 22108, 83202, 29045, 1772, 88598, 81519, 41398, 16707, 34486, 2272, 92916, 47652, 99365, 95005,
39416, 77780, 28778, 75294, 81891, 95050, 37955, 28803, 19527, 67, 69492, 28635, 96926, 59073, 4874, 75644, 68338, 41368, 71873, 71289,
67924, 4733, 14164, 17892, 38828, 84141, 66764, 69505, 95978, 65222, 58685, 848, 24990, 72158, 34250, 66702, 16290, 41201, 48260, 62154,
34092, 30249, 20908, 54756, 93067, 45932, 58912, 4959, 61289, 46612, 36779, 97765, 59802, 43280, 39452, 6689, 36436, 32689, 27298, 90154,
52142, 27957, 32314, 41858, 50225, 88155, 84872, 66423, 47164, 50056, 70331, 45054, 35502, 41234, 95896, 41575, 14100, 4617, 68543, 37829,
5296, 11231, 89156, 86146, 72106, 83030, 35808, 64542, 28741, 15339, 26443, 10559, 52283, 56443, 45477, 37830, 28763, 98269, 47644, 20443,
14448, 44861, 6370, 80492, 85001, 72737, 51720, 31424, 99527, 22420, 38776, 62662, 27502, 36580, 3307, 83960, 81721, 51624, 64182, 45836,
1142, 33260, 75913, 94960, 16724, 92842, 89870, 92244, 24408, 19935, 94145, 25952, 60513, 98704, 69713, 46450, 9281, 16864, 7195, 96912,
24452, 93864, 23523, 10910, 71732, 27237, 25286, 40790, 66746, 88387, 35004, 99859, 70027, 31707, 41359, 59875, 52986, 24154, 39601, 13952,
14845, 36397, 78033, 97093, 43471, 79587, 17740, 2334, 20975, 70433, 48316, 20809, 89126, 346, 53303, 95290, 46100, 98972, 25761, 56374,
72548, 522, 60873, 56778, 69867, 58418, 11277, 6346, 76779, 35626, 41615, 77473, 41372, 27889, 38640, 64797, 74422, 59716, 6530, 17798,
86356, 6037, 51450, 32010, 5755, 56904, 35165, 5598, 17784, 92297, 61238, 76340, 53938, 93742, 25511, 33923, 77947, 91562, 99162, 90512,
96749, 60367, 32742, 47696, 35649, 35581, 91908, 23524, 73036, 58325, 1642, 84646, 91901, 25729, 82064, 81835, 19387, 61543, 68288, 95618,
86715, 75797, 29530, 40875, 68019, 23736, 46328, 47927, 7882, 77085, 20355, 74989, 71929, 24800, 13585, 29510, 81173, 53946, 12017, 57628,
67465, 1584, 68135, 48915, 36062, 15397, 32156, 98903, 63257, 92838, 39730, 51909, 86167, 3358, 1553, 54615, 83915, 4448, 25246, 28089,
7795, 71271, 7179, 37688, 76932, 54541, 9356, 95744, 60661, 31195, 17491, 43766, 45565, 17181, 47779, 22976, 32372, 30265, 10905, 21731
};
static size_t random_size_lin[2000];
static size_t random_size_exp[2000];
static size_t* random_size_arr;
static size_t num_alloc_ops[311] = {
58, 56, 65, 85, 83, 70, 33, 58, 69, 32,
70, 88, 58, 81, 98, 91, 57, 32, 42, 88,
84, 93, 80, 89, 34, 83, 86, 48, 32, 70,
77, 72, 56, 50, 81, 59, 95, 69, 96, 38,
44, 97, 74, 64, 85, 53, 85, 78, 58, 48,
61, 91, 89, 57, 68, 61, 64, 74, 46, 34,
48, 82, 86, 93, 37, 66, 59, 50, 47, 36,
79, 33, 71, 43, 63, 80, 57, 87, 65, 76,
59, 81, 50, 85, 75, 93, 95, 45, 61, 55,
32, 52, 68, 62, 97, 34, 65, 88, 97, 85,
88, 39, 44, 39, 55, 45, 40, 50, 44, 96,
94, 99, 91, 84, 48, 54, 35, 76, 91, 47,
59, 34, 69, 78, 71, 67, 81, 91, 43, 78,
41, 47, 49, 65, 77, 62, 31, 56, 50, 94,
40, 48, 42, 96, 63, 33, 42, 99, 81, 67,
74, 65, 83, 47, 46, 44, 41, 46, 50, 42,
31, 38, 79, 85, 47, 65, 94, 73, 49, 96,
30, 95, 59, 50, 32, 94, 71, 89, 85, 94,
83, 80, 68, 41, 84, 42, 64, 72, 96, 34,
67, 58, 79, 87, 80, 57, 95, 67, 99, 38,
81, 93, 65, 67, 35, 61, 80, 81, 59, 72,
46, 49, 39, 64, 51, 66, 36, 72, 78, 46,
61, 99, 32, 74, 78, 68, 34, 91, 65, 89,
74, 37, 38, 76, 30, 68, 58, 36, 39, 92,
73, 41, 57, 68, 68, 61, 64, 71, 58, 42,
36, 53, 58, 82, 67, 78, 59, 75, 96, 64,
92, 68, 89, 75, 73, 97, 72, 67, 32, 85,
47, 61, 36, 43, 86, 43, 68, 99, 43, 87,
39, 66, 78, 94, 60, 45, 35, 98, 36, 76,
91, 98, 87, 41, 35, 85, 55, 93, 60, 59,
34, 96, 86, 44, 84, 50, 89, 81, 56, 88,
74
};
static size_t num_free_ops[257] = {
94, 51, 88, 47, 51, 76, 99, 47, 48, 96,
74, 61, 51, 40, 76, 31, 41, 61, 93, 55,
78, 87, 83, 35, 35, 59, 58, 86, 97, 80,
35, 44, 83, 30, 98, 35, 71, 55, 54, 93,
95, 78, 49, 51, 89, 42, 85, 81, 47, 82,
32, 40, 38, 52, 98, 30, 86, 91, 91, 84,
65, 62, 93, 33, 93, 67, 59, 81, 96, 91,
70, 69, 42, 81, 94, 80, 66, 58, 71, 35,
40, 89, 42, 45, 68, 91, 40, 33, 57, 42,
61, 55, 54, 74, 88, 60, 84, 32, 49, 92,
69, 41, 82, 38, 93, 32, 74, 67, 32, 40,
35, 90, 99, 81, 43, 51, 92, 72, 49, 90,
54, 58, 88, 62, 66, 30, 52, 82, 84, 99,
58, 77, 95, 79, 50, 32, 45, 31, 98, 45,
38, 96, 37, 40, 69, 58, 65, 79, 44, 66,
60, 45, 83, 40, 55, 62, 58, 33, 39, 64,
56, 53, 64, 95, 47, 70, 73, 75, 98, 41,
77, 91, 32, 56, 35, 77, 73, 93, 60, 32,
47, 45, 30, 88, 68, 43, 32, 89, 57, 44,
38, 42, 52, 88, 65, 42, 40, 55, 65, 47,
31, 35, 64, 88, 63, 59, 61, 84, 52, 40,
67, 97, 92, 61, 93, 30, 87, 96, 96, 93,
76, 47, 43, 41, 49, 83, 69, 52, 82, 54,
50, 57, 79, 62, 85, 49, 98, 66, 34, 34,
65, 34, 44, 38, 87, 69, 82, 41, 74, 59,
97, 40, 56, 66, 91, 64, 93
};
static size_t primes[] = {
7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59,
61, 67, 71, 73, 79, 83, 89, 97,
101, 103, 107, 109, 113, 127,
131, 137, 139, 149, 151, 157,
163, 167, 173, 179, 181, 191,
193, 197, 199
};
#if defined(_WIN32)
#include <windows.h>
#include <psapi.h>
#elif defined(__APPLE__)
#include <mach/mach.h>
#include <mach/task.h>
#else
#include <unistd.h>
#include <sys/resource.h>
#endif
int
benchmark_run(int argc, char** argv);
static size_t
get_process_memory_usage(void) {
#if defined(_WIN32)
PROCESS_MEMORY_COUNTERS counters;
memset(&counters, 0, sizeof(counters));
counters.cb = sizeof(counters);
GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters));
return counters.WorkingSetSize;
#elif defined(__APPLE__)
struct task_basic_info info;
mach_msg_type_number_t info_count = TASK_BASIC_INFO_COUNT;
if (task_info(mach_task_self(), TASK_BASIC_INFO,
(task_info_t)&info, &info_count) != KERN_SUCCESS)
return 0;
return info.resident_size;
#else
long rss = 0L;
FILE* fp = fopen("/proc/self/statm", "r");
if (!fp)
return 0;
if (fscanf(fp, "%*s%ld", &rss) != 1)
rss = 0;
fclose(fp);
return (size_t)rss * (size_t)sysconf(_SC_PAGESIZE);
#endif
}
static size_t
get_process_peak_memory_usage(void) {
#if defined(_WIN32)
PROCESS_MEMORY_COUNTERS counters;
memset(&counters, 0, sizeof(counters));
counters.cb = sizeof(counters);
GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters));
return counters.PeakWorkingSetSize;
#else
struct rusage rusage;
getrusage(RUSAGE_SELF, &rusage);
#if defined(__APPLE__)
return (size_t)rusage.ru_maxrss;
#else
return (size_t)rusage.ru_maxrss * 1024;
#endif
#endif
}
static void
put_cross_thread_memory(atomicptr_t* ptr, thread_pointers* pointers) {
void* prev;
uintptr_t newval;
do {
prev = atomic_load_ptr(ptr);
pointers->next = (void*)((uintptr_t)prev & ~(uintptr_t)0xF);
newval = (uintptr_t)pointers | (atomic_incr32(&cross_thread_counter) & 0xF);
} while (!atomic_cas_ptr(ptr, (void*)newval, prev));
}
static thread_pointers*
get_cross_thread_memory(atomicptr_t* ptr) {
void* prev;
thread_pointers* current;
do {
prev = atomic_load_ptr(ptr);
current = (void*)((uintptr_t)prev & ~(uintptr_t)0xF);
} while (current && !atomic_cas_ptr(ptr, (void*)((uintptr_t)atomic_incr32(&cross_thread_counter) & 0xF), prev));
return current;
}
static void
benchmark_worker(void* argptr) {
benchmark_arg* arg = argptr;
thread_pointers* foreign = 0;
void** pointers;
const size_t random_size_count = (sizeof(random_size) / sizeof(random_size[0]));
const size_t alloc_ops_count = (sizeof(num_alloc_ops) / sizeof(num_alloc_ops[0]));
const size_t free_ops_count = (sizeof(num_free_ops) / sizeof(num_free_ops[0]));
const size_t alignment[3] = { 0, 8, 16 };
size_t alloc_idx = 0;
size_t free_idx = 0;
size_t iop;
uint64_t tick_start, ticks_elapsed;
int32_t allocated;
size_t cross_index = 0;
int aborted = 0;
benchmark_thread_initialize();
size_t pointers_size = sizeof(void*) * arg->alloc_count;
pointers = benchmark_malloc(16, pointers_size);
memset(pointers, 0, pointers_size);
atomic_add32(&arg->allocated, (int32_t)pointers_size);
while (!benchmark_start)
thread_sleep(10);
arg->ticks = 0;
arg->mops = 0;
for (size_t iter = 0; iter < 2; ++iter) {
size_t size_index = ((arg->index + 1) * ((iter + 1) * 37)) % random_size_count;
uint64_t iter_ticks_elapsed = 0;
int do_foreign = 1;
for (size_t iloop = 0; iloop < arg->loop_count; ++iloop) {
foreign = get_cross_thread_memory(&arg->foreign);
allocated = 0;
tick_start = timer_current();
const size_t free_op_count = num_free_ops[(iter + iloop) % free_ops_count];
const size_t alloc_op_count = num_alloc_ops[(iter + iloop) % alloc_ops_count];
for (iop = 0; iop < free_op_count; ++iop) {
if (pointers[free_idx]) {
allocated -= *(int32_t*)pointers[free_idx];
benchmark_free(pointers[free_idx]);
++arg->mops;
pointers[free_idx] = 0;
}
free_idx = (free_idx + free_scatter) % arg->alloc_count;
}
while (foreign) {
int32_t foreign_allocated = 0;
for (iop = 0; iop < foreign->count; ++iop) {
foreign_allocated -= *(int32_t*)foreign->pointers[iop];
benchmark_free(foreign->pointers[iop]);
++arg->mops;
}
void* next = foreign->next;
foreign_allocated -= (int32_t)(foreign->count * sizeof(void*) + sizeof(thread_pointers));
atomic_add32(foreign->allocated, foreign_allocated);
benchmark_free(foreign->pointers);
benchmark_free(foreign);
arg->mops += 2;
foreign = next;
}
for (iop = 0; iop < alloc_op_count; ++iop) {
if (pointers[alloc_idx]) {
allocated -= *(int32_t*)pointers[alloc_idx];
benchmark_free(pointers[alloc_idx]);
++arg->mops;
}
size_t size = arg->min_size;
if (arg->mode == MODE_RANDOM)
size = random_size_arr[(size_index + 2) % random_size_count];
pointers[alloc_idx] = benchmark_malloc((size < 4096) ? alignment[(size_index + iop) % 3] : 0, size);
//Make sure to write to each page to commit it for measuring memory usage
*(int32_t*)pointers[alloc_idx] = (int32_t)size;
size_t num_pages = (size - 1) / 4096;
for (size_t page = 1; page < num_pages; ++page)
*((char*)(pointers[alloc_idx]) + (page * 4096)) = 1;
*((char*)(pointers[alloc_idx]) + (size - 1)) = 1;
allocated += (int32_t)size;
++arg->mops;
alloc_idx = (alloc_idx + alloc_scatter) % arg->alloc_count;
size_index = (size_index + 1) % random_size_count;
}
foreign = 0;
if (arg->cross_rate && ((iloop % arg->cross_rate) == 0) && (do_foreign > 0)) {
foreign = benchmark_malloc(16, sizeof(thread_pointers));
foreign->count = alloc_op_count;
foreign->pointers = benchmark_malloc(16, sizeof(void*) * alloc_op_count);
foreign->allocated = &arg->allocated;
allocated += (int32_t)(alloc_op_count * sizeof(void*) + sizeof(thread_pointers));
arg->mops += 2;
for (iop = 0; iop < alloc_op_count; ++iop) {
size_t size = arg->min_size;
if (arg->mode == MODE_RANDOM)
size = random_size_arr[(size_index + 2) % random_size_count];
foreign->pointers[iop] = benchmark_malloc((size < 4096) ? alignment[(size_index + iop) % 3] : 0, size);
*(int32_t*)foreign->pointers[iop] = (int32_t)size;
size_t num_pages = (size - 1) / 4096;
for (size_t page = 1; page < num_pages; ++page)
*((char*)(foreign->pointers[iop]) + (page * 4096)) = 1;
*((char*)(foreign->pointers[iop]) + (size - 1)) = 1;
allocated += (int32_t)size;
++arg->mops;
size_index = (size_index + 1) % random_size_count;
}
}
ticks_elapsed = timer_current() - tick_start;
iter_ticks_elapsed += ticks_elapsed;
arg->ticks += ticks_elapsed;
int32_t current_allocated = atomic_add32(&arg->allocated, allocated);
if (arg->peak_allocated < current_allocated)
arg->peak_allocated = current_allocated;
if (foreign) {
cross_index = (cross_index + 1) % arg->numthreads;
if ((arg->numthreads > 1) && (cross_index == arg->index))
cross_index = (cross_index + 1) % arg->numthreads;
benchmark_arg* cross_arg = &arg->args[cross_index];
put_cross_thread_memory(&cross_arg->foreign, foreign);
foreign = 0;
}
if (atomic_load32(&benchmark_threads_sync) > 0)
do_foreign = 0; //one thread completed
if (timer_ticks_to_seconds(iter_ticks_elapsed) > 120) {
aborted = 1;
break;
}
}
/*
allocated = 0;
tick_start = timer_current();
for (size_t iptr = 0; iptr < arg->alloc_count; ++iptr) {
if (!pointers[iptr]) {
size_t size = arg->min_size;
if (arg->mode == MODE_RANDOM)
size = random_size_exp[(size_index + 2) % random_size_count];
pointers[iptr] = benchmark_malloc((size < 4096) ? alignment[size_index % 3] : 0, size);
*(int32_t*)pointers[iptr] = (int32_t)size;
size_t num_pages = (size - 1) / 4096;
for (size_t page = 1; page < num_pages; ++page)
*((char*)(pointers[iptr]) + (page * 4096)) = 1;
*((char*)(pointers[iptr]) + (size - 1)) = 1;
allocated += (int32_t)size;
++arg->mops;
size_index = (size_index + 1) % random_size_count;
}
}
ticks_elapsed = timer_current() - tick_start;
atomic_add32(&arg->allocated, allocated);
iter_ticks_elapsed += ticks_elapsed;
arg->ticks += ticks_elapsed;
*/
//Sync and allow main thread to gather allocation stats
atomic_incr32(&benchmark_threads_sync);
do {
foreign = get_cross_thread_memory(&arg->foreign);
if (foreign) {
tick_start = timer_current();
while (foreign) {
allocated = 0;
for (iop = 0; iop < foreign->count; ++iop) {
allocated -= *(int32_t*)foreign->pointers[iop];
benchmark_free(foreign->pointers[iop]);
++arg->mops;
}
void* next = foreign->next;
allocated -= (int32_t)(foreign->count * sizeof(void*) + sizeof(thread_pointers));
atomic_add32(foreign->allocated, allocated);
benchmark_free(foreign->pointers);
benchmark_free(foreign);
arg->mops += 2;
foreign = next;
}
ticks_elapsed = timer_current() - tick_start;
arg->ticks += ticks_elapsed;
}
thread_sleep(1);
thread_fence();
} while (atomic_load32(&benchmark_threads_sync));
allocated = 0;
tick_start = timer_current();
for (size_t iptr = 0; iptr < arg->alloc_count; ++iptr) {
if (pointers[iptr]) {
allocated -= *(int32_t*)pointers[iptr];
benchmark_free(pointers[iptr]);
++arg->mops;
pointers[iptr] = 0;
}
}
ticks_elapsed = timer_current() - tick_start;
atomic_add32(&arg->allocated, allocated);
iter_ticks_elapsed += ticks_elapsed;
arg->ticks += ticks_elapsed;
thread_sleep(10);
foreign = get_cross_thread_memory(&arg->foreign);
while (foreign) {
for (iop = 0; iop < foreign->count; ++iop)
benchmark_free(foreign->pointers[iop]);
void* next = foreign->next;
benchmark_free(foreign->pointers);
benchmark_free(foreign);
foreign = next;
}
printf(".");
fflush(stdout);
//printf(" %.2f ", timer_ticks_to_seconds(iter_ticks_elapsed));
//if (aborted)
// printf("(aborted) ");
//fflush(stdout);
aborted = 0;
}
//Sync threads
thread_sleep(1000);
thread_fence();
atomic_incr32(&benchmark_threads_sync);
do {
foreign = get_cross_thread_memory(&arg->foreign);
if (foreign) {
tick_start = timer_current();
while (foreign) {
allocated = 0;
for (iop = 0; iop < foreign->count; ++iop) {
allocated -= *(int32_t*)foreign->pointers[iop];
benchmark_free(foreign->pointers[iop]);
++arg->mops;
}
void* next = foreign->next;
allocated -= (int32_t)(foreign->count * sizeof(void*) + sizeof(thread_pointers));
atomic_add32(foreign->allocated, allocated);
benchmark_free(foreign->pointers);
benchmark_free(foreign);
arg->mops += 2;
foreign = next;
}
ticks_elapsed = timer_current() - tick_start;
arg->ticks += ticks_elapsed;
}
thread_sleep(1);
thread_fence();
} while (atomic_load32(&benchmark_threads_sync));
benchmark_free(pointers);
atomic_add32(&arg->allocated, -(int32_t)pointers_size);
benchmark_thread_finalize();
arg->accumulator += arg->mops;
thread_exit(0);
}
int
benchmark_run(int argc, char** argv) {
if (timer_initialize() < 0)
return -1;
if (benchmark_initialize() < 0)
return -2;
/**
if ((argc < 9) || (argc > 10)) {
printf("Usage: benchmark <thread count> <mode> <size mode> <cross rate> <loops> <allocs> <op count> <min size> <max size>\n"
" <thread count> Number of execution threads\n"
" <mode> 0 for random size [min, max], 1 for fixed size (min)\n"
" <size mode> 0 for even distribution, 1 for linear dropoff, 2 for exp dropoff\n"
" <cross rate> Rate of cross-thread deallocations (every n iterations), 0 for none\n"
" <loops> Number of loops in each iteration (0 for default, 800k)\n"
" <allocs> Number of concurrent allocations in each thread, (0 for default, 10k)\n"
" <op count> Iteration operation count\n"
" <min size> Minimum size for random mode, fixed size for fixed mode\n"
" <max size> Maximum size for random mode, ignored for fixed mode\n");
return -3;
}
**/
// size_t thread_count = (size_t)strtol(argv[1], 0, 10);
// size_t mode = (size_t)strtol(argv[2], 0, 10);
// size_t size_mode = (size_t)strtol(argv[3], 0, 10);
// size_t cross_rate = (size_t)strtol(argv[4], 0, 10);
// size_t loop_count = (size_t)strtol(argv[5], 0, 10);
// size_t alloc_count = (size_t)strtol(argv[6], 0, 10);
// size_t op_count = (size_t)strtol(argv[7], 0, 10);
// size_t min_size = (size_t)strtol(argv[8], 0, 10);
// size_t max_size = (argc > 9) ? (size_t)strtol(argv[9], 0, 10) : 0;
size_t thread_count = 1;
size_t mode = 0; // rand
size_t size_mode = 0; //
size_t cross_rate = 0;
size_t loop_count = 0;
size_t alloc_count = 0;
size_t op_count = 0;
size_t min_size = 16;
size_t max_size = 1024;
// if ((thread_count < 1) || (thread_count > 64)) {
// printf("Invalid thread count: %s\n", argv[1]);
// return -3;
// }
// if ((mode != MODE_RANDOM) && (mode != MODE_FIXED)) {
// printf("Invalid mode: %s\n", argv[2]);
// return -3;
// }
// if ((size_mode != SIZE_MODE_EVEN) && (size_mode != SIZE_MODE_LINEAR) && (size_mode != SIZE_MODE_EXP)) {
// printf("Invalid size mode: %s\n", argv[3]);
// return -3;
// }
if (!loop_count || (loop_count > 0x00FFFFFF))
loop_count = 32*1024;
if (!alloc_count || (alloc_count > 0x00FFFFFF))
alloc_count = 10*1024;
if (!op_count || (op_count > 0x00FFFFFF))
op_count = 1000;
// if ((mode == MODE_RANDOM) && (!max_size || (max_size < min_size))) {
// printf("Invalid min/max size for random mode: %s %s\n", argv[7], (argc > 8) ? argv[8] : "<missing>");
// printf("Invalid min/max size for random mode: max_size%u min_size %u\n", max_size, min_size );
// return -3;
// }
// if ((mode == MODE_FIXED) && !min_size) {
// printf("Invalid size for fixed mode: %s\n", argv[7]);
// return -3;
// }
if (thread_count == 1)
cross_rate = 0;
size_t iprime = 0;
alloc_scatter = primes[iprime];
while ((alloc_count % alloc_scatter) == 0)
alloc_scatter = primes[++iprime];
free_scatter = primes[++iprime];
while ((alloc_count % free_scatter) == 0)
free_scatter = primes[++iprime];
//Setup the random size tables
size_t size_range = max_size - min_size;
const size_t random_size_count = (sizeof(random_size) / sizeof(random_size[0]));
for (size_t ir = 0; ir < random_size_count; ++ir)
random_size[ir] = min_size + (size_t)round((double)size_range * ((double)random_size[ir] / 100000.0));
if (!size_range)
++size_range;
for (size_t ir = 0; ir < random_size_count; ++ir) {
double w0 = 1.0 - (double)(random_size[ir] - min_size) / (double)size_range;
double w1 = 1.0 - (double)(random_size[(ir + 1) % random_size_count] - min_size) / (double)size_range;
double even = (double)(random_size[(ir + 2) % random_size_count] - min_size);
random_size_lin[ir] = min_size + (size_t)(even * fabs((w0 + w1) - 1.0));
random_size_exp[ir] = min_size + (size_t)(even * (w0 * w1));
}
//Setup operation count
size_t alloc_op_count = (sizeof(num_alloc_ops) / sizeof(num_alloc_ops[0]));
for (size_t ic = 0; ic < alloc_op_count; ++ic)
num_alloc_ops[ic] = (size_t)((double)op_count * ((double)num_alloc_ops[ic] / 100.0));
size_t free_op_count = (sizeof(num_free_ops) / sizeof(num_free_ops[0]));
for (size_t ic = 0; ic < free_op_count; ++ic)
num_free_ops[ic] = (size_t)(0.8 * (double)op_count * ((double)num_free_ops[ic] / 100.0));
if (size_mode == SIZE_MODE_EVEN)
random_size_arr = random_size;
if (size_mode == SIZE_MODE_LINEAR)
random_size_arr = random_size_lin;
if (size_mode == SIZE_MODE_EXP)
random_size_arr = random_size_exp;
benchmark_arg* arg;
uintptr_t* thread_handle;
arg = benchmark_malloc(0, sizeof(benchmark_arg) * thread_count);
thread_handle = benchmark_malloc(0, sizeof(thread_handle) * thread_count);
benchmark_start = 0;
if (mode == MODE_RANDOM)
printf("%-12s %u threads random %s size [%u,%u] %u loops %u allocs %u ops: ",
benchmark_name(),
(unsigned int)thread_count,
(size_mode == SIZE_MODE_EVEN) ? "even" : ((size_mode == SIZE_MODE_LINEAR) ? "linear" : "exp"),
(unsigned int)min_size, (unsigned int)max_size,
(unsigned int)loop_count, (unsigned int)alloc_count, (unsigned int)op_count);
else
printf("%-12s %u threads fixed size [%u] %u loops %u allocs %u ops: ",
benchmark_name(),
(unsigned int)thread_count,
(unsigned int)min_size,
(unsigned int)loop_count, (unsigned int)alloc_count, (unsigned int)op_count);
fflush(stdout);
size_t memory_usage = 0;
size_t cur_memory_usage = 0;
size_t sample_allocated = 0;
size_t cur_allocated = 0;
uint64_t mops = 0;
uint64_t ticks = 0;
for (size_t iter = 0; iter < 2; ++iter) {
benchmark_start = 0;
atomic_store32(&benchmark_threads_sync, 0);
thread_fence();
for (size_t ithread = 0; ithread < thread_count; ++ithread) {
arg[ithread].numthreads = thread_count;
arg[ithread].index = ithread;
arg[ithread].mode = mode;
arg[ithread].size_mode = size_mode;
arg[ithread].cross_rate = cross_rate;
arg[ithread].loop_count = loop_count;
arg[ithread].alloc_count = alloc_count;
arg[ithread].min_size = min_size;
arg[ithread].max_size = max_size;
arg[ithread].thread_arg.fn = benchmark_worker;
arg[ithread].thread_arg.arg = &arg[ithread];
atomic_store_ptr(&arg[ithread].foreign, 0);
atomic_store32(&arg[ithread].allocated, 0);
arg[ithread].peak_allocated = 0;
arg[ithread].args = arg;
thread_fence();
thread_handle[ithread] = thread_run(&arg[ithread].thread_arg);
}
thread_sleep(1000);
benchmark_start = 1;
thread_fence();
while (atomic_load32(&benchmark_threads_sync) < (int32_t)thread_count) {
thread_sleep(1000);
thread_fence();
}
thread_sleep(1000);
thread_fence();
cur_allocated = 0;
for (size_t ithread = 0; ithread < thread_count; ++ithread) {
size_t thread_allocated = (size_t)atomic_load32(&arg[ithread].allocated);
cur_allocated += thread_allocated;
}
cur_memory_usage = get_process_memory_usage();
if ((cur_allocated > sample_allocated) || (cur_memory_usage > memory_usage)) {
sample_allocated = cur_allocated;
memory_usage = cur_memory_usage;
}
atomic_store32(&benchmark_threads_sync, 0);
thread_fence();
thread_sleep(1000);
while (atomic_load32(&benchmark_threads_sync) < (int32_t)thread_count) {
thread_sleep(1000);
thread_fence();
}
thread_sleep(1000);
thread_fence();
cur_allocated = 0;
for (size_t ithread = 0; ithread < thread_count; ++ithread) {
size_t thread_allocated = (size_t)atomic_load32(&arg[ithread].allocated);
cur_allocated += thread_allocated;
}
cur_memory_usage = get_process_memory_usage();
if ((cur_allocated > sample_allocated) || (cur_memory_usage > memory_usage)) {
sample_allocated = cur_allocated;
memory_usage = cur_memory_usage;
}
atomic_store32(&benchmark_threads_sync, 0);
thread_fence();
thread_sleep(1000);
while (atomic_load32(&benchmark_threads_sync) < (int32_t)thread_count) {
thread_sleep(1000);
thread_fence();
}
thread_sleep(1000);
thread_fence();
atomic_store32(&benchmark_threads_sync, 0);
thread_fence();
for (size_t ithread = 0; ithread < thread_count; ++ithread) {
thread_join(thread_handle[ithread]);
ticks += arg[ithread].ticks;
mops += arg[ithread].mops;
if (!arg[ithread].accumulator)
exit(-1);
}
}
if (!ticks)
ticks = 1;
benchmark_free(thread_handle);
benchmark_free(arg);
FILE* fd;
char filebuf[64];
if (mode == 0)
sprintf(filebuf, "benchmark-random-%u-%u-%u-%s.txt",
(unsigned int)thread_count, (unsigned int)min_size,
(unsigned int)max_size, benchmark_name());
else
sprintf(filebuf, "benchmark-fixed-%u-%u-%s.txt",
(unsigned int)thread_count, (unsigned int)min_size,
benchmark_name());
fd = fopen(filebuf, "w+b");
size_t peak_allocated = get_process_peak_memory_usage();
double time_elapsed = timer_ticks_to_seconds(ticks);
double average_mops = (double)mops / time_elapsed;
char linebuf[128];
int len = snprintf(linebuf, sizeof(linebuf), "%u,%" PRIsize ",%" PRIsize ",%" PRIsize "\n",
(unsigned int)average_mops,
peak_allocated,
sample_allocated,
memory_usage);
if (fd) {
fwrite(linebuf, (len > 0) ? (size_t)len : 0, 1, fd);
fflush(fd);
}
printf("%u memory ops/CPU second (%uMiB peak, %uMiB -> %uMiB bytes sample, %.0f%% overhead)\n",
(unsigned int)average_mops, (unsigned int)(peak_allocated / (1024 * 1024)),
(unsigned int)(sample_allocated / (1024 * 1024)), (unsigned int)(memory_usage / (1024 * 1024)),
100.0 * ((double)memory_usage - (double)sample_allocated) / (double)sample_allocated);
fflush(stdout);
if (fd)
fclose(fd);
if (benchmark_finalize() < 0)
return -4;
return 0;
}
#if ( defined( __APPLE__ ) && __APPLE__ )
# include <TargetConditionals.h>
# if defined( __IPHONE__ ) || ( defined( TARGET_OS_IPHONE ) && TARGET_OS_IPHONE ) || ( defined( TARGET_IPHONE_SIMULATOR ) && TARGET_IPHONE_SIMULATOR )
# define NO_MAIN 1
# endif
#endif
#if !defined(NO_MAIN)
int main(int argc, char** argv) {
return benchmark_run(argc, argv);
}
#endif
#include <stdint.h>
#if defined( __x86_64__ ) || defined( _M_AMD64 ) || defined( _M_X64 ) || defined( _AMD64_ ) || defined( __arm64__ ) || defined( __aarch64__ )
# define ARCH_64BIT 1
#else
# define ARCH_64BIT 0
#endif
#ifdef _MSC_VER
# define ALIGNED_STRUCT(name, alignment) __declspec(align(alignment)) struct name
#else
# define ALIGNED_STRUCT(name, alignment) struct __attribute__((__aligned__(alignment))) name
#endif
ALIGNED_STRUCT(atomicptr_t, 8) {
void* nonatomic;
};
typedef struct atomicptr_t atomicptr_t;
static void*
atomic_load_ptr(atomicptr_t* src) {
return src->nonatomic;
}
static void
atomic_store_ptr(atomicptr_t* dst, void* val) {
dst->nonatomic = val;
}
ALIGNED_STRUCT(atomic32_t, 4) {
int32_t nonatomic;
};
typedef struct atomic32_t atomic32_t;
static int32_t
atomic_load32(atomic32_t* src) {
return src->nonatomic;
}
static void
atomic_store32(atomic32_t* dst, int32_t val) {
dst->nonatomic = val;
}
static int32_t
atomic_incr32(atomic32_t* val) {
#ifdef _MSC_VER
int32_t old = (int32_t)_InterlockedExchangeAdd((volatile long*)&val->nonatomic, 1);
return (old + 1);
#else
return __sync_add_and_fetch(&val->nonatomic, 1);
#endif
}
static int32_t
atomic_add32(atomic32_t* val, int32_t add) {
#ifdef _MSC_VER
int32_t old = (int32_t)_InterlockedExchangeAdd((volatile long*)&val->nonatomic, add);
return (old + add);
#else
return __sync_add_and_fetch(&val->nonatomic, add);
#endif
}
static int
atomic_cas_ptr(atomicptr_t* dst, void* val, void* ref) {
#ifdef _MSC_VER
# if ARCH_64BIT
return (_InterlockedCompareExchange64((volatile long long*)&dst->nonatomic,
(long long)val, (long long)ref) == (long long)ref) ? 1 : 0;
# else
return (_InterlockedCompareExchange((volatile long*)&dst->nonatomic,
(long)val, (long)ref) == (long)ref) ? 1 : 0;
# endif
#else
return __sync_bool_compare_and_swap(&dst->nonatomic, ref, val);
#endif
}
#undef ARCH_64BIT
#undef ALIGNED_STRUCT