Re: Difficulties with C FFI & writing a concurrent stack

2019-11-18 Thread Hongwei Xi
Took a closer look.

'atstype_var' should be changed to 'atstype_boxed'.

The real problem is due to 'pop' being given an incorrect type.
I tried the following type to make the code work:

  extern
  fun pop {a:type}(_t(a) >> _) : (a) = "ext#pop_ats"

To mix C with ATS can be difficult. In particular, there is not much
documentation to help.

If you want Option(a) as the return type of 'pop', 'return x' in __cats_pop
needs to be changed to 'return __cats_some(x)' where '__cats_some' can
be implemented as follows:

extern
fun
none{a:type}(): Option(a) = "__cats_none"
extern
fun
some{a:type}(x:a): Option(a) = "__cats_some"

implement none() = None()
implement some(x) = Some(x)

Frankly speaking, without documentation, I don't feel that ATS2 is ready
for you to do what you wanted here.

On Mon, Nov 18, 2019 at 10:44 PM Vanessa McHale  wrote:

> Thanks for the response!
>
> Unfortunately I still get trouble, viz.
>
> ...
>
> atstype_boxed pop_ats(atstype_ref st) { return __cats_pop(st); }
>
> atsvoid_t0ype new_ats(atstype_ref st) { __cats_new(st); }
>
> atsvoid_t0ype push_ats(atstype_ref st, atstype_boxed val) {
> __cats_push(st, val);
> }
> %}
>
> typedef stack_t(a: type) = $extype "struct stack_t"
>
> extern
> fun new {a:type}(_t(a)? >> _) : void =
>   "ext#new_ats"
>
> extern
> fun push {a:type}(_t(a) >> _, a) : void =
>   "ext#push_ats"
>
> extern
> fun pop {a:type}(_t(a) >> _) : Option(a) =
>   "ext#pop_ats"
>
> fn print_str(x : string) : void =
>   println!(x)
>
> ...
>
> leads to a segfault as before.
>
> Cheers,
> Vanessa
>
> On Sunday, November 17, 2019 at 10:18:54 PM UTC-6, gmhwxi wrote:
>>
>>
>> Each occurrence of {a:t@ype+} should be changed to {a:type}. E.g.,
>>
>> extern
>> fun pop {a:t@ype+}(_t(a) >> _) : Option(a) =
>>   "ext#pop_ats"
>>
>> should be changed to
>>
>> extern
>> fun pop {a:type}(_t(a) >> _) : Option(a) = "ext#pop_ats"
>>
>> On Sunday, November 17, 2019 at 10:16:11 PM UTC-5, Vanessa McHale wrote:
>>>
>>> Hi all,
>>>
>>> I am trying to write a concurrent stack. Code is below:
>>>
>>> %{
>>> #include 
>>> #include 
>>>
>>> struct stack_t {
>>> void *value;
>>> struct stack_t *next;
>>> };
>>>
>>> void __cats_new(struct stack_t *st) {
>>> st->value = NULL;
>>> st->next = NULL;
>>> }
>>>
>>> void __cats_push(struct stack_t *st, void *val) {
>>> for (;;) {
>>> struct stack_t old_st = *st;
>>> struct stack_t new_st = {val, _st};
>>> if (atomic_compare_exchange_strong(st, _st, new_st))
>>> return;
>>> }
>>> }
>>>
>>> // ignore ABA problem
>>> void *__cats_pop(struct stack_t *st) {
>>> for (;;) {
>>> if (st->next == NULL)
>>> return NULL;
>>> struct stack_t *old_st = st;
>>> struct stack_t xs1 = *(st->next);
>>> void *x = st->value;
>>> if (atomic_compare_exchange_strong(st, old_st, xs1))
>>> return x;
>>> }
>>> }
>>>
>>> atstype_boxed pop_ats(atstype_ref st) { return __cats_pop(st); }
>>>
>>> atsvoid_t0ype new_ats(atstype_ref st) { __cats_new(st); }
>>>
>>> atsvoid_t0ype push_ats(atstype_ref st, atstype_var val) {
>>> __cats_push(st, val);
>>> }
>>> %}
>>>
>>> typedef stack_t(a: t@ype+) = $extype "struct stack_t"
>>>
>>> extern
>>> fun new {a:t@ype+}(_t(a)? >> _) : void =
>>>   "ext#new_ats"
>>>
>>> extern
>>> fun push {a:t@ype+}(_t(a) >> _, a) : void =
>>>   "ext#push_ats"
>>>
>>> extern
>>> fun pop {a:t@ype+}(_t(a) >> _) : Option(a) =
>>>   "ext#pop_ats"
>>>
>>> fn print_str(x : string) : void =
>>>   println!(x)
>>>
>>> implement main0 (argc, argv) =
>>>   let
>>> var st: stack_t(string)
>>> val () = new(st)
>>> val () = push(st, "res")
>>> val () = push(st, "res2")
>>> val- Some (x) = pop(st)
>>> val () = print_str(x)
>>>   in end
>>>
>>> (This compiles with gcc; I can run it with patscc simple.dats -latomic ;
>>> ./a.out)
>>>
>>> Unfortunately, it immediately segfaults. I know that the offending line
>>> is the
>>>
>>> val () = print_str(x)
>>>
>>> because removing it makes the program run fine.
>>>
>>> I tried writing an equivalent program in C, viz.
>>>
>>> #include 
>>>
>>> int main(int argc, char *argv[]) {
>>>
>>> struct stack_t *st;
>>>
>>> __cats_push(st, "res");
>>> __cats_push(st, "res2");
>>>
>>> char *res;
>>>
>>> res = __cats_pop(st);
>>> printf("%s\n", res);
>>>
>>> res = __cats_pop(st);
>>> printf("%s\n", res);
>>> }
>>>
>>> ...which works as expected. So I believe I am misunderstanding how ATS
>>> handles FFI and how structures exist in memory.
>>>
>>> Any insight is appreciated!
>>>
>>> Thanks,
>>> Vanessa
>>>
>>> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> 

Re: Difficulties with C FFI & writing a concurrent stack

2019-11-18 Thread Vanessa McHale
Thanks for the response!

Unfortunately I still get trouble, viz.

...

atstype_boxed pop_ats(atstype_ref st) { return __cats_pop(st); }

atsvoid_t0ype new_ats(atstype_ref st) { __cats_new(st); }

atsvoid_t0ype push_ats(atstype_ref st, atstype_boxed val) {
__cats_push(st, val);
}
%}

typedef stack_t(a: type) = $extype "struct stack_t"

extern
fun new {a:type}(_t(a)? >> _) : void =
  "ext#new_ats"

extern
fun push {a:type}(_t(a) >> _, a) : void =
  "ext#push_ats"

extern
fun pop {a:type}(_t(a) >> _) : Option(a) =
  "ext#pop_ats"

fn print_str(x : string) : void =
  println!(x)

...

leads to a segfault as before.

Cheers,
Vanessa

On Sunday, November 17, 2019 at 10:18:54 PM UTC-6, gmhwxi wrote:
>
>
> Each occurrence of {a:t@ype+} should be changed to {a:type}. E.g.,
>
> extern
> fun pop {a:t@ype+}(_t(a) >> _) : Option(a) =
>   "ext#pop_ats"
>
> should be changed to
>
> extern
> fun pop {a:type}(_t(a) >> _) : Option(a) = "ext#pop_ats"
>
> On Sunday, November 17, 2019 at 10:16:11 PM UTC-5, Vanessa McHale wrote:
>>
>> Hi all,
>>
>> I am trying to write a concurrent stack. Code is below:
>>
>> %{
>> #include 
>> #include 
>>
>> struct stack_t {
>> void *value;
>> struct stack_t *next;
>> };
>>
>> void __cats_new(struct stack_t *st) {
>> st->value = NULL;
>> st->next = NULL;
>> }
>>
>> void __cats_push(struct stack_t *st, void *val) {
>> for (;;) {
>> struct stack_t old_st = *st;
>> struct stack_t new_st = {val, _st};
>> if (atomic_compare_exchange_strong(st, _st, new_st))
>> return;
>> }
>> }
>>
>> // ignore ABA problem
>> void *__cats_pop(struct stack_t *st) {
>> for (;;) {
>> if (st->next == NULL)
>> return NULL;
>> struct stack_t *old_st = st;
>> struct stack_t xs1 = *(st->next);
>> void *x = st->value;
>> if (atomic_compare_exchange_strong(st, old_st, xs1))
>> return x;
>> }
>> }
>>
>> atstype_boxed pop_ats(atstype_ref st) { return __cats_pop(st); }
>>
>> atsvoid_t0ype new_ats(atstype_ref st) { __cats_new(st); }
>>
>> atsvoid_t0ype push_ats(atstype_ref st, atstype_var val) {
>> __cats_push(st, val);
>> }
>> %}
>>
>> typedef stack_t(a: t@ype+) = $extype "struct stack_t"
>>
>> extern
>> fun new {a:t@ype+}(_t(a)? >> _) : void =
>>   "ext#new_ats"
>>
>> extern
>> fun push {a:t@ype+}(_t(a) >> _, a) : void =
>>   "ext#push_ats"
>>
>> extern
>> fun pop {a:t@ype+}(_t(a) >> _) : Option(a) =
>>   "ext#pop_ats"
>>
>> fn print_str(x : string) : void =
>>   println!(x)
>>
>> implement main0 (argc, argv) =
>>   let
>> var st: stack_t(string)
>> val () = new(st)
>> val () = push(st, "res")
>> val () = push(st, "res2")
>> val- Some (x) = pop(st)
>> val () = print_str(x)
>>   in end
>>
>> (This compiles with gcc; I can run it with patscc simple.dats -latomic ;
>> ./a.out)
>>
>> Unfortunately, it immediately segfaults. I know that the offending line
>> is the
>>
>> val () = print_str(x)
>>
>> because removing it makes the program run fine.
>>
>> I tried writing an equivalent program in C, viz.
>>
>> #include 
>>
>> int main(int argc, char *argv[]) {
>>
>> struct stack_t *st;
>>
>> __cats_push(st, "res");
>> __cats_push(st, "res2");
>>
>> char *res;
>>
>> res = __cats_pop(st);
>> printf("%s\n", res);
>>
>> res = __cats_pop(st);
>> printf("%s\n", res);
>> }
>>
>> ...which works as expected. So I believe I am misunderstanding how ATS
>> handles FFI and how structures exist in memory. 
>>
>> Any insight is appreciated!
>>
>> Thanks,
>> Vanessa
>>
>>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ats-lang-users/2b564e10-e652-47d9-a6b5-61b3b27499d0%40googlegroups.com.