Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

{.volatile.} is almost useless #3382

Closed
rasendubi opened this issue Sep 27, 2015 · 5 comments · Fixed by #5263
Closed

{.volatile.} is almost useless #3382

rasendubi opened this issue Sep 27, 2015 · 5 comments · Fixed by #5263
Labels

Comments

@rasendubi
Copy link

As an embedded and kernel developer I need pointers to a volatile memory to work with memory-mapped hardware registers. Nim has a {.volatile.} pragma but it's a property of a variable.

let reg {.volatile.} = cast[ptr char](0x101f1000)

gives the following C output:

NIM_CHAR* volatile reg;
nimfr("kmain", "kernel.nim");
nimln(5, "kernel.nim");
reg = ((NIM_CHAR*) 270471168);

As you see, reg is a volatile pointer to a non-volatile memory. The behavior I want to achieve is a non-volatile pointer to a volatile memory:

NIM_CHAR volatile *reg;

I don't see a way to create such a variable in Nim. I would say, that's pretty critical: embedded and kernel-level programming is impossible without that.

As a fix I think of making volatile a property of a type rather than a variable. I expect to write the following:

let reg = cast[ptr[char {.volatile.}]](0x101f1000)
# or even
const reg = cast[ptr[char {.volatile.}]](0x101f1000)
# const reg {.volatile.} = ... doesn't even work now
@yglukhov
Copy link
Member

As a quick and dirty workaround you can use emit.

{.emit: "NIM_CHAR volatile* myPtr;".}
var myPtr {.nodecl, importc.}: ptr char
myPtr[] = 'A'

I guess this could be wrapped in a macro.

@rasendubi
Copy link
Author

The other solution (from Rust: rust-lang/rust#11172) is to implement volatile_load and volatile_store functions.

@Araq
Copy link
Member

Araq commented Sep 28, 2015

Volatile is not a property of a type and should not be.

@Araq
Copy link
Member

Araq commented Sep 29, 2015

volatile_load and volatile_store is the superior solution indeed.

@dom96 dom96 added the Feature label Jan 16, 2016
Jeff-Ciesielski added a commit to Jeff-Ciesielski/Nim that referenced this issue Jan 23, 2017
Adds volatile load/store capability to the impure part of the standard
library.  This makes use of two new C macros stored in the nimbase.h
file and some macro trickery to perform type checking on the nim side.
Note that this currently only supports numerical types.

Should resolve nim-lang#3382
Jeff-Ciesielski added a commit to Jeff-Ciesielski/Nim that referenced this issue Jan 23, 2017
Adds volatile load/store capability to the impure part of the standard
library.  This makes use of two new C macros stored in the nimbase.h
file and some macro trickery to perform type checking on the nim side.
Note that this currently only supports numerical types.

Should resolve nim-lang#3382
@jcosborn
Copy link
Contributor

This seems to work. It involves an extra copy, but doesn't require any emits.

template volatileLoad*[T](p: ptr T): T =
  let x {.volatile.} = p[]
  x

template volatileStore*[T](p: ptr T, v: T) =
  let x {.volatile.} = v
  p[] = x

type VolatilePtr*[T] = distinct ptr T

template `[]`*[T](p: VolatilePtr[T]): T =
  volatileLoad((ptr T)(p))

template `[]=`*[T](p: VolatilePtr[T], v: T) =
  volatileStore((ptr T)(p), v)

when isMainModule:
  proc test =
    var t = 0
    var c = 0

    for i in 1..1000:
      volatileStore(addr t, 1)
      if volatileLoad(addr t)==1:
        inc c

    let p = VolatilePtr(addr t)

    for i in 1..1000:
      p[] = 2
      if p[]==2:
        inc c

    echo c

  test()

Jeff-Ciesielski added a commit to Jeff-Ciesielski/Nim that referenced this issue Jan 25, 2017
Adds volatile load/store capability to the impure part of the standard
library.  Note that this currently only supports numerical types.

Should resolve nim-lang#3382
Jeff-Ciesielski added a commit to Jeff-Ciesielski/Nim that referenced this issue Jan 25, 2017
Adds volatile load/store capability to the impure part of the standard
library.  Note that this currently only supports numerical types.

Should resolve nim-lang#3382
Jeff-Ciesielski added a commit to Jeff-Ciesielski/Nim that referenced this issue Jan 25, 2017
Adds volatile load/store capability to the impure part of the standard
library.  Note that this currently only supports numerical types.

Should resolve nim-lang#3382
Araq pushed a commit that referenced this issue Jan 25, 2017
Adds volatile load/store capability to the impure part of the standard
library.  Note that this currently only supports numerical types.

Should resolve #3382
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants