Flat memory underlying dataviewtypes

106 views
Skip to first unread message

Andrew Knapp

unread,
Mar 20, 2018, 2:35:46 PM3/20/18
to ats-lang-users
Hello,

I'd like to be able to send dataviewtypes as messages in a low-latency ipc library I've written.

In this scenario, any use of malloc is unacceptable. Everything must be allocated from a memory pool or the stack, but datavtype constructors always allocate on the heap.

What is the best way to access to the size and flat memory of the datavtype's tagged union, preferably in a typesafe manner? You can do this by a hack like

dataviewtype message =
 
| Bar of (int, double)
 
| Baz of (double, double)

#define BAR 0
#define BAZ 1

typedef BAR_ = @{
  contag
= int,
  atslab__0
= int,
  atslab__1
= double
}

typedef BAZ_ = @{
  contag
= int,
  atslab__0
= double,
  atslab__1
= double
}

and then using $UNSAFE.cast{Foo} on a pointer to stack or pool allocated memory of size FOO_SIZE = max(sizeof<BAR_>, sizeof<BAZ_>), which has had its contag set to BAR or BAZ via another unsafe cast.

Unfortunately there is really a lot of boilerplate here and it will be easy for things to get out of sync with datatype definitions, especially with a lot of constructors. Moreover, FOO_SIZE is not a static constant, so you can't just write something like var buf : @[char][FOO_SIZE*N]

Also, is there an equivalent of the placement new operator in C++?

Thanks,
Andrew

Hongwei Xi

unread,
Mar 21, 2018, 7:05:43 AM3/21/18
to ats-lan...@googlegroups.com
In your case,

the type message_Bar_pstruct(int, double) is for a pointer to BAR_

Here is a relevant example:

http://ats-lang.sourceforge.net/DOCUMENT/INT2PROGINATS/HTML/HTMLTOC/x2223.html

You can find more in the following book by searching 'pstruct':
Placement new operator in C++ can be simulated:

val Bar(int, double) = <some_uninitialized_node>
val () = int := 0 and double = 0.0

Hopefully, the boilerplate code can be compiler-generated in the future.



--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-users+unsubscribe@googlegroups.com.
To post to this group, send email to ats-lang-users@googlegroups.com.
Visit this group at https://groups.google.com/group/ats-lang-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ats-lang-users/51b38545-377a-445a-9e3c-2086e760a680%40googlegroups.com.

Andrew Knapp

unread,
Mar 21, 2018, 4:30:00 PM3/21/18
to ats-lang-users
That works nicely! At least on glot.io...

https://glot.io/snippets/ezdur9ik70

When I run the exact same code on my machine, I get the following error

exit(ATS): unmatched value at run-time:
/home/andy/tmp/tmp.dats: 713(line=30, offs=9) -- 725(line=30, offs=21)

i.e. the line

    val Bar(x,y) = p

fails.

Andrew Knapp

unread,
Mar 21, 2018, 4:32:36 PM3/21/18
to ats-lang-users
The code on glot also fails if you change Bar to Baz in all the appropriate places.

Hongwei Xi

unread,
Mar 21, 2018, 4:49:02 PM3/21/18
to ats-lan...@googlegroups.com

The tag part needs to be set manually. For Bar, it is 0. For Baz, it is 1.
You may have to do it in C or in unsafe ATS for this part.



On Wed, Mar 21, 2018 at 4:32 PM, Andrew Knapp <andy.j...@gmail.com> wrote:
The code on glot also fails if you change Bar to Baz in all the appropriate places.

--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-users+unsubscribe@googlegroups.com.
To post to this group, send email to ats-lang-users@googlegroups.com.
Visit this group at https://groups.google.com/group/ats-lang-users.

gmhwxi

unread,
Mar 21, 2018, 7:10:56 PM3/21/18
to ats-lang-users

I suddenly recall a feature in ATS:

$extype_struct.

The following code should compile and run:

#include "share/atspre_staload.hats"
#include "share/atspre_define.hats"

staload UN = "prelude/SATS/unsafe.sats"

datavtype message =

  | Bar of (int, double)
  | Baz of (double, double)

vtypedef
BAR = Bar_pstruct(int, double)
vtypedef
BAZ = Baz_pstruct(double, double)

extern vtypedef "BAR" = BAR
extern vtypedef "BAZ" = BAZ

typedef BAR_ =
$extype_struct "BAR_" of { contag=int }
typedef BAZ_ =
$extype_struct "BAZ_" of { contag=int }

extern castfn stack_unwind{a:vt0p}(INV(a)):<> void

fn f(x: !message): void =
  case+ x of
  | Bar(a,b) => println!("BAR ", a, " ", b)
  | Baz(a,b) => println!("BAZ ", a, " ", b)

implement main0() =
  let
    var b : BAR_
    val () = b.contag := 0
    val p = $UN.castvwtp0{BAR}(addr@b)
    val msg = $UN.castvwtp0{message}(addr@b)
    val Bar(x,y) = p
    val () = begin
      x := 5;
      y := 3.14;
      f(msg)
    end
    val _ = $UN.castvwtp0{ptr}((view@x, view@y | p))
  in
    stack_unwind(msg)
  end

Andrew Knapp

unread,
Mar 21, 2018, 7:30:00 PM3/21/18
to ats-lang-users
Yes, that works well. Thank you!

Artyom Shalkhakov

unread,
Mar 28, 2018, 3:15:30 AM3/28/18
to ats-lang-users
Hi Andrew,

Could you please post a link to the library? Thanks. :)

Andrew Knapp

unread,
Apr 2, 2018, 1:41:11 AM4/2/18
to ats-lang-users
I'll put it on github sometime this week. It's an ATS port of this c++ library

https://github.com/rigtorp/nanomq
Reply all
Reply to author
Forward
0 new messages