Call to SetSystemFileCacheSize is failing in C++ - c++

The following call to SetSystemFileCacheSize() fails, however it passes if replace "FILE_CACHE_MIN_HARD_ENABLE " with 0.
What am I doing wrong?
SIZE_T dwMinimumFileCacheSize = 1048576; // Exact number reported by SetSystemFileCacheSize.
SIZE_T dwMaximumFileCacheSize = 1099511627776; // Exact number reported by SetSystemFileCacheSize.
int result = SetSystemFileCacheSize(
dwMinimumFileCacheSize, // dwMinimumWorkingSetSize
dwMaximumFileCacheSize, // dwMaximumWorkingSetSize,
FILE_CACHE_MIN_HARD_ENABLE // Works if this flag is set to 0.
);
if (result == 0)
{
// Error is "5" if it fails.
wprintf(L" Error E2469: Could not set size of system cache, error %u.\n", GetLastError());
}
else
{
wprintf(L" Pass.\n");
}

It turns out that dwMinimumFileCacheSize must be 64KB less than dwMaximumFileCacheSize, if FILE_CACHE_MIN_HARD_ENABLE is enabled.
Here is the fix:
int result = SetSystemFileCacheSize(
dwMinimumFileCacheSize - 64 * 1024, // dwMinimumWorkingSetSize
dwMaximumFileCacheSize, // dwMaximumWorkingSetSize,
FILE_CACHE_MIN_HARD_ENABLE // Works if this flag is set to 0.
);

Related

What's the actual size of PSAPI_WORKING_SET_INFORMATION buffer used in QueryWorkingSet function of PSAPI.h

I'd like to use the function QueryWorkingSet available in PSAPI, but I'm having trouble to actually define the size of the buffer pv. Here is the code :
#include <Windows.h>
#include <Psapi.h>
#include <iostream>
void testQueryWorkingSet()
{
unsigned int counter;
HANDLE thisProcess = GetCurrentProcess();
SYSTEM_INFO si;
PSAPI_WORKING_SET_INFORMATION wsi, wsi2;
GetSystemInfo(&si);
QueryWorkingSet(thisProcess, &wsi, sizeof(wsi));
DWORD wsi2_buffer_size = (wsi.NumberOfEntries) * sizeof(PSAPI_WORKING_SET_BLOCK);
if (!QueryWorkingSet(thisProcess, &wsi2, wsi2_buffer_size))
{
std::cout << "ERROR CODE : " << GetLastError() << std::endl;
abort();
}
}
int main(int argc, char * argv[])
{
testQueryWorkingSet();
int* test = new int[1000000];
testQueryWorkingSet();
}
I keep ending up with abort() being called and either an error code 24 or 998 during the first call to testQueryWorkingSet(). that I interpret respectively as : wsi2_buffer_size is too low and wsi2_buffer_size is too big.
Now I have no idea of the value this variable should take, I tried :
counting everything including the NumberOfEntries field, that is DWORD wsi2_buffer_size = sizeof(wsi.NumberOfEntries) + wsi.NumberOfEntries * sizeof(PSAPI_WORKING_SET_BLOCK); => error 998;
counting only the number of entries, that is the code given above => error 998;
the size of the variable wsi2, that is DWORD wsi2_buffer_size = sizeof(wsi2); => error 24;
There has to be something I do not understand in the way we're supposed to use this function but I can't find what. I tried to adapt the code given there, that is :
#include <Windows.h>
#include <Psapi.h>
#include <iostream>
void testQueryWorkingSet()
{
unsigned int counter;
HANDLE thisProcess = GetCurrentProcess();
SYSTEM_INFO si;
PSAPI_WORKING_SET_INFORMATION wsi_1, * wsi;
DWORD wsi_size;
GetSystemInfo(&si);
wsi_1.NumberOfEntries = 0;
QueryWorkingSet(thisProcess, (LPVOID)&wsi_1, sizeof(wsi));
#if !defined(_WIN64)
wsi_1.NumberOfEntries--;
#endif
wsi_size = sizeof(PSAPI_WORKING_SET_INFORMATION)
+ sizeof(PSAPI_WORKING_SET_BLOCK) * wsi_1.NumberOfEntries;
wsi = (PSAPI_WORKING_SET_INFORMATION*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, wsi_size);
if (!QueryWorkingSet(thisProcess, (LPVOID)wsi, wsi_size)) {
printf("# Second QueryWorkingSet failed: %lu\n"
, GetLastError());
abort();
}
}
int main(int argc, char * argv[])
{
testQueryWorkingSet();
int* test = new int[1000000];
testQueryWorkingSet();
}
This code is working for only 1 call to testQueryWorkingSet(), the second one is aborting with error code 24. Here are the questions in brief :
How would you use QueryWorkingSet in a function that you could call multiple times successively?
What is representing the value of the parameter cb of the documentation given a PSAPI_WORKING_SET_INFORMATION?
Both examples are completely ignoring the return value and error code of the 1st call of QueryWorkingSet(). You are doing error handling only on the 2nd call.
Your 1st example fails because you are not taking into account the entire size of the PSAPI_WORKING_SET_INFORMATION when calculating wsi2_buffer_size for the 2nd call of QueryWorkingSet(). Even if the 1st call were successful, you are not allocating any additional memory for the 2nd call to fill in, if the NumberOfEntries returned is > 1.
Your 2nd example is passing in the wrong buffer size value to the cb parameter of the 1st call of QueryWorkingSet(). You are passing in just the size of a single pointer, not the size of the entire PSAPI_WORKING_SET_INFORMATION. Error 24 is ERROR_BAD_LENGTH. You need to use sizeof(wsi_1) instead of sizeof(wsi).
I would suggest calling QueryWorkingSet() in a loop, in case the working set actually changes in between the call to query its size and the call to get its data.
Also, be sure you free the memory you allocate when you are done using it.
With that said, try something more life this:
void testQueryWorkingSet()
{
HANDLE thisProcess = GetCurrentProcess();
PSAPI_WORKING_SET_INFORMATION *wsi, *wsi_new;
DWORD wsi_size;
ULONG_PTR count = 1; // or whatever initial size you want...
do
{
wsi_size = offsetof(PSAPI_WORKING_SET_INFORMATION, WorkingSetInfo[count]);
wsi = (PSAPI_WORKING_SET_INFORMATION*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, wsi_size);
if (!wsi)
{
printf("HeapAlloc failed: %lu\n", GetLastError());
abort();
}
if (QueryWorkingSet(thisProcess, wsi, wsi_size))
break;
if (GetLastError() != ERROR_BAD_LENGTH)
{
printf("QueryWorkingSet failed: %lu\n", GetLastError());
HeapFree(GetProcessHeap(), 0, wsi);
abort();
}
count = wsi->NumberOfEntries;
HeapFree(GetProcessHeap(), 0, wsi);
}
while (true);
// use wsi as needed...
HeapFree(GetProcessHeap(), 0, wsi);
}

Visual C++ 19.10.25019 – C++ compiler bug?

I have a function for receiving messages of variable length through TCP. The send-function creates a buffer, puts the length of message in first four bytes, fills the rest with the message, and sends by parts. But the receive-function was receiving 4 bytes less. And suddenly, when I put one printf, everything is working as it should.
bool TCP_Server::recvMsg(SOCKET client_sock, std::unique_ptr<char[]>& buf_ptr, int* buf_len)
{
int msg_len;
int rcvd = 0, tmp;////
/* get msg len */
if((tmp = recv(client_sock, (char*)&msg_len, sizeof(msg_len), 0)) == -1)
{
handle_error("recv");
return false;
}
*buf_len = msg_len;
printf("msg_len = %d\n", msg_len); //
printf("tmp getting msg_len = %d\n", tmp);//
rcvd += tmp;//
buf_ptr.reset((char*)malloc(msg_len));
if(buf_ptr.get() == nullptr) // not enough memory
{
handle_error("malloc");
return false;
}
/* get msg of specified len */
/* get by biggest available pieces */
int i = 1;
while(int(msg_len - 1440 * i) > 0)
{
char* cur_ptr = buf_ptr.get() + 1440 * (i - 1);
if((tmp=recv(client_sock, cur_ptr, 1440, 0)) == -1)
{
handle_error("recv");
return false;
}
printf("1440 = %d\n", tmp); // doesn't work if I comment this line
rcvd += tmp;
i++;
}
int rest = msg_len - 1440 * (i - 1);
/* get the rest */
if((tmp = recv(client_sock, buf_ptr.get() + msg_len - rest, rest, 0)) == -1)
{
handle_error("(recv)reading with msg_len");
return false;
}
rcvd += tmp;//
printf("rcvd = %d\n", rcvd);//
return true;
}
In sum, if I comment printf("1440 = %d\n", tmp);, the function is receiving 4 bytes less.
I'm compiling with x86 Debug.
Here's the dissimilar lines in asm(/FA flag): http://text-share.com/view/50743a5e
But I don't see anything suspicious
printf writes to the console, which is a fairly slow operation, relatively speaking. The extra delay it produces might easily change how much data has arrived in the buffer when you call recv.
As Tulon comments, reads from TCP streams can be any length. TCP doesn't preserve message boundaries, so they don't necessarily match the send sizes on the other end. And if less data has been sent across the network than you asked to read, you'll get what is available.
Solution: stop thinking of 1440 byte chunks. Get rid of i and simply compare rcvd to msg_len.

parsing complete messages from serial port

I am trying to read complete messages from my GPS via serial port.
The message I am looking for starts with:
0xB5 0x62 0x02 0x13
So I read from the serial port like so
while (running !=0)
{
int n = read (fd, input_buffer, sizeof input_buffer);
for (int i=0; i<BUFFER_SIZE; i++)
{
if (input_buffer[i]==0xB5 && input_buffer[i+1]== 0x62 && input_buffer[i+2]== 0x02 && input_buffer[i+3]== 0x13 && i<(BUFFER_SIZE-1) )
{
// process the message.
}
}
The problem I am having is that I need to get a complete message. Half of a message could be in the buffer one iteration. And the other half could come into the message the next iteration.
Somebody suggested that free the buffer up from the complete message. And then I move the rest of data in the buffer to the beginning of the buffer.
How do I do that or any other way that make sure I get every complete selected message that comes in?
edit//
I want a particular class and ID. But I can also read in the length
To minimize the overhead of making many read() syscalls of small byte counts, use an intermediate buffer in your code.
The read()s should be in blocking mode to avoid a return code of zero bytes.
#define BLEN 1024
unsigned char rbuf[BLEN];
unsigned char *rp = &rbuf[BLEN];
int bufcnt = 0;
static unsigned char getbyte(void)
{
if ((rp - rbuf) >= bufcnt) {
/* buffer needs refill */
bufcnt = read(fd, rbuf, BLEN);
if (bufcnt <= 0) {
/* report error, then abort */
}
rp = rbuf;
}
return *rp++;
}
For proper termios initialization code for the serial terminal, see this answer. You should increase the VMIN parameter to something closer to the BLEN value.
Now you can conveniently access the received data a byte at a time with minimal performance penalty.
#define MLEN 1024 /* choose appropriate value for message protocol */
unsigned char mesg[MLEN];
while (1) {
while (getbyte() != 0xB5)
/* hunt for 1st sync */ ;
retry_sync:
if ((sync = getbyte()) != 0x62) {
if (sync == 0xB5)
goto retry_sync;
else
continue; /* restart sync hunt */
}
class = getbyte();
id = getbyte();
length = getbyte();
length += getbyte() << 8;
if (length > MLEN) {
/* report error, then restart sync hunt */
continue;
}
for (i = 0; i < length; i++) {
mesg[i] = getbyte();
/* accumulate checksum */
}
chka = getbyte();
chkb = getbyte();
if ( /* valid checksum */ )
break; /* verified message */
/* report error, and restart sync hunt */
}
/* process the message */
switch (class) {
case 0x02:
if (id == 0x13) {
...
...
You can break the read into three parts. Find the start of a message. Then get the LENGTH. Then read the rest of the message.
// Should probably clear these in case data left over from a previous read
input_buffer[0] = input_buffer[1] = 0;
// First make sure first char is 0xB5
do {
n = read(fd, input_buffer, 1);
} while (0xB5 != input_buffer[0]);
// Check for 2nd sync char
n = read(fd, &input_buffer[1], 1);
if (input_buffer[1] != 0x62) {
// Error
return;
}
// Read up to LENGTH
n = read(fd, &input_buffer[2], 4);
// Parse length
//int length = *((int *)&input_buffer[4]);
// Since I don't know what size an int is on your system, this way is better
int length = input_buffer[4] | (input_buffer[5] << 8);
// Read rest of message
n = read(fd, &input_buffer[6], length);
// input_buffer should now have a complete message
You should add error checking...

tex1Dfetch unexpectedly returning 0

I don't believe this is the same issue as reported here :
Bound CUDA texture reads zero
CUDA 1D texture fetch always return 0
In my CUDA application I noticed that tex1Dfetch is not returning the expected value, past a certain index in the buffer. An initial observation in the application was that a value at index 0 could be read correctly, but at 12705625, the value read was 0. I made a small test program to investigate this, given below. The results are a little bit baffling to me. I'm trying to probe at what index the values no longer are read correctly. But as the value arraySize is changed, so does the "firstBadIndex". Even with arraySize =2, the second value is read incorrectly! As arraySize is made bigger, the firstBadIndex gets bigger. This happens when binding to arrays of float, float2, or float4. If the data are read from the device buffer instead (switch around the commented lines in FetchTextureData), then everything is fine. This is using CUDA 6.5, on a Tesla c2075.
Thanks for any insights or advice you might have.
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#define FLOATTYPE float4
texture<FLOATTYPE,cudaTextureType1D,cudaReadModeElementType> texture1D;
const unsigned int arraySize = 1000;
FLOATTYPE* host;
FLOATTYPE* device;
FLOATTYPE* dTemp;
FLOATTYPE hTemp[1];
__global__ void FetchTextureData(FLOATTYPE* data,FLOATTYPE* arr,int idx)
{
data[0] = tex1Dfetch(texture1D, idx);
//data[0] = arr[idx];
}
bool GetTextureValues(int idx){
FetchTextureData<<<1,1>>>(dTemp,device,idx);
// copy to the host
cudaError_t err = cudaMemcpy(hTemp,dTemp,sizeof(FLOATTYPE),cudaMemcpyDeviceToHost);
if (err != cudaSuccess) {
throw "cudaMemcpy failed!";
}
if (cudaDeviceSynchronize() != cudaSuccess) {
throw "cudaDeviceSynchronize failed!";
}
return hTemp[0].x == 1.0f;
}
int main()
{
try{
host = new FLOATTYPE[arraySize];
cudaError_t err = cudaMalloc((void**)&device,sizeof(FLOATTYPE) * arraySize);
cudaError_t err1 = cudaMalloc((void**)&dTemp,sizeof(FLOATTYPE));
if (err != cudaSuccess || err1 != cudaSuccess) {
throw "cudaMalloc failed!";
}
// make some host data
for(unsigned int i=0; i<arraySize; i++){
FLOATTYPE data = {1.0f, 0.0f, 0.0f, 0.0f};
host[i] = data;
}
// and copy it to the device
err = cudaMemcpy(device,host,sizeof(FLOATTYPE) * arraySize,cudaMemcpyHostToDevice);
if (err != cudaSuccess){
throw "cudaMemcpy failed!";
}
// set up the textures
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<FLOATTYPE>();
texture1D.addressMode[0] = cudaAddressModeClamp;
texture1D.filterMode = cudaFilterModePoint;
texture1D.normalized = false;
cudaBindTexture(NULL, texture1D, device, channelDesc, arraySize);
// do a texture fetch and find where the fetches stop working
int lastGoodValue = -1, firstBadValue = -1;
float4 badValue = {-1.0f,0.0f,0.0f,0.0f};
for(unsigned int i=0; i<arraySize; i++){
if(i % 100000 == 0) printf("%d\n",i);
bool isGood = GetTextureValues(i);
if(firstBadValue == -1 && !isGood)
firstBadValue = i;
if(isGood)
lastGoodValue = i;
else
badValue = hTemp[0];
}
printf("lastGoodValue %d, firstBadValue %d\n",lastGoodValue,firstBadValue);
printf("Bad value is (%.2f)\n",badValue.x);
}catch(const char* err){
printf("\nCaught an error : %s\n",err);
}
return 0;
}
The problem lies in the texture set up. This:
cudaBindTexture(NULL, texture1D, device, channelDesc, arraySize);
should be:
cudaBindTexture(NULL, texture1D, device, channelDesc,
arraySize * sizeof(FLOATTYPE));
As per the documentation, the size argument is the size of the memory area in bytes, not the number of elements. I would have expected that with the clamped addressing mode, the code would still work as expected. With border mode, you should get a zero value which looks like it would trigger your bad value detection. I haven't actually run your code, so perhaps there is a subtley I'm missing somewhere. For such a simple repro case, your code structure is rather convoluted and hard to follow (at least on the mobile phone screen I am reading it on).
EDIT to add that between the time I started writing this and finished, #njuffa pointed out the same mistake in comments

I want to copy the data in (wchar_t *)buffer but i am unable to do so bcz there are other incompatible types,typecasting but not getting the result?

I want to print buffer data at one instance avoiding all other wprintf instances but unable to convert data in compatible type with buffer.
Have a look at code:
Kindly tell me how to get through it:
DWORD PrintEvent(EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
PEVT_VARIANT pRenderedValues = NULL;
WCHAR wsGuid[50];
LPWSTR pwsSid = NULL;
//
// Beginning of functional Logic
//
for (;;)
{
if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount))
{
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
{
dwBufferSize = dwBufferUsed;
dwBytesToWrite = dwBufferSize;
pRenderedValues = (PEVT_VARIANT)malloc(dwBufferSize);
if (pRenderedValues)
{
EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount);
}
else
{
printf("malloc failed\n");
status = ERROR_OUTOFMEMORY;
break;
}
}
}
Buffer = (wchar_t*) malloc (1*wcslen(pRenderedValues[EvtSystemProviderName].StringVal));
//
// Print the values from the System section of the element.
wcscpy(Buffer,pRenderedValues[EvtSystemProviderName].StringVal);
int i = wcslen(Buffer);
if (NULL != pRenderedValues[EvtSystemProviderGuid].GuidVal)
{
StringFromGUID2(*(pRenderedValues[EvtSystemProviderGuid].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wcscpy(Buffer+i,(wchar_t*)pRenderedValues[EvtSystemProviderGuid].GuidVal);
wprintf(L"Provider Guid: %s\n", wsGuid);
}
//Getting "??????" on screen after inclusion of guidval tell me the correct way to copy it??
wprintf(L"Buffer = %ls",Buffer);
//Also tell the way to copy unsigned values into buffer
wprintf(L"EventID: %lu\n", EventID);
wprintf(L"Version: %u\n", pRenderedValues[EvtSystemVersion].ByteVal);
wprintf(L"Level: %u\n", pRenderedValues[EvtSystemLevel].ByteVal);
wprintf(L"EventRecordID: %I64u\n", pRenderedValues[EvtSystemEventRecordId].UInt64Val);
if (EvtVarTypeNull != pRenderedValues[EvtSystemActivityID].Type)
{
StringFromGUID2(*(pRenderedValues[EvtSystemActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Correlation ActivityID: %s\n", wsGuid);
}
if (EvtVarTypeNull != pRenderedValues[EvtSystemRelatedActivityID].Type)
{
StringFromGUID2(*(pRenderedValues[EvtSystemRelatedActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Correlation RelatedActivityID: %s\n", wsGuid);
}
wprintf(L"Execution ProcessID: %lu\n", pRenderedValues[EvtSystemProcessID].UInt32Val);
wprintf(L"Execution ThreadID: %lu\n", pRenderedValues[EvtSystemThreadID].UInt32Val);
wprintf(L"Channel: %s\n",pRenderedValues[EvtSystemChannel].StringVal);
wprintf(L"Computer: %s\n", pRenderedValues[EvtSystemComputer].StringVal);
//
// Final Break Point
//
break;
}
}
The first error is when starting to write to the buffer:
Buffer = (wchar_t*) malloc (1*wcslen(pRenderedValues[EvtSystemProviderName].StringVal));
wcscpy(Buffer,pRenderedValues[EvtSystemProviderName].StringVal);
StringVal points to a wide character string with a trailing null byte, so you should
Buffer = malloc (sizeof(wchar_t)*(wcslen(pRenderedValues[EvtSystemProviderName].StringVal)+1));
or even better
Buffer = wcsdup(pRenderedValues[EvtSystemProviderName].StringVal);
Second error is when appending the GUID.
You are not allocating enough memory, you are just appending to the already full Buffer. And you are appending the raw GUID, not the GUID string. You should replace
int i = wcslen(Buffer);
wcscpy(Buffer+i,(wchar_t*)pRenderedValues[EvtSystemProviderGuid].GuidVal);
with something like
// Attention: memory leak if realloc returns NULL! So better use a second variable for the return code and check that before assigning to Buffer.
Buffer = realloc(Buffer, wcslen(Buffer) + wcslen(wsGuid) + 1);
wcscat(Buffer,wsGuid);
Also:
Besides, you should do better error checking for EvtRender. And you should check dwPropertyCount before accessing pRenderedValues[i].
BTW, wprintf(L"Buffer = %s",Buffer); (with %s instead of %ls) is sufficient with wprintf.
And to your last question: if you want to append unsigned values to a buffer you can use wsprintf to write to a string. If you can do it C++-only then you should consider using std::wstring. This is much easier for you with regard to allocating the buffers the right size.