Skip to content

Commit

Permalink
add check for sufficient free memory, update exes, update ReadMe
Browse files Browse the repository at this point in the history
  • Loading branch information
Tinram committed Dec 4, 2016
1 parent 3b5a5d7 commit f4dcf0b
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 8 deletions.
14 changes: 11 additions & 3 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
### 64-bit multi-threading random data generator


##### RND64 v.0.32
##### RND64 v.0.33

##### Linux and Windows


## Purpose

Generate large files (non-sparse) and large streams of random data (4GB+) at fast generation rates (~1.25GB/sec on modest CPUs such as Intel i3 desktop / Intel Xeon AWS microinstance (running Linux)).
Generate large files (non-sparse) and large streams of random data (4GB+) at fast generation rates (~1.25GB/sec (under Linux using -f option) on modest CPUs such as Intel i3 desktop / Intel Xeon AWS microinstance).


## OS Support
Expand Down Expand Up @@ -50,7 +50,7 @@ Windows x64
rnd64 -a 1k | nc 192.168.1.20 80 pipe 1kB of random bytes to 'netcat' to send to 192.168.1.20 on port 80


###### WARNING: Be careful of the amount of data generated in regards to the available memory of the PC for creating data, and the age and performance of the PC's hard-drive for writing data. A file dump of more than 1GB can be brutal.
###### WARNING: Be careful of the amount of data generated in regards to the available memory of the PC for creating data, and the age and performance of the PC's hard-drive for writing data. A file dump of more than 1GB can be brutal. On Linux, a large <size> gigabyte value that works on a freshly booted system, may not work on the same busy long-running system, because of caching and application requirements.


## Build
Expand Down Expand Up @@ -92,6 +92,14 @@ Move the rnd64 executable to a location such as */usr/local/bin* (location must
(Windows/Super key + Break) > Advanced tab > Environmental Variables button > click Path line > Edit button > Variable value - append at the end of existing line information: *C:\directory paths\to rnd64.exe\;*


## Credits

+ Aleksandr Sergeev: testing, recommendations.
+ Travis Gockel: Linux free memory report.
+ MSDN: Windows crypto and free system memory.
+ Ben Alpert: microsecond timer.


## License

RND64 is released under the [GPL v.3](https://www.gnu.org/licenses/gpl-3.0.html).
Binary file modified bin/rnd64
Binary file not shown.
Binary file modified bin/rnd64.exe
Binary file not shown.
63 changes: 60 additions & 3 deletions rnd64.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*
* @author Martin Latter <copysense.co.uk>
* @copyright Martin Latter, April 2014
* @version 0.32 mt
* @version 0.33 mt
* @license GNU GPL version 3.0 (GPL v3); https://www.gnu.org/licenses/gpl-3.0.html
* @link https://github.com/Tinram/RND64.git
*
Expand Down Expand Up @@ -76,6 +76,8 @@ int main(int iArgCount, char* aArgV[]) {
unsigned int i;
unsigned int j;
unsigned int iFIndex = 0;
unsigned int iUnavailMB;
unsigned long long iFreeMemory;
char cUnit;
char sFileSize[iSizeLen];
char* aBuffer[iNumThreads];
Expand Down Expand Up @@ -133,6 +135,16 @@ int main(int iArgCount, char* aArgV[]) {
return EXIT_FAILURE;
}

iFreeMemory = getFreeSystemMemory();

/* bail out if required memory exceeds, or is likely to dangerously exhaust, free memory */
if (iTotalBytes > iFreeMemory) {

iUnavailMB = iTotalBytes / 1024 / 1024;
fprintf(stderr,"\n%s: insufficient memory to allocate %u MB.\nPlease use a smaller <size>\n\n", pFilename, iUnavailMB);
return EXIT_FAILURE;
}

/* set global variable for thread functions */
iBytes = iTotalBytes / iNumThreads;

Expand Down Expand Up @@ -163,7 +175,8 @@ int main(int iArgCount, char* aArgV[]) {

if (aBuffer[i] == NULL) {

fprintf(stderr, "\n%s: insufficient memory to allocate %"PRId64" bytes.\n\n", pFilename, iBytesLocal);
iUnavailMB = iBytesLocal / 1024 / 1024;
fprintf(stderr, "\n%s: insufficient memory to allocate %u MB in thread buffer.\n\n", pFilename, iUnavailMB);

for (j = 0; j <= i; j++) { /* deallocate up to this i */
free(aBuffer[j]);
Expand All @@ -189,7 +202,7 @@ int main(int iArgCount, char* aArgV[]) {
#endif
}

/* create stream if no specified <file> argument, then exit */
/* create stream if no specified [file] argument, then exit */
if (aArgV[3] == NULL) {

for (i = 0; i < iNumThreads; i++) {
Expand Down Expand Up @@ -453,6 +466,50 @@ int main(int iArgCount, char* aArgV[]) {
#endif


/**
* Attempt to find free memory available for allocation.
* Windows reporting through MEMORYSTATUSEX seems accurate.
* Linux is trickier: what is reported as free in conjunction with considerable buffering and caching.
*
* @return integer
*/

#ifdef __linux

unsigned long long getFreeSystemMemory() {

/**
* Derived from an example by Travis Gockel.
* Linux apparently provides only total and free (unbuffered) memory values reliably.
* Found that 0.5GB margin on kernel 4.4 with 6GB RAM is not quite enough (e.g 5g okay, 5300m locks system).
*/

long iPages;
long iPageSize;

iPages = sysconf(_SC_PHYS_PAGES);
iPageSize = sysconf(_SC_PAGE_SIZE);

return (iPages * iPageSize) - cSafetyChunk; /* assumes system has at least 1GB total memory */
}

#elif _WIN64

unsigned long long getFreeSystemMemory() {

/* from MSDN */

MEMORYSTATUSEX stMemState;

stMemState.dwLength = sizeof(stMemState);
GlobalMemoryStatusEx(&stMemState);

return stMemState.ullAvailPhys;
}

#endif


/**
* Display menu.
*
Expand Down
7 changes: 5 additions & 2 deletions rnd64.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*
* @author Martin Latter <copysense.co.uk>
* @copyright Martin Latter, April 2014
* @version 0.32 mt
* @version 0.33 mt
* @license GNU GPL version 3.0 (GPL v3); http://www.gnu.org/licenses/gpl.html
* @link https://github.com/Tinram/RND64.git
*
Expand All @@ -25,21 +25,23 @@
#ifdef __linux
#include <pthread.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#define RANDOM_PATH "/dev/urandom"
#elif _WIN64
#include <windows.h>
#include <wincrypt.h> /* CryptAcquireContext, CryptGenRandom */
#endif


#define RND64_VERSION "0.32 mt"
#define RND64_VERSION "0.33 mt"


#ifdef __linux
void* generateAll(void* buff);
void* generateRestricted(void* buff);
void* generateSingleChar(void* buff);
void* generateCrypto(void* buff);
const unsigned long cSafetyChunk = 786432000; /* 0.75 MB non-allocation margin */
#elif _WIN64
DWORD WINAPI generateAll(LPVOID buff);
DWORD WINAPI generateRestricted(LPVOID buff);
Expand All @@ -48,6 +50,7 @@
#endif


unsigned long long getFreeSystemMemory();
void menu(char* pFilename);


Expand Down

0 comments on commit f4dcf0b

Please sign in to comment.