|
I forget one thing to mention,this problem occur when i convert my code from VS-2006 to VS-2008.
its works perfectly fine in VS-2006.
so please help me.
thanks in advance.
To accomplish great things, we must not only act, but also dream;
not only plan, but also believe.
|
|
|
|
|
Hello!
Let's say we have the following:
class MyClass
{
public:
void SetValue( __int64 a_i64Value );
__int64 GetValue( void ) const;
private:
__int64 m_i64Value;
};
void MyClass::SetValue( __int64 a_i64Value )
{
m_i64Value = a_i64Value;
}
__int64 MyClass::GetValue( void ) const
{
return m_i64Value;
}
We also have two threads: ThreadA and ThreadB , each setting the value of m_i64Value to something different.
Let's assume that ThreadA executes and SetValue is called. It writes 32 bits of m_i64Value , ThreadB executes, it calls SetValue which also writes 32 bits of m_i64Value , then ThreadA resumes and continues writing the other 32 bits of m_i64Value . Finally, ThreadB also writes the other half of m_i64Value . Eventually, m_i64Value contains garbage, invalid data.
Question 1: Is this scenario valid? Can it happen on a 32 bit machine?
Anyway, this can be solved using InterlockedExchange64 , right?
But let's suppose there is a ThreadC which needs to read that value, using the member function GetValue . When returning from GetValue , 32 bits of m_i64Value get written to EAX register and 32 bits to EDX .
Question 2: What if 32 bits get written to EAX , ThreadB resumes and writes to m_i64Value and after that, ThreadC resumes and the other 32 bits (changed by ThreadB ) go to EDX ? Is this also a possibility on 32 bit machines? If yes, what is the best way to return such a value (__int64, in this example)?
I guess one of the solutions could be this one:
void GetValue( __int64 *a_pi64Value )
{
if ( NULL != a_pi64Value )
{
InterlockedExchange64( *a_pi64Value, m_i64Value );
}
}
Question 3: But what if we still want to actually return the value and not copy it to the memory pointed by a_pi64Value ? Can this be done somehow thread-safely and using the return instruction?
Thanks in advance!
|
|
|
|
|
Eikthrynir wrote: Question 1: Is this scenario valid? Can it happen on a 32 bit machine?
Yes as the MSDN states in the article Interlocked Variable Access[^]:
Reads and writes to 64-bit values are not guaranteed to be atomic on 32-bit Windows. Reads and writes to variables of other sizes are not guaranteed to be atomic on any platform.
Eikthrynir wrote: Question 2: What if 32 bits get written to EAX, ThreadB resumes and writes to m_i64Value and after that, ThreadC resumes and the other 32 bits (changed by ThreadB) go to EDX? Is this also a possibility on 32 bit machines? If yes, what is the best way to return such a value (__int64, in this example)?
Eikthrynir wrote: Question 3: But what if we still want to actually return the value and not copy it to the memory pointed by a_pi64Value? Can this be done somehow thread-safely and using the return instruction?
I would personally do it like this:
LONGLONG GetValue(__int64 *a_pi64Value)
{
return InterlockedExchangeAdd64(a_pi64Value,0);
}
Best Wishes,
-David Delaune
modified on Wednesday, May 13, 2009 11:41 AM
|
|
|
|
|
Hello!
Thanks for the reply!
I would like to make a few comments regarding your version of GetValue ...
1. You call InterlockedExchange64 with a_pi64Value as the first parameter, so the __int64 variable pointed by a_pi64Value gets 0 . Then, you return the previous value of that __int64 variable which is certainly not the one we are interested in, m_i64Value .
2. GetValue returns a LONGLONG value, so we find ourselves in exactly the same situation from Question 2 (concerning the EAX and EDX registers)...
Best regards!
|
|
|
|
|
Eikthrynir wrote: 1. You call InterlockedExchange64 with a_pi64Value as the first parameter, so the __int64 variable pointed by a_pi64Value gets 0. Then, you return the previous value of that __int64 variable which is certainly not the one we are interested in, m_i64Value.
If the 64 bit integer variable you want to read atomically is m_i64Value
Then the correct way to atomically read the value is:
__int64 i64Val = InterlockedExchangeAdd64(m_i64Value,0);
Eikthrynir wrote: 2. GetValue returns a LONGLONG value, so we find ourselves in exactly the same situation from Question 2 (concerning the EAX and EDX registers)...
This statement does not make any sense to me.
Best Wishes,
-David Delaune
|
|
|
|
|
Dear All,
Can anybody please tell me how to find whether a SCSI hard disk has S.M.A.R.T. support or not and also its S.M.A.R.T. features using M.F.C?
Thank You
|
|
|
|
|
What about the previous replies[^] given to you?
It is a crappy thing, but it's life -^ Carlo Pallini
|
|
|
|
|
The previous replies doesn't give any information about SCSI S.M.A.R.T features.
Thank You
|
|
|
|
|
Those clearly did not work.
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
I was referring to the second reply (by David), which was posted one day after the OP said Stuart's approach didn't help.
It is a crappy thing, but it's life -^ Carlo Pallini
|
|
|
|
|
Have you tried DeviceIoControl(hDrive, SMART_GET_VERSION, ...) ?
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
Yes I tried DeviceIoControl(hDrivee,SMART_GET_VERSION,...).But it is returning zero.
|
|
|
|
|
Hi,
I also actually try this, and it doesn't work, and DeviceIoControl doesn't work neither with CreateFile ("\\\\.\\PhysicalDrive%d",...), nor with CreateFile ("\\\\.\\Scsi%d:",...).
I have found an interesting source in internet , see Guckst du hier[^] explaining a workaround for SMART with SCSI drives, but even after some needed code corrections (e.g. adding iobuff definitions, etc.), this doesn't worked for me (now I've got error 55 instead of 1117). If you have more luck, I would appreciate a answer from you .
BR
|
|
|
|
|
Abinash Mohanty wrote: But it is returning zero.
Which means you should then call GetLastError() to find out why.
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
I would guess ERROR_INVALID_FUNCTION ...
It seems that SCSI doesn't support this method. But S.M.A.R.T. is supported by a different way, because tools like Crystal Disk Info are showing correct info.
|
|
|
|
|
Hi, Have you fixed that problem now?
It also bother me, I can't get SMART info in SCSI hard disk by SMART_GET_VERSION.
Could you pls tell me your method ?
my mail:aishui0905@163.com
Thank you !
|
|
|
|
|
Yes, I made a workaround. I do not need the SMART_GET_VERSION, it was only a test which version is supported. Since the function has failed, I stepped out the procedure.
In my workaround I do not bother if the command fails in try to read the SMART infos. This works on all my test systems .
|
|
|
|
|
So you still have no solution of SMART IN SCSI HDD,right?
|
|
|
|
|
Sure. My aim was, to read the smart info on SCSI drives. This is working fine now. What doesn't work, is to read the SMART version numbor on SCSI. But that's a minor problem and is not really bothering.
|
|
|
|
|
Hello All,
I want to Create ISO9660 image file , So how to convert
normal file/folders to ISO9660 image file format. If any source code
will be greatly appriciated, matter urgent.
I simply want to add files and dirs and create the iso image from that.
there is no useful answer in Codeproject and other web sites....
Thanks in Advance.
|
|
|
|
|
Hi,
InfraRecorder[^] is open source and it can create ISO files. If think that it uses cygwin to create binary for Windows, but am not sure. Just have a look at it.
ISO Master[^] is another such thing, but they provide source code that compiles only on Unix/Linux like operating systems.
It is a crappy thing, but it's life -^ Carlo Pallini
|
|
|
|
|
I have created a win32 resource dll which has only string table, also i have included \NOENTRY in linker options in-order to make it as resource only dll
Now I am loading the dll in MFC application and loads fine but when I am try to get the string from the string table it doens't load. Here is my code:
HINSTANCE hinsttance = ::LoadLibrary("SampleEN.dll");
DWORD dwError = GetLastError();
if (!hinsttance)
{
AfxMessageBox("Failed to load");
}
else
{
HINSTANCE hInstResourceClient = AfxGetResourceHandle();
AfxSetResourceHandle(hinsttance);
LPCTSTR lpszName = MAKEINTRESOURCE(1);
HRSRC hrsrc = FindResource(m_hinstLib, lpszName, RT_STRING);
if (hrsrc)
{
TCHAR szTemp[256];
LoadString(m_hinstLib, IDC_STATIC_TOP, szTemp, 255);
}
AfxSetResourceHandle(hInstResourceClient);
}
what could be the problem???
|
|
|
|
|
Super Hornet wrote: HRSRC hrsrc = FindResource(m_hinstLib, lpszName, RT_STRING);
What is m_hinstLib?
It should be hinsttance.
Then use the handle returned by FindResource in a call to LoadResource .
To access the actual resource call LockResource on the handle returned by LoadResource .
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
Actually it's - hinsttance, mistakenly written here as m_hinstLib
|
|
|
|
|
Where exactly does it fail?
Is it the FindResource that is failing or is it LoadString ?
Try it without the AfxSetResourceHandle call.
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|