I've just discovered that there are "no fence" versions of atomic-add on 
Windows, but they are only available starting with Windows 8/Windows Server 
2012. A quick search told me that I should use 
[IsWindows8OrGreater()](https://msdn.microsoft.com/en-us/library/windows/desktop/dn424961\(v=vs.85\).aspx)
 from VersionHelpers.h.

I've tried something like this:
    
    
    const
      hasThreadSupport = compileOption("threads") and not defined(nimscript)
    
    if defined(vcc) and hasThreadSupport:
      when defined(cpp):
        proc isWindows8OrGreater(): bool
          {.importcpp: "_IsWindows8OrGreater(void)", header: 
"<VersionHelpers.h>".}
      
      else:
        proc isWindows8OrGreater(): bool
          {.importc: "_IsWindows8OrGreater", header: "<VersionHelpers.h>".}
    

but trying to use it fails with such errors:
    
    
    cl.exe /c /nologo /Z7 /IC:\nim-0.17.2\lib ...
    atomiks.c
    C:\Program Files (x86)\Windows 
Kits\10\include\10.0.14393.0\um\VersionHelpers.h(39): error C2061: syntax 
error: identifier 'BOOL'
    C:\Program Files (x86)\Windows 
Kits\10\include\10.0.14393.0\um\VersionHelpers.h(39): error C2059: syntax 
error: ';'
    C:\Program Files (x86)\Windows 
Kits\10\include\10.0.14393.0\um\VersionHelpers.h(40): error C2146: syntax 
error: missing ')' before identifier 'wMajorVersion'
    C:\Program Files (x86)\Windows 
Kits\10\include\10.0.14393.0\um\VersionHelpers.h(40): error C2061: syntax 
error: identifier 'wMajorVersion'
    C:\Program Files (x86)\Windows 
Kits\10\include\10.0.14393.0\um\VersionHelpers.h(40): error C2059: syntax 
error: ';'
    C:\Program Files (x86)\Windows 
Kits\10\include\10.0.14393.0\um\VersionHelpers.h(40): error C2059: syntax 
error: ','
    C:\Program Files (x86)\Windows 
Kits\10\include\10.0.14393.0\um\VersionHelpers.h(40): error C2059: syntax 
error: ')'
    C:\Program Files (x86)\Windows 
Kits\10\include\10.0.14393.0\um\VersionHelpers.h(57): error C2061: syntax 
error: identifier 'BOOL'
    

I would like to know how to correctly call IsWindows8OrGreater() OR how to 
otherwise check the Windows version in some other "Nim way", if available. This 
would only need to be done once at the start of the application, so "speed" is 
not relevant in this case.

Another related question is, once I can do:
    
    
    let WIN8_OR_GREATER = isWindows8OrGreater()
    

Can I write something like this:
    
    
    proc atomicIncRelaxed*[T: AtomType](p: VolatilePtr[T], x: T = 1): T =
        ## Increments a volatile (32/64 bit) value, and returns the new value.
        ## Performed in RELAXED/No-Fence memory-model.
        let pp = cast[pointer](p)
        when sizeof(T) == 8:
          if WIN8_OR_GREATER:
            cast[T](interlockedExchangeAddNoFence64(pp, cast[int64](x)))
          else:
            cast[T](interlockedExchangeAdd64(pp, cast[int64](x)))
        elif sizeof(T) == 4:
          if WIN8_OR_GREATER:
            cast[T](interlockedExchangeAddNoFence32(pp, cast[int32](x)))
          else:
            cast[T](interlockedExchangeAdd32(pp, cast[int32](x)))
        else:
          static: assert(false, "invalid parameter size: " & $sizeof(T))
    

and expect it to work on Windows 7? Or will it fail/crash because 
interlockedExchangeAddNoFence64() is not available, even if I never call it, 
due to the runtime check?

Reply via email to