Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #18560 > unrolled thread

things i would ban from clc

Started byjgk@panix.com (Joe keane)
First post2012-03-11 23:05 +0000
Last post2012-03-14 13:01 -0700
Articles 20 on this page of 87 — 22 participants

Back to article view | Back to comp.lang.c


Contents

  things i would ban from clc jgk@panix.com (Joe keane) - 2012-03-11 23:05 +0000
    Re: things i would ban from clc Keith Thompson <kst-u@mib.org> - 2012-03-12 10:33 -0700
      Re: things i would ban from clc gazelle@shell.xmission.com (Kenny McCormack) - 2012-03-12 23:57 +0000
    Re: things i would ban from clc jacob navia <jacob@spamsink.net> - 2012-03-12 18:44 +0100
      Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-12 12:26 -0700
        Re: things i would ban from clc "osmium" <r124c4u102@comcast.net> - 2012-03-12 14:36 -0600
          Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-12 13:57 -0700
        Re: things i would ban from clc James Kuyper <jameskuyper@verizon.net> - 2012-03-12 17:34 -0400
          Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-12 15:00 -0700
            Re: things i would ban from clc James Kuyper <jameskuyper@verizon.net> - 2012-03-12 18:21 -0400
              Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-12 15:43 -0700
                Re: things i would ban from clc jacob navia <jacob@spamsink.net> - 2012-03-12 23:53 +0100
                  Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-12 17:17 -0700
                    Re: things i would ban from clc jacob navia <jacob@spamsink.net> - 2012-03-13 09:09 +0100
                      Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 01:24 -0700
                        Re: things i would ban from clc Keith Thompson <kst-u@mib.org> - 2012-03-13 05:59 -0700
                          Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 10:55 -0700
                            Re: things i would ban from clc blp@cs.stanford.edu (Ben Pfaff) - 2012-03-13 11:07 -0700
                              Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 11:25 -0700
                                Re: things i would ban from clc blp@cs.stanford.edu (Ben Pfaff) - 2012-03-13 11:32 -0700
                                  Re: things i would ban from clc Keith Thompson <kst-u@mib.org> - 2012-03-13 12:18 -0700
                                    Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 16:13 -0700
                                  Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 13:49 -0700
                                    Re: things i would ban from clc James Kuyper <jameskuyper@verizon.net> - 2012-03-13 17:14 -0400
                                      Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 14:35 -0700
                                        Re: things i would ban from clc James Kuyper <jameskuyper@verizon.net> - 2012-03-13 18:09 -0400
                                          Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 16:06 -0700
                                            Re: things i would ban from clc "io_x" <a@b.c.invalid> - 2012-03-14 08:18 +0100
                                              Re: things i would ban from clc "io_x" <a@b.c.invalid> - 2012-03-14 10:07 +0100
                                              Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-14 12:41 -0700
                                                Re: things i would ban from clc "io_x" <a@b.c.invalid> - 2012-03-14 21:53 +0100
                                                  Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-15 14:16 -0700
                                                    Re: things i would ban from clc "io_x" <a@b.c.invalid> - 2012-03-18 07:14 +0100
                                          Re: things i would ban from clc Jens Gustedt <jens.gustedt@loria.fr> - 2012-03-14 10:39 +0100
                                    Re: things i would ban from clc Ben Pfaff <blp@cs.stanford.edu> - 2012-03-13 14:33 -0700
                                      Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 14:40 -0700
                              Re: things i would ban from clc Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-13 16:25 -0700
                                Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-14 00:51 -0700
                                  Re: things i would ban from clc Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-14 14:25 -0700
                                    Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-15 13:40 -0700
                                      Re: things i would ban from clc Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-18 17:05 -0700
                                        Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-23 11:59 -0700
                                          Re: things i would ban from clc Robert Wessel <robertwessel2@yahoo.com> - 2012-03-23 17:02 -0500
                                            Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-23 16:51 -0700
                                              Re: things i would ban from clc "io_x" <a@b.c.invalid> - 2012-03-24 07:16 +0100
                                          Re: things i would ban from clc Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-27 11:26 -0700
                                        Re: things i would ban from clc Kaz Kylheku <kaz@kylheku.com> - 2012-03-23 19:43 +0000
                                          Re: things i would ban from clc Rui Maciel <rui.maciel@gmail.com> - 2012-03-23 19:45 +0000
                                          Re: things i would ban from clc Jens Gustedt <jens.gustedt@loria.fr> - 2012-03-23 23:49 +0100
                                            Re: things i would ban from clc Ian Collins <ian-news@hotmail.com> - 2012-03-24 11:54 +1300
                                              Re: things i would ban from clc Jens Gustedt <jens.gustedt@loria.fr> - 2012-03-24 09:26 +0100
                                              Re: things i would ban from clc gwowen <gwowen@gmail.com> - 2012-03-26 07:31 -0700
                                            Re: things i would ban from clc Kaz Kylheku <kaz@kylheku.com> - 2012-03-24 05:45 +0000
                                              Re: things i would ban from clc Jens Gustedt <jens.gustedt@loria.fr> - 2012-03-24 09:31 +0100
                            Re: things i would ban from clc James Kuyper <jameskuyper@verizon.net> - 2012-03-13 14:34 -0400
                            Re: things i would ban from clc Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-13 16:18 -0700
                              Re: things i would ban from clc "io_x" <a@b.c.invalid> - 2012-03-14 08:18 +0100
                                Re: things i would ban from clc Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-14 14:06 -0700
                        Re: things i would ban from clc Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-03-15 15:22 +0000
                          Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-15 12:26 -0700
                            Re: things i would ban from clc jacob navia <jacob@spamsink.net> - 2012-03-15 21:28 +0100
                              Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-15 13:49 -0700
                        Re: things i would ban from clc Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-15 16:36 +0000
                          Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-15 12:16 -0700
                            Re: things i would ban from clc Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-16 00:13 +0000
                              Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-15 20:40 -0700
                  Re: things i would ban from clc gwowen <gwowen@gmail.com> - 2012-03-13 01:52 -0700
                    Re: things i would ban from clc "io_x" <a@b.c.invalid> - 2012-03-13 11:31 +0100
                    Re: things i would ban from clc jacob navia <jacob@spamsink.net> - 2012-03-13 11:41 +0100
                      Re: things i would ban from clc gwowen <gwowen@gmail.com> - 2012-03-13 06:06 -0700
                        Re: things i would ban from clc jacob navia <jacob@spamsink.net> - 2012-03-13 15:06 +0100
                        Re: things i would ban from clc ImpalerCore <jadill33@gmail.com> - 2012-03-13 07:46 -0700
                        Re: things i would ban from clc jacob navia <jacob@spamsink.net> - 2012-03-13 19:08 +0100
                      Re: things i would ban from clc Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-13 13:20 +0000
                        Re: things i would ban from clc Jens Gustedt <jens.gustedt@loria.fr> - 2012-03-13 20:41 +0100
                  Re: things i would ban from clc Kaz Kylheku <kaz@kylheku.com> - 2012-03-13 19:34 +0000
                    Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 16:14 -0700
                      Re: things i would ban from clc Kaz Kylheku <kaz@kylheku.com> - 2012-03-13 23:28 +0000
                        Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 21:18 -0700
        Re: things i would ban from clc Ian Collins <ian-news@hotmail.com> - 2012-03-13 20:19 +1300
          Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-13 01:09 -0700
            Re: things i would ban from clc Ian Collins <ian-news@hotmail.com> - 2012-03-13 21:32 +1300
    Re: things i would ban from clc nick_keighley_nospam@hotmail.com - 2012-03-13 01:52 -0700
      Re: things i would ban from clc "io_x" <a@b.c.invalid> - 2012-03-13 11:31 +0100
        Re: things i would ban from clc nick_keighley_nospam@hotmail.com - 2012-03-14 01:18 -0700
          Re: things i would ban from clc Don Y <this@isnotme.com> - 2012-03-14 12:09 -0700
    Re: things i would ban from clc ArifulHossain tuhin <etothepowerpi@gmail.com> - 2012-03-14 13:01 -0700

Page 2 of 5 — ← Prev page 1 [2] 3 4 5  Next page →


#18692

FromKeith Thompson <kst-u@mib.org>
Date2012-03-13 12:18 -0700
Message-ID<lnobs0cnsn.fsf@nuthaus.mib.org>
In reply to#18689
blp@cs.stanford.edu (Ben Pfaff) writes:
[...]
> Threading is intentionally an optional feature for C
> implementations, because C is supposed to work on platforms that
> do not or cannot support threads.

<threads.h>, like most of the standard library, is specified only for
hosted implementations.  Certainly most mainstream hosted platforms
support threading; I'm skeptical that there are any hosted systems
that are likely to support C2011 that *can't* support threads.

I think <threads.h> was made optional mostly to ease the burden
on implementers, and encourage them to develop conforming
implementations when they otherwise wouldn't.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#18729

FromDon Y <this@isnotme.com>
Date2012-03-13 16:13 -0700
Message-ID<jjokaf$6lg$1@speranza.aioe.org>
In reply to#18692
Hi Keith,

On 3/13/2012 12:18 PM, Keith Thompson wrote:

> I think<threads.h>  was made optional mostly to ease the burden
> on implementers, and encourage them to develop conforming
> implementations when they otherwise wouldn't.

I think this is just another aspect of C's "light touch".
It tries not to be "imposing" (Ada, anyone?) so you can
use as little of it as you need/want.

E.g., you don't *have* to use strlen() to determine the
length of a string.  You don't *have* to use printf()
to pass text to the outside world.  You don't *have* to
use array notation to access a group of contiguous like-typed
values.

[toc] | [prev] | [next] | [standalone]


#18697

FromDon Y <this@isnotme.com>
Date2012-03-13 13:49 -0700
Message-ID<jjobtc$gbj$1@speranza.aioe.org>
In reply to#18689
Hi Ben,

>>> What's the advantage of putting threading into language instead
>>> of the library?  (You explained *how* Limbo integrates threading
>>> into the language, but not why it does.)
>>
>> It elevates threads to first-class objects.  It recognizes
>> that programs are more "collections of threads" than "monolithic,
>> single-threaded processes" that have to *struggle* to
>> CO-operate.
>
> That is a nice statement of principles, but it's hard for me to
> imagine what practical effect it would have on threaded C
> programs.  Do you have an example to propose?

See below.

>> Moving things into the language also changes who is
>> responsible for the implementation and performance of
>> the feature.  In Limbo, the "compiler"/runtime VM handle
>> ALL of the mechanisms associated with these features.
>> it means that those features are accessible to your
>> code on any platform that can support Limbo programs.
>> (double edged sword... if you don't like how they do
>> it, you can't just swap out that aspect like you can with
>> a separate library).
>
> Threading is intentionally an optional feature for C
> implementations, because C is supposed to work on platforms that
> do not or cannot support threads.

Yes.  This goes to my comment (elsewhere) about the "attitude"
(philosophy?) that C presents vs. other languages.  E.g.,
C exposes lots of fine-grained detail and gives you a great
deal of control over what's happening "now".

By contrast, Limbo (and its Inferno base) *hides* lots of
detail from the developer.  E.g., (apologies for any typos)

greetings(
   surname: string,
   children: list of (string, int)
) {
    sys = load Sys Sys->PATH;

    sys->print("Season's Greetings from the %s family!\n"
               surname);
    while (children != nil) {
      (firstname, age) := hd children;
      fullname := firstname + " " + surname;
      sys->print("%s (%d years old)\n" firstname, age);
      children = tl children;
    }
}

Note that the only function invoked in the above is
"print" from the "Sys" module.  The string support, list
support, tuples, etc. are all part of the language itself.
(so there is a garbage collector hiding behind the scenes
as well!)

The routine could just as easily have delivered its
"output" to a *channel" (communication mechanism):

greetings(
   surname: string,
   children: list of (string, int)
   output: chan of string
) {
    output <-= "Season's Greetings from the "
            + surname + " family!\n";

    while (children != nil) {
      (firstname, age) := hd children;
      description := firstname + " " + surname;
      description = description
                  + " (" + age + " years old)";
      output <-= fullname;
      children = tl children;
    }
}

Some other thread could similarly watch a channel and
pass anything inbound directly to the "print" device:

logging(
   input: chan of string
) {
    sys = load Sys Sys->PATH;

    while (FOREVER) {
      text :=<- input;
      sys->print("%s\n", text)
    }
}

This channel can be shared between these two threads:

job(surname: string,
     children: list of (string, int)
) {
    pipe: channel of string;

    spawn logging(pipe);
    spawn greetings(surname, children, pipe)
    ...
}

Any of those threads can be located on another "node"/machine;
the communications can be transparently encrypted, etc.

You can conceivably push *modules* (i.e., the "Sys"
executable) across a pipe and execute them on the other
remote end, etc.

But, like I said, you lose lots of fine grained control over
what is happening -- and *when*.  In return, you don't
worry about silly details that are closely tied to an
*implementation* (e.g., when do you invoke the garbage
collector?  Did you remember to NUL terminate your
"strings"?  Who cleans up the resources used by a
thread when the thread exits -- stack, string space, etc.)

[toc] | [prev] | [next] | [standalone]


#18698

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-03-13 17:14 -0400
Message-ID<4F5FB8C6.6030308@verizon.net>
In reply to#18697
On 03/13/2012 04:49 PM, Don Y wrote:
> Hi Ben,
> 
>>>> What's the advantage of putting threading into language instead
>>>> of the library?  (You explained *how* Limbo integrates threading
>>>> into the language, but not why it does.)
>>>
>>> It elevates threads to first-class objects.  It recognizes
>>> that programs are more "collections of threads" than "monolithic,
>>> single-threaded processes" that have to *struggle* to
>>> CO-operate.
>>
>> That is a nice statement of principles, but it's hard for me to
>> imagine what practical effect it would have on threaded C
>> programs.  Do you have an example to propose?
> 
> See below.

It would have been more helpful if your example had involved, as
specified, a "threaded C program".

[toc] | [prev] | [next] | [standalone]


#18702

FromDon Y <this@isnotme.com>
Date2012-03-13 14:35 -0700
Message-ID<jjoeic$nvu$1@speranza.aioe.org>
In reply to#18698
Hi James,

On 3/13/2012 2:14 PM, James Kuyper wrote:
> On 03/13/2012 04:49 PM, Don Y wrote:

>>>>> What's the advantage of putting threading into language instead
>>>>> of the library?  (You explained *how* Limbo integrates threading
>>>>> into the language, but not why it does.)
>>>>
>>>> It elevates threads to first-class objects.  It recognizes
>>>> that programs are more "collections of threads" than "monolithic,
>>>> single-threaded processes" that have to *struggle* to
>>>> CO-operate.
>>>
>>> That is a nice statement of principles, but it's hard for me to
>>> imagine what practical effect it would have on threaded C
>>> programs.  Do you have an example to propose?
>>
>> See below.
>
> It would have been more helpful if your example had involved, as
> specified, a "threaded C program".

That's left as an exercise for one of the language lawyers!  :>
(Note that you and keith are the ones who raised the topic of C's
support for these features)

Actually would be interesting to compare the size/complexity
of the two approaches.  Anyone with a *functional* knowledge
of the 2011 draft want to take a stab at it?

[toc] | [prev] | [next] | [standalone]


#18711

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-03-13 18:09 -0400
Message-ID<4F5FC58A.9040909@verizon.net>
In reply to#18702
On 03/13/2012 05:35 PM, Don Y wrote:
> Hi James,
> 
> On 3/13/2012 2:14 PM, James Kuyper wrote:
>> On 03/13/2012 04:49 PM, Don Y wrote:
> 
>>>>>> What's the advantage of putting threading into language instead
>>>>>> of the library?  (You explained *how* Limbo integrates threading
>>>>>> into the language, but not why it does.)
>>>>>
>>>>> It elevates threads to first-class objects.  It recognizes
>>>>> that programs are more "collections of threads" than "monolithic,
>>>>> single-threaded processes" that have to *struggle* to
>>>>> CO-operate.
>>>>
>>>> That is a nice statement of principles, but it's hard for me to
>>>> imagine what practical effect it would have on threaded C
>>>> programs.  Do you have an example to propose?
>>>
>>> See below.
>>
>> It would have been more helpful if your example had involved, as
>> specified, a "threaded C program".
> 
> That's left as an exercise for one of the language lawyers!  :>

That requires us to be able to correctly interpret Limbo code. You know
Limbo, I don't, and I suspect that such ignorance is fairly common here.
It should be incumbent on you, not us, to provide a translation.

Even if I were familiar with Limbo, I'm not competent to provide a
counter-example, and never claimed to be. I've written highly parallel
code - a quarter century ago, using a non-conforming C compiler, a
highly idiosyncratic operating system, and a concept that I no longer
remember the name of that was significantly different from the concept
of threads.
I've written ordinary POSIX threaded code - but that was just for fun,
about two decades ago, and I never even got it running, because I had
more urgent work that I was actually being paid to do. I've only just
started familiarizing myself with C2011 threads; I'm not ready to write
anything using them.

As the complainant, you should be competent to provide an example of the
problem you're complaining about - without such expertise the problem
could just be due to your lack of familiarity with the system. Not many
people are C2011 threading experts yet; I'd happily accept as relevant
an example using any other well-known threading system with a C
interface, such as POSIX threads. As I indicated above, I wouldn't be
competent to judge your example, but other people on this forum would
be; presumably including Ben Pfaff.

[toc] | [prev] | [next] | [standalone]


#18728

FromDon Y <this@isnotme.com>
Date2012-03-13 16:06 -0700
Message-ID<jjojtk$5ps$1@speranza.aioe.org>
In reply to#18711
Hi James,

On 3/13/2012 3:09 PM, James Kuyper wrote:

>>> It would have been more helpful if your example had involved, as
>>> specified, a "threaded C program".
>>
>> That's left as an exercise for one of the language lawyers!  :>
>
> That requires us to be able to correctly interpret Limbo code. You know
> Limbo, I don't, and I suspect that such ignorance is fairly common here.
> It should be incumbent on you, not us, to provide a translation.

A translation of the Limbo code appears at the end.  Expecting *me*
to come up with a C version that uses features THAT I DIDN'T KNOW
EXISTED as of a few hours ago would be as prepostrous as me asking
you to tell me why C's approach is better than a Limbo approach --
and expecting *you* to provide that Limbo example!  (assuming you've
never seen Limbo code until the same point in this thread that *I*
was informed of <threading.h>)

> Even if I were familiar with Limbo, I'm not competent to provide a
> counter-example, and never claimed to be. I've written highly parallel
> code - a quarter century ago, using a non-conforming C compiler, a
> highly idiosyncratic operating system, and a concept that I no longer
> remember the name of that was significantly different from the concept
> of threads.
> I've written ordinary POSIX threaded code - but that was just for fun,
> about two decades ago, and I never even got it running, because I had
> more urgent work that I was actually being paid to do. I've only just
> started familiarizing myself with C2011 threads; I'm not ready to write
> anything using them.

Understood.

> As the complainant, you should be competent to provide an example of the
> problem you're complaining about - without such expertise the problem
> could just be due to your lack of familiarity with the system. Not many

Exactly.  I have no interest in waiting for a C2011 implementation
on <whatever> processors I need to support.  I will probably never
even *work* in that environment.

> people are C2011 threading experts yet; I'd happily accept as relevant
> an example using any other well-known threading system with a C
> interface, such as POSIX threads. As I indicated above, I wouldn't be
> competent to judge your example, but other people on this forum would
> be; presumably including Ben Pfaff.

greetings(
   surname: string,     # parameter of type "string"
   children: list of (string, int)  # a list of tuples each
                                    # consisting of a string and an int
   output: chan of string   # communication channel named "output"
                            # that conveys strings
) {
    # create a string by concatenating the two string constants
    # with the string *variable* passed to the function as "surname"
    # pass the resulting string out the channel named "output"
    output <-= "Season's Greetings from the "
            + surname + " family!\n";

    # as long as the "children" list is not empty...
    while (children != nil) {
      # extract one the first ("head") element from the "children"
      # list assigning it's component values to "firstname" and "int"
      # the presence of the ':' is a syntactic shortcut that allows
      # the declaration of these variables to be deduced from the
      # values assigned to them (i.e., we know children consists
      # of (string, int) tuples so we know "firstname" is now declared
      # as a string and "age" is an int.  I.e., this just saves two
      # lines declaring those types as
      #    firstname: string;
      #    age: int;
      (firstname, age) := hd children;

      # ':' tells you that description is of the same type as the
      # rvalue -- a string (since the expression on the right is
      # recognizable as a string).  Set the description string
      # variable to the concatenation of the "firstname" and "surname"
      # strings -- with a constant string (whitespace) in the middle
      description := firstname + " " + surname;

      # tack on the parenthetical comment indicating the child's age
      # note the use of '=' instead of ":=" -- since we have already
      # declared description's type
      description = description
                  + " (" + age + " years old)";

      # pass the "fullname" (grrr... should have been "description")
      # string to the communication channel named "output"
      output <-= fullname;

      # assign the balance (everything beyond the "head") of the children
      # list to the children list variable
      children = tl children;
    }
}


logging(
   input: chan of string    # communication channel named "input"
                            # that conveys 'strings'
) {
    sys = load Sys Sys->PATH;   # a variable that holds a reference to
                                # a module called Sys.  Sys->PATH
                                # is a constant defined within that
                                # module indicating where it is

    while (FOREVER) {
      # text is a string (because it's type is derived from the
      # rhs type -- which is "chan of string"
      # It's value is assigned from the string fetched from the
      # communication channel named "input"
      text :=<- input;

      # use the print() member of the module referenced by "sys"
      # to print a string "somewhere" (i.e., like printf)
      sys->print("%s\n", text)
    }
}


job(surname: string,
     children: list of (string, int)  # you've seen this before...
) {
    pipe: channel of string;     # declare "pipe" to be a communication
                                 # channel (should have been "chan") that
                                 # conveys "string" data types.

    # create a thread that executes the "logging" function (defined
    # above).  Pass it a communication channel that it will use to
    # watch for incoming text
    spawn logging(pipe);

    # create a thread that executes the "greetings" function (defined
    # above).  Pass it the communication channel that it should use
    # to interact with the "logging" function started above.  Pass
    # the surname and list of children's (names, ages) to that
    # function (i.e., thread) so that it has some work to do.
    spawn greetings(surname, children, pipe)
    ...
}

I.e., anything that doesn't say "chan" or "spawn" in the above
is "application" and unrelated to the tasking aspects of the
language.

[toc] | [prev] | [next] | [standalone]


#18749

From"io_x" <a@b.c.invalid>
Date2012-03-14 08:18 +0100
Message-ID<4f604550$0$1385$4fafbaef@reader2.news.tin.it>
In reply to#18728
"Don Y" <this@isnotme.com> ha scritto nel messaggio
news:jjojtk$5ps$1@speranza.aioe.org...
> Hi James,
> greetings(
>   surname: string,     # parameter of type "string"
>   children: list of (string, int)  # a list of tuples each
>                                    # consisting of a string and an int
>   output: chan of string   # communication channel named "output"
>                            # that conveys strings
> ) {
>    # create a string by concatenating the two string constants
>    # with the string *variable* passed to the function as "surname"
>    # pass the resulting string out the channel named "output"
>    output <-= "Season's Greetings from the "
>            + surname + " family!\n";
>
>    # as long as the "children" list is not empty...
>    while (children != nil) {
>      # extract one the first ("head") element from the "children"
>      # list assigning it's component values to "firstname" and "int"
>      # the presence of the ':' is a syntactic shortcut that allows
>      # the declaration of these variables to be deduced from the
>      # values assigned to them (i.e., we know children consists
>      # of (string, int) tuples so we know "firstname" is now declared
>      # as a string and "age" is an int.  I.e., this just saves two
>      # lines declaring those types as
>      #    firstname: string;
>      #    age: int;
>      (firstname, age) := hd children;
>
>      # ':' tells you that description is of the same type as the
>      # rvalue -- a string (since the expression on the right is
>      # recognizable as a string).  Set the description string
>      # variable to the concatenation of the "firstname" and "surname"
>      # strings -- with a constant string (whitespace) in the middle
>      description := firstname + " " + surname;
>
>      # tack on the parenthetical comment indicating the child's age
>      # note the use of '=' instead of ":=" -- since we have already
>      # declared description's type
>      description = description
>                  + " (" + age + " years old)";
>
>      # pass the "fullname" (grrr... should have been "description")
>      # string to the communication channel named "output"
>      output <-= fullname;
>
>      # assign the balance (everything beyond the "head") of the children
>      # list to the children list variable
>      children = tl children;
>    }
> }

i see above as:

#define   R  return
#define   G  goto
#define   u8  unsigned char
#define   u32 unsigned

// at end of progr someone has to free the list children
i32 greetings(
   u8    *output,    # communication channel named "output"
   u8   *surname,    # parameter of type "string"
   u8  *children     # a list of tuples each
 ) {u8    *tmpStr, *tmpPlist;
    i32                  r=0;
    if(surname==0||output==0||children==0||ListNotOk(children))
                   R  1;

    # create a string by concatenating the two string constants
    # with the string *variable* passed to the function as "surname"
    # pass the resulting string out the channel named "output"
#    output <-= "Season's Greetings from the "
#            + surname + " family!\n";

    // StrMultiCat(u8** , ...) where ... are C string u8*
    if( StrMultiCat(&tmpStr, "Season's Greetings from the ",
               surname, " family!\n" )==-1 )
               {err:
                StrDel(&tmpStr); R  r
               }

    if(  StrSPut(output, tmpStr) == -1) {r=5; G err;}

    # as long as the "children" list is not empty...
    tmpPlist=0;
   // NextListElement of 0 is the first element of the list
   // [or 0 if it is a void list]
   // NextListElement of the last element of list is 0
    while(NextListElement(&tmpPlist, children)) !=  0 ) {
      # extract one the first ("head") element from the "children"
      # list assigning it's component values to "firstname" and "int"
      # the presence of the ':' is a syntactic shortcut that allows
      # the declaration of these variables to be deduced from the
      # values assigned to them (i.e., we know children consists
      # of (string, int) tuples so we know "firstname" is now declared
      # as a string and "age" is an int.  I.e., this just saves two
      # lines declaring those types as
      #    firstname: string;
      #    age: int;
      //    firstname: u8* string
      //    age:       u32
      #(firstname, age) := hd children;

// this assign each list element, the name of children of age hd
// what is hd? or what is age?
      if( StrMove(tmpPlist, children)==-1 ) {r=6; G err;}
      *(u32*)(tmpPlist+4)=hd;

      # ':' tells you that description is of the same type as the
      # rvalue -- a string (since the expression on the right is
      # recognizable as a string).  Set the description string
      # variable to the concatenation of the "firstname" and "surname"
      # strings -- with a constant string (whitespace) in the middle
      #description := firstname + " " + surname;
      if( StrMultiCat(&tmpStr, firstname, " ", surname)==-1 )
                                          {r=7; G err;}

       # tack on the parenthetical comment indicating the child's age
       # note the use of '=' instead of ":=" -- since we have already
       # declared description's type
       #description = description
       #            + " (" + age + " years old)";
       // you not say what the age is...

       if(     StrCat(&tmpStr, " (") == -1 ){r=10; G err;}
       if( StrCat_u32(&tmpStr, age)  == -1 ){r=11; G err;}
       if(     StrCat(&tmpStr,  " years old)") == -1 )
                                            {r=12; G err;}

       # pass the "fullname" (grrr... should have been "description")
       # string to the communication channel named "output"
       # output <-= fullname;

       if( StrSPut(output, tmpStr) == -1 ) {r=13; G err;}

       # assign the balance (everything beyond the "head") of the children
       # list to the children list variable

#       children = tl children;
not traslated: what is t1?

     }
   StrDel(&tmpStr);
   R  r;
  }

your way of check error are wrong
i'm sorry for the C++ people...

it is possible i never use type just u32 and u8 and their pointers
and going
to make less error of you because the functions check
if the structure passed to them is the riht type ie
the 0 are in the right positions in the memory,
the size of one element is not 4GB [or range error] etc

for example if i remeber well
i added to struct that descrive list one u32 random number
[associated to list type], so if pointed memory is not ok make
return error for the function that use the wrong pointer
to list...

ciao


[toc] | [prev] | [next] | [standalone]


#18758

From"io_x" <a@b.c.invalid>
Date2012-03-14 10:07 +0100
Message-ID<4f605ec9$0$1381$4fafbaef@reader2.news.tin.it>
In reply to#18749
"io_x" <a@b.c.invalid> ha scritto nel messaggio
news:4f604550$0$1385$4fafbaef@reader2.news.tin.it...
> #define   R  return
> #define   G  goto
> #define   u8  unsigned char
> #define   u32 unsigned
>
> // at end of progr someone has to free the list children
> i32 greetings(
>   u8    *output,    # communication channel named "output"
>   u8   *surname,    # parameter of type "string"
>   u8  *children     # a list of tuples each
> ) {u8    *tmpStr, *tmpPlist;
>    i32                  r=0;
>    if(surname==0||output==0||children==0||ListNotOk(children))
>                   R  1;
>
>    # create a string by concatenating the two string constants
>    # with the string *variable* passed to the function as "surname"
>    # pass the resulting string out the channel named "output"
> #    output <-= "Season's Greetings from the "
> #            + surname + " family!\n";
>
>    // StrMultiCat(u8** , ...) where ... are C string u8*
>    if( StrMultiCat(&tmpStr, "Season's Greetings from the ",
>               surname, " family!\n" )==-1 )

i realize StrMultiCat() function has need to know the number o element
it use: so what about something as:

 if( StrMultiCat(&tmpStr, 3, "Season's Greetings from the ",
                surname, " family!\n" )==-1 )


?

>               {err:
>                StrDel(&tmpStr); R  r
>               }
>
Buon Giorno



[toc] | [prev] | [next] | [standalone]


#18777

FromDon Y <this@isnotme.com>
Date2012-03-14 12:41 -0700
Message-ID<jjqs8d$e4o$1@speranza.aioe.org>
In reply to#18749
On 3/14/2012 12:18 AM, io_x wrote:

> i see above as:
>
> #define   R  return
> #define   G  goto
> #define   u8  unsigned char
> #define   u32 unsigned
>
> // at end of progr someone has to free the list children
> i32 greetings(
>     u8    *output,    # communication channel named "output"

No.  The *data type* of "output" is "communication channel".
There is no counterpart in C.  Think of it as a "named pipe"
that connects two threads -- possibly across machine boundaries.
You could provide similar functionality with a *socket*, a FIFO
or a managed shared memory region (in some contexts).  But, you
would have to explicitly set up this mechanism (function calls).

Limbo lets you just create one (and "pass it around") just like
you would an int, etc.

So, while you can accumulate the stuff intended to be transfered
across that channel *in* a string (assuming the channel is
declared to support strings -- and not ints or some other
data type!), you still have to actively *pass* it across
some communication mechanism.

Threading implies communication between threads.  Channels
formalize that.

>     u8   *surname,    # parameter of type "string"
>     u8  *children     # a list of tuples each

Not sure how you plan on storing those, yet...  Note that Limbo
makes it clear what you are intending *in* the declaration:
"This is a LIST of TUPLES where each is tuple consists of
a string (the child's name) and an integer (his age)"

>   ) {u8    *tmpStr, *tmpPlist;
>      i32                  r=0;
>      if(surname==0||output==0||children==0||ListNotOk(children))
>                     R  1;
>
>      # create a string by concatenating the two string constants
>      # with the string *variable* passed to the function as "surname"
>      # pass the resulting string out the channel named "output"
> #    output<-= "Season's Greetings from the "
> #            + surname + " family!\n";
>
>      // StrMultiCat(u8** , ...) where ... are C string u8*
>      if( StrMultiCat(&tmpStr, "Season's Greetings from the ",
>                 surname, " family!\n" )==-1 )
>                 {err:
>                  StrDel(&tmpStr); R  r
>                 }

Notice that you have to explicitly manage memory (to avoid leaks).
Limbo ensures that the resources you hold are automatically
free-d when you terminate.  I.e., it is part of the *language*
specification, not the "hosting environment".

>      if(  StrSPut(output, tmpStr) == -1) {r=5; G err;}

Again, all you have done is built a string.  No one else
can *see* it!  You haven't, yet:

   # pass the resulting string out the channel named "output"

>      # as long as the "children" list is not empty...
>      tmpPlist=0;
>     // NextListElement of 0 is the first element of the list
>     // [or 0 if it is a void list]
>     // NextListElement of the last element of list is 0
>      while(NextListElement(&tmpPlist, children)) !=  0 ) {
>        # extract one the first ("head") element from the "children"
>        # list assigning it's component values to "firstname" and "int"
>        # the presence of the ':' is a syntactic shortcut that allows
>        # the declaration of these variables to be deduced from the
>        # values assigned to them (i.e., we know children consists
>        # of (string, int) tuples so we know "firstname" is now declared
>        # as a string and "age" is an int.  I.e., this just saves two
>        # lines declaring those types as
>        #    firstname: string;
>        #    age: int;
>        //    firstname: u8* string
>        //    age:       u32
>        #(firstname, age) := hd children;
>
> // this assign each list element, the name of children of age hd
> // what is hd? or what is age?

hd = "head"

     # extract one the first ("head") element from the "children"
     # list assigning it's component values to "firstname" and "int"

My apologies for the typos.  This should have said:

     # extract one element -- the *first* ("head") element -- from the
     # "children"
     # list assigning it's component values to "firstname" and "AGE"

I'd have thought the intent would have been obvious even if the
commentary was crap  :>

>        if( StrMove(tmpPlist, children)==-1 ) {r=6; G err;}
>        *(u32*)(tmpPlist+4)=hd;
>
>        # ':' tells you that description is of the same type as the
>        # rvalue -- a string (since the expression on the right is
>        # recognizable as a string).  Set the description string
>        # variable to the concatenation of the "firstname" and "surname"
>        # strings -- with a constant string (whitespace) in the middle
>        #description := firstname + " " + surname;
>        if( StrMultiCat(&tmpStr, firstname, " ", surname)==-1 )
>                                            {r=7; G err;}
>
>         # tack on the parenthetical comment indicating the child's age
>         # note the use of '=' instead of ":=" -- since we have already
>         # declared description's type
>         #description = description
>         #            + " (" + age + " years old)";
>         // you not say what the age is...

See above comment.  (firstname, age) can be though of as
struct {
    char *firstname;
    int age;
}

The "children" list could be implemented as either a linked list
of these structs *or* an array -- with suitable code wrapped
around it to allow it to grow and shrink as needed.

>         if(     StrCat(&tmpStr, " (") == -1 ){r=10; G err;}
>         if( StrCat_u32(&tmpStr, age)  == -1 ){r=11; G err;}
>         if(     StrCat(&tmpStr,  " years old)") == -1 )
>                                              {r=12; G err;}
>
>         # pass the "fullname" (grrr... should have been "description")
>         # string to the communication channel named "output"
>         # output<-= fullname;
>
>         if( StrSPut(output, tmpStr) == -1 ) {r=13; G err;}
>
>         # assign the balance (everything beyond the "head") of the children
>         # list to the children list variable
>
> #       children = tl children;
> not traslated: what is t1?

tl == "tail"

     # assign the balance (everything beyond the "head") of the children
-------------^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^
     # list to the children list variable

>       }
>     StrDel(&tmpStr);
>     R  r;
>    }

Notice how much "manual" work you have to do to implement the
same sorts of functionality?  More opportunities for mistakes
(did you remember to free all your resources regardless of
the path you took through the code, etc.).  Limbo's syntax
is a lot cleaner (though admittedly cryptic for novices)

[toc] | [prev] | [next] | [standalone]


#18779

From"io_x" <a@b.c.invalid>
Date2012-03-14 21:53 +0100
Message-ID<4f610452$0$1385$4fafbaef@reader2.news.tin.it>
In reply to#18777
"Don Y" <this@isnotme.com> ha scritto nel messaggio 
news:jjqs8d$e4o$1@speranza.aioe.org...
> On 3/14/2012 12:18 AM, io_x wrote:
>
>> i see above as:
>>
>> #define   R  return
>> #define   G  goto
>> #define   u8  unsigned char
>> #define   u32 unsigned
>>
>> // at end of progr someone has to free the list children
>> i32 greetings(
>>     u8    *output,    # communication channel named "output"
>
> No.  The *data type* of "output" is "communication channel".
> There is no counterpart in C.  Think of it as a "named pipe"
> that connects two threads -- possibly across machine boundaries.
> You could provide similar functionality with a *socket*, a FIFO
> or a managed shared memory region (in some contexts).  But, you
> would have to explicitly set up this mechanism (function calls).

a pointer can point to each region of memory, that can be used
from functions for doing all is possible to do

> Limbo lets you just create one (and "pass it around") just like
> you would an int, etc.
>
> So, while you can accumulate the stuff intended to be transfered
> across that channel *in* a string (assuming the channel is

is not a string is a pointer to a unsigned char
[but it could be aligned to unsigned if the function initialize
it allow...]

> declared to support strings -- and not ints or some other
> data type!), you still have to actively *pass* it across
> some communication mechanism.
>
> Threading implies communication between threads.  Channels
> formalize that.
>
>>     u8   *surname,    # parameter of type "string"
>>     u8  *children     # a list of tuples each
>
> Not sure how you plan on storing those, yet...  Note that Limbo
> makes it clear what you are intending *in* the declaration:
> "This is a LIST of TUPLES where each is tuple consists of
> a string (the child's name) and an integer (his age)"

i have no problem with these char pointers...

>>   ) {u8    *tmpStr, *tmpPlist;
>>      i32                  r=0;
>>      if(surname==0||output==0||children==0||ListNotOk(children))
>>                     R  1;
>>
>>      # create a string by concatenating the two string constants
>>      # with the string *variable* passed to the function as "surname"
>>      # pass the resulting string out the channel named "output"
>> #    output<-= "Season's Greetings from the "
>> #            + surname + " family!\n";
>>
>>      // StrMultiCat(u8** , ...) where ... are C string u8*
>>      if( StrMultiCat(&tmpStr, "Season's Greetings from the ",
>>                 surname, " family!\n" )==-1 )
>>                 {err:
>>                  StrDel(&tmpStr); R  r
>>                 }
>
> Notice that you have to explicitly manage memory (to avoid leaks).

yes that is supposed a real programmer should do

> Limbo ensures that the resources you hold are automatically
> free-d when you terminate.  I.e., it is part of the *language*
> specification, not the "hosting environment".

i have not problem with memory leak

>>      if(  StrSPut(output, tmpStr) == -1) {r=5; G err;}
>
> Again, all you have done is built a string.  No one else
> can *see* it!  You haven't, yet:

no "output" can point, for example to a C like FILE struct etc

>   # pass the resulting string out the channel named "output"
>
>>      # as long as the "children" list is not empty...
>>      tmpPlist=0;
>>     // NextListElement of 0 is the first element of the list
>>     // [or 0 if it is a void list]
>>     // NextListElement of the last element of list is 0
>>      while(NextListElement(&tmpPlist, children)) !=  0 ) {
>>        # extract one the first ("head") element from the "children"
>>        # list assigning it's component values to "firstname" and "int"
>>        # the presence of the ':' is a syntactic shortcut that allows
>>        # the declaration of these variables to be deduced from the
>>        # values assigned to them (i.e., we know children consists
>>        # of (string, int) tuples so we know "firstname" is now declared
>>        # as a string and "age" is an int.  I.e., this just saves two
>>        # lines declaring those types as
>>        #    firstname: string;
>>        #    age: int;
>>        //    firstname: u8* string
>>        //    age:       u32
>>        #(firstname, age) := hd children;
>>
>> // this assign each list element, the name of children of age hd
>> // what is hd? or what is age?
>
> hd = "head"
>
>     # extract one the first ("head") element from the "children"
>     # list assigning it's component values to "firstname" and "int"
>
> My apologies for the typos.  This should have said:
>
>     # extract one element -- the *first* ("head") element -- from the
>     # "children"
>     # list assigning it's component values to "firstname" and "AGE"
>
> I'd have thought the intent would have been obvious even if the
> commentary was crap  :>
>
>>        if( StrMove(tmpPlist, children)==-1 ) {r=6; G err;}
>>        *(u32*)(tmpPlist+4)=hd;
>>
>>        # ':' tells you that description is of the same type as the
>>        # rvalue -- a string (since the expression on the right is
>>        # recognizable as a string).  Set the description string
>>        # variable to the concatenation of the "firstname" and "surname"
>>        # strings -- with a constant string (whitespace) in the middle
>>        #description := firstname + " " + surname;
>>        if( StrMultiCat(&tmpStr, firstname, " ", surname)==-1 )
>>                                            {r=7; G err;}
>>
>>         # tack on the parenthetical comment indicating the child's age
>>         # note the use of '=' instead of ":=" -- since we have already
>>         # declared description's type
>>         #description = description
>>         #            + " (" + age + " years old)";
>>         // you not say what the age is...
>
> See above comment.  (firstname, age) can be though of as
> struct {
>    char *firstname;
>    int age;
> }
>
> The "children" list could be implemented as either a linked list
> of these structs *or* an array -- with suitable code wrapped
> around it to allow it to grow and shrink as needed.

can be upside down and down upside, at end i say it should be ok

>>         if(     StrCat(&tmpStr, " (") == -1 ){r=10; G err;}
>>         if( StrCat_u32(&tmpStr, age)  == -1 ){r=11; G err;}
>>         if(     StrCat(&tmpStr,  " years old)") == -1 )
>>                                              {r=12; G err;}
>>
>>         # pass the "fullname" (grrr... should have been "description")
>>         # string to the communication channel named "output"
>>         # output<-= fullname;
>>
>>         if( StrSPut(output, tmpStr) == -1 ) {r=13; G err;}
>>
>>         # assign the balance (everything beyond the "head") of the children
>>         # list to the children list variable
>>
>> #       children = tl children;
>> not traslated: what is t1?
>
> tl == "tail"
>
>     # assign the balance (everything beyond the "head") of the children
> -------------^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^
>     # list to the children list variable
>
>>       }
>>     StrDel(&tmpStr);
>>     R  r;
>>    }
>
> Notice how much "manual" work you have to do to implement the
> same sorts of functionality?

i'm not agree

> More opportunities for mistakes
> (did you remember to free all your resources regardless of
> the path you took through the code, etc.).  Limbo's syntax
> is a lot cleaner (though admittedly cryptic for novices)

leak are not my problems, but problem of my malloc()
function implementation ...


[toc] | [prev] | [next] | [standalone]


#18813

FromDon Y <this@isnotme.com>
Date2012-03-15 14:16 -0700
Message-ID<jjtm7m$nj5$1@speranza.aioe.org>
In reply to#18779
>>> // at end of progr someone has to free the list children
>>> i32 greetings(
>>>      u8    *output,    # communication channel named "output"
>>
>> No.  The *data type* of "output" is "communication channel".
>> There is no counterpart in C.  Think of it as a "named pipe"
>> that connects two threads -- possibly across machine boundaries.
>> You could provide similar functionality with a *socket*, a FIFO
>> or a managed shared memory region (in some contexts).  But, you
>> would have to explicitly set up this mechanism (function calls).
>
> a pointer can point to each region of memory, that can be used
> from functions for doing all is possible to do

Sure!  And where do you synchronize access to that region with
other threads?  What happens when the region is "full"?  Do you
reset the pointer to the "beginning" and keep going?  How does
the thread on the other end know *where* you are in this region
and where the "still undefined" portion of the region begins
(so it doesn't look for real data in those places)

>> Limbo lets you just create one (and "pass it around") just like
>> you would an int, etc.
>>
>> So, while you can accumulate the stuff intended to be transfered
>> across that channel *in* a string (assuming the channel is
>
> is not a string is a pointer to a unsigned char
> [but it could be aligned to unsigned if the function initialize
> it allow...]

Understood.  But it still isn't a complete communication
system.  See above

>> declared to support strings -- and not ints or some other
>> data type!), you still have to actively *pass* it across
>> some communication mechanism.
>>
>> Threading implies communication between threads.  Channels
>> formalize that.
>>
>>>      u8   *surname,    # parameter of type "string"
>>>      u8  *children     # a list of tuples each
>>
>> Not sure how you plan on storing those, yet...  Note that Limbo
>> makes it clear what you are intending *in* the declaration:
>> "This is a LIST of TUPLES where each is tuple consists of
>> a string (the child's name) and an integer (his age)"
>
> i have no problem with these char pointers...

But *you* are responsible for implementing the list and the
tuples within it.  I have no problem multiplying integers
in a loop of successive shifts and conditional adds.  But,
I would much rather type an '*' between the two variable
names!  :>

>>>    ) {u8    *tmpStr, *tmpPlist;
>>>       i32                  r=0;
>>>       if(surname==0||output==0||children==0||ListNotOk(children))
>>>                      R  1;
>>>
>>>       # create a string by concatenating the two string constants
>>>       # with the string *variable* passed to the function as "surname"
>>>       # pass the resulting string out the channel named "output"
>>> #    output<-= "Season's Greetings from the "
>>> #            + surname + " family!\n";
>>>
>>>       // StrMultiCat(u8** , ...) where ... are C string u8*
>>>       if( StrMultiCat(&tmpStr, "Season's Greetings from the ",
>>>                  surname, " family!\n" )==-1 )
>>>                  {err:
>>>                   StrDel(&tmpStr); R  r
>>>                  }
>>
>> Notice that you have to explicitly manage memory (to avoid leaks).
>
> yes that is supposed a real programmer should do

Sure.  IF THE LANGUAGE DOESN'T DO IT FOR YOU!

I.e., when a UN*X process ends, the system doesn't complain
that you forgot to free() some memory that you had allocated
BEFORE the process terminated.

The designers of the process semantics opted to take care of
this little detail *for* you because it is something that
is common enough in actual use.  "Sorry, you forgot to
free() your resources so we are going to mess with the
operation of other UNRELATED processes in the system just
to ensure those folks get REALLY mad at you and force you
to behave more hospitably"  :>

>> Limbo ensures that the resources you hold are automatically
>> free-d when you terminate.  I.e., it is part of the *language*
>> specification, not the "hosting environment".
>
> i have not problem with memory leak
>
>>>       if(  StrSPut(output, tmpStr) == -1) {r=5; G err;}
>>
>> Again, all you have done is built a string.  No one else
>> can *see* it!  You haven't, yet:
>
> no "output" can point, for example to a C like FILE struct etc

Again, see above.  How does "logging()" know that you have
added something to that region of memory?  What happens when
logging() gets ahead of you?  Does it just print whatever
jibberish happened to reside in that region of memory
BEFORE you got around to stuffing tmpStr into it?

[big snip]

>> The "children" list could be implemented as either a linked list
>> of these structs *or* an array -- with suitable code wrapped
>> around it to allow it to grow and shrink as needed.
>
> can be upside down and down upside, at end i say it should be ok
>
>>>          if(     StrCat(&tmpStr, " (") == -1 ){r=10; G err;}
>>>          if( StrCat_u32(&tmpStr, age)  == -1 ){r=11; G err;}
>>>          if(     StrCat(&tmpStr,  " years old)") == -1 )
>>>                                               {r=12; G err;}
>>>
>>>          # pass the "fullname" (grrr... should have been "description")
>>>          # string to the communication channel named "output"
>>>          # output<-= fullname;
>>>
>>>          if( StrSPut(output, tmpStr) == -1 ) {r=13; G err;}
>>>
>>>          # assign the balance (everything beyond the "head") of the children
>>>          # list to the children list variable
>>>
>>> #       children = tl children;
>>> not traslated: what is t1?
>>
>> tl == "tail"
>>
>>      # assign the balance (everything beyond the "head") of the children
>> -------------^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^
>>      # list to the children list variable
>>
>>>        }
>>>      StrDel(&tmpStr);
>>>      R  r;
>>>     }
>>
>> Notice how much "manual" work you have to do to implement the
>> same sorts of functionality?
>
> i'm not agree

That's your perogative!  :>  Some of us even use assembly language
(gasp!  heresy!!)

>> More opportunities for mistakes
>> (did you remember to free all your resources regardless of
>> the path you took through the code, etc.).  Limbo's syntax
>> is a lot cleaner (though admittedly cryptic for novices)
>
> leak are not my problems, but problem of my malloc()
> function implementation ...

If you forget to free something that *you* caused to be allocated
(either directly or indirectly), then the leak is *your* problem.
You can't blame the memory subsystem for failing to read your
mind.

[toc] | [prev] | [next] | [standalone]


#18844

From"io_x" <a@b.c.invalid>
Date2012-03-18 07:14 +0100
Message-ID<4f657c41$0$1391$4fafbaef@reader1.news.tin.it>
In reply to#18813
"Don Y" <this@isnotme.com> ha scritto nel messaggio
news:jjtm7m$nj5$1@speranza.aioe.org...
>>>> // at end of progr someone has to free the list children
>>>> i32 greetings(
>>>>      u8    *output,    # communication channel named "output"
>>>
>>> No.  The *data type* of "output" is "communication channel".
>>> There is no counterpart in C.  Think of it as a "named pipe"
>>> that connects two threads -- possibly across machine boundaries.
>>> You could provide similar functionality with a *socket*, a FIFO
>>> or a managed shared memory region (in some contexts).  But, you
>>> would have to explicitly set up this mechanism (function calls).
>>
>> a pointer can point to each region of memory, that can be used
>> from functions for doing all is possible to do
>
> Sure!  And where do you synchronize access to that region with
> other threads?

it is the OS that, using one unsigned 32 bit region of mem,
say to function if it is safe to read write to list struct,
if it is safe to use the list or not...

>What happens when the region is "full"?  Do you
> reset the pointer to the "beginning" and keep going?  How does
> the thread on the other end know *where* you are in this region
> and where the "still undefined" portion of the region begins
> (so it doesn't look for real data in those places)

OS know one single thread use the list


[toc] | [prev] | [next] | [standalone]


#18761

FromJens Gustedt <jens.gustedt@loria.fr>
Date2012-03-14 10:39 +0100
Message-ID<4F60673F.9090407@loria.fr>
In reply to#18711
Am 03/13/2012 11:09 PM, schrieb James Kuyper:
> I've written ordinary POSIX threaded code - but that was just for fun,
> about two decades ago, and I never even got it running, because I had
> more urgent work that I was actually being paid to do. I've only just
> started familiarizing myself with C2011 threads; I'm not ready to write
> anything using them.

Just as a side note, C11 threading is basically POSIX threads with
reduced tuning functionality. It is relatively easily emulated by
POSIX threads. (There is just one major issue with the return type of
the thread functions, POSIX has void* where C11 has int)

I have written a lightweighted emulation in that sense that you could
check out to improve your practical skills :)

Jens

[toc] | [prev] | [next] | [standalone]


#18701

FromBen Pfaff <blp@cs.stanford.edu>
Date2012-03-13 14:33 -0700
Message-ID<87k42otccx.fsf@blp.benpfaff.org>
In reply to#18697
Don Y <this@isnotme.com> writes:

>>> Moving things into the language also changes who is
>>> responsible for the implementation and performance of
>>> the feature.  In Limbo, the "compiler"/runtime VM handle
>>> ALL of the mechanisms associated with these features.
>>> it means that those features are accessible to your
>>> code on any platform that can support Limbo programs.
>>> (double edged sword... if you don't like how they do
>>> it, you can't just swap out that aspect like you can with
>>> a separate library).
>>
>> Threading is intentionally an optional feature for C
>> implementations, because C is supposed to work on platforms that
>> do not or cannot support threads.
>
> Yes.  This goes to my comment (elsewhere) about the "attitude"
> (philosophy?) that C presents vs. other languages.  E.g.,
> C exposes lots of fine-grained detail and gives you a great
> deal of control over what's happening "now".
>
> By contrast, Limbo (and its Inferno base) *hides* lots of
> detail from the developer.  E.g., (apologies for any typos)

The difference, at least in the way that you present it, goes far
beyond threading, so I wonder how applying the "Limbo philosophy"
to only a single feature of C (threading) would be useful in C.
-- 
Ben Pfaff 
http://benpfaff.org

[toc] | [prev] | [next] | [standalone]


#18703

FromDon Y <this@isnotme.com>
Date2012-03-13 14:40 -0700
Message-ID<jjoes0$otl$1@speranza.aioe.org>
In reply to#18701
Hi Ben,

On 3/13/2012 2:33 PM, Ben Pfaff wrote:
> Don Y<this@isnotme.com>  writes:
>
>>>> Moving things into the language also changes who is
>>>> responsible for the implementation and performance of
>>>> the feature.  In Limbo, the "compiler"/runtime VM handle
>>>> ALL of the mechanisms associated with these features.
>>>> it means that those features are accessible to your
>>>> code on any platform that can support Limbo programs.
>>>> (double edged sword... if you don't like how they do
>>>> it, you can't just swap out that aspect like you can with
>>>> a separate library).
>>>
>>> Threading is intentionally an optional feature for C
>>> implementations, because C is supposed to work on platforms that
>>> do not or cannot support threads.
>>
>> Yes.  This goes to my comment (elsewhere) about the "attitude"
>> (philosophy?) that C presents vs. other languages.  E.g.,
>> C exposes lots of fine-grained detail and gives you a great
>> deal of control over what's happening "now".
>>
>> By contrast, Limbo (and its Inferno base) *hides* lots of
>> detail from the developer.  E.g., (apologies for any typos)

[examples elided]

> The difference, at least in the way that you present it, goes far
> beyond threading, so I wonder how applying the "Limbo philosophy"
> to only a single feature of C (threading) would be useful in C.

You can elide the use of tuples, lists, strings, etc. and
concoct a more trivial example.  *But*, with threading,
you still need communications (between threads), resource
management (for the spawned threads creation/termination),
etc.

I suspect that if you trim the Limbo example down to passing
a const int back and forth between two threads (I originally
considered sending "ping" from A to B and having B reply with
"pong", etc.) you could come up with a similar implementation
in C that does the exact same thing -- and see how you would
approach it.  From there, think about how you would pass
larger objects, communicate between multiple threads, implement
synchronization primitives, etc.

[toc] | [prev] | [next] | [standalone]


#18732

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-03-13 16:25 -0700
Message-ID<kfn1uowm6c4.fsf@x-alumni2.alumni.caltech.edu>
In reply to#18685
blp@cs.stanford.edu (Ben Pfaff) writes:

> Don Y <this@isnotme.com> writes:
>
>> On 3/13/2012 5:59 AM, Keith Thompson wrote:
>>> Don Y<this@isnotme.com>  writes:
>>>> Why not support for *tasking* -- native to the language
>>>> (instead of in a library!) like Limbo?
>>>
>>> The 2011 ISO C standard includes (optional) support for threading.
>>>
>>> See<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>
>>> section 7.26.
>>
>> OK.  But that's just another standard library.  The language
>> itself doesn't include those provisions.

(to repeat myself, IMO this statement is inaccurate for C2011.)


> What's the advantage of putting threading into language instead
> of the library?  (You explained *how* Limbo integrates threading
> into the language, but not why it does.)

I assume most people in the group have seen this, but for those
who have not:


  Threads Cannot be Implemented as a Library

  Boehm, Hans-J.

  HPL-2004-209

  Abstract:  In many environments, multi-threaded code is written
  in a language that was originally designed without thread support
  (e.g.  C), to which a library of threading primitives was
  subsequently added.  There appears to be a general understanding
  that this is not the right approach.  We provide specific
  arguments that a pure library approach, in which the compiler is
  designed independently of threading issues, cannot guarantee
  correctness of the resulting code.  We first review why the
  approach almost works, and then examine some of the surprising
  behavior it may entail.  We further illustrate that there are
  very simple cases in which a pure library-based approach seems
  incapable of expressing an efficient parallel algorithm.  Our
  discussion takes place in the context of C with Pthreads, since
  it is commonly used, reasonably well specified, and does not
  attempt to ensure type-safety, which would entail even stronger
  constraints.  The issues we raise are not specific to that
  context.

  http://www.hpl.hp.com/techreports/2004/HPL-2004-209.pdf

[toc] | [prev] | [next] | [standalone]


#18751

FromDon Y <this@isnotme.com>
Date2012-03-14 00:51 -0700
Message-ID<jjpim1$vka$1@speranza.aioe.org>
In reply to#18732
Hi Tim,

On 3/13/2012 4:25 PM, Tim Rentsch wrote:
> blp@cs.stanford.edu (Ben Pfaff) writes:
>> Don Y<this@isnotme.com>  writes:
>>> On 3/13/2012 5:59 AM, Keith Thompson wrote:
>>>> Don Y<this@isnotme.com>   writes:
>>>>> Why not support for *tasking* -- native to the language
>>>>> (instead of in a library!) like Limbo?
>>>>
>>>> The 2011 ISO C standard includes (optional) support for threading.
>>>>
>>>> See<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>
>>>> section 7.26.
>>>
>>> OK.  But that's just another standard library.  The language
>>> itself doesn't include those provisions.
>
> (to repeat myself, IMO this statement is inaccurate for C2011.)
>
>> What's the advantage of putting threading into language instead
>> of the library?  (You explained *how* Limbo integrates threading
>> into the language, but not why it does.)
>
> I assume most people in the group have seen this, but for those
> who have not:
>
>    Threads Cannot be Implemented as a Library
>
>    Boehm, Hans-J.
>
>    HPL-2004-209
>
>    Abstract:  In many environments, multi-threaded code is written
>    in a language that was originally designed without thread support
>    (e.g.  C), to which a library of threading primitives was
>    subsequently added.  There appears to be a general understanding
>    that this is not the right approach.  We provide specific
>    arguments that a pure library approach, in which the compiler is
>    designed independently of threading issues, cannot guarantee
>    correctness of the resulting code.  We first review why the
>    approach almost works, and then examine some of the surprising
>    behavior it may entail.  We further illustrate that there are
>    very simple cases in which a pure library-based approach seems
>    incapable of expressing an efficient parallel algorithm.  Our
>    discussion takes place in the context of C with Pthreads, since
>    it is commonly used, reasonably well specified, and does not
>    attempt to ensure type-safety, which would entail even stronger
>    constraints.  The issues we raise are not specific to that
>    context.
>
>    http://www.hpl.hp.com/techreports/2004/HPL-2004-209.pdf

I think the problem being addressed, here, boil down to
removing the need for the developer to "take precautions"
(i.e., manually ensure that the compiler doesn't "get ahead
of him") along with wanting to be able to use the language
to *efficiently* implement truly parallel threads of
execution.

In practice (at least in the applications I've designed),
you partition an application with an eye towards keeping
individual threads "disjoint".  "Communication is
expensive" so you want to minimize the amount of data
that has to be shared between threads (and processes,
too, but that's another level).

As you reduce the communication interconnects, the relative
cost of synchronization, mutual exclusion, etc. drop.  So, the
cost to *implement* them can creep up without having dramatic
effects on the overall performance of the application.

I.e., a truly parallel approach to a problem having multiple
threads (possibly executing on SMP) each actively accessing
the same data set is impractical with the overhead of library
calls (even if they are lightweight).

OTOH, having one thread do <something> and another thread
doing <somethingcompletelydifferent> -- with little or no
interaction between them -- incurs very little added cost.

If you want to allow the programmer to divorce himself
from this responsibility (?), then the compiler has to
take a more active role in guaranteeing this behavior.

[toc] | [prev] | [next] | [standalone]


#18781

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-03-14 14:25 -0700
Message-ID<kfnobrylvt0.fsf@x-alumni2.alumni.caltech.edu>
In reply to#18751
Don Y <this@isnotme.com> writes:

> Hi Tim,
>
> On 3/13/2012 4:25 PM, Tim Rentsch wrote:
>> blp@cs.stanford.edu (Ben Pfaff) writes:
>>> Don Y<this@isnotme.com>  writes:
>>>> On 3/13/2012 5:59 AM, Keith Thompson wrote:
>>>>> Don Y<this@isnotme.com>   writes:
>>>>>> Why not support for *tasking* -- native to the language
>>>>>> (instead of in a library!) like Limbo?
>>>>>
>>>>> The 2011 ISO C standard includes (optional) support for threading.
>>>>>
>>>>> See<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>
>>>>> section 7.26.
>>>>
>>>> OK.  But that's just another standard library.  The language
>>>> itself doesn't include those provisions.
>>
>> (to repeat myself, IMO this statement is inaccurate for C2011.)
>>
>>> What's the advantage of putting threading into language instead
>>> of the library?  (You explained *how* Limbo integrates threading
>>> into the language, but not why it does.)
>>
>> I assume most people in the group have seen this, but for those
>> who have not:
>>
>>    Threads Cannot be Implemented as a Library
>>
>>    Boehm, Hans-J.
>>
>>    HPL-2004-209
>>
>>    Abstract:  In many environments, multi-threaded code is written
>>    in a language that was originally designed without thread support
>>    (e.g.  C), to which a library of threading primitives was
>>    subsequently added.  There appears to be a general understanding
>>    that this is not the right approach.  We provide specific
>>    arguments that a pure library approach, in which the compiler is
>>    designed independently of threading issues, cannot guarantee
>>    correctness of the resulting code.  We first review why the
>>    approach almost works, and then examine some of the surprising
>>    behavior it may entail.  We further illustrate that there are
>>    very simple cases in which a pure library-based approach seems
>>    incapable of expressing an efficient parallel algorithm.  Our
>>    discussion takes place in the context of C with Pthreads, since
>>    it is commonly used, reasonably well specified, and does not
>>    attempt to ensure type-safety, which would entail even stronger
>>    constraints.  The issues we raise are not specific to that
>>    context.
>>
>>    http://www.hpl.hp.com/techreports/2004/HPL-2004-209.pdf
>
> I think the problem being addressed, here,

Did you read the paper?

> boil down to
> removing the need for the developer to "take precautions"
> (i.e., manually ensure that the compiler doesn't "get ahead
> of him") along with wanting to be able to use the language
> to *efficiently* implement truly parallel threads of
> execution.  [snip elaboration]

The problem is the compiler is operating at the wrong level of
abstraction.  Whether the compiler "gets ahead" of a developer
(a frightening concept in and of itself, but let's ignore
that) doesn't matter, because the operating environment that
(non-thread-aware) compilers generate code for doesn't make
strong enough guarantees about inter-thread or inter-processor
memory consistency.  To get threads to work usably, at least
part of the compiler needs to be aware of a lower level of
abstraction, below the architectural level for a single
process (which is where essentially all pre-thread-aware
compilers operate).

[toc] | [prev] | [next] | [standalone]


#18811

FromDon Y <this@isnotme.com>
Date2012-03-15 13:40 -0700
Message-ID<jjtk44$hih$1@speranza.aioe.org>
In reply to#18781
Hi Tim,

On 3/14/2012 2:25 PM, Tim Rentsch wrote:

>>> I assume most people in the group have seen this, but for those
>>> who have not:
>>>
>>>     Threads Cannot be Implemented as a Library
>>>
>>>     Boehm, Hans-J.
>>>
>>>     HPL-2004-209
>>>
>>>     Abstract:  In many environments, multi-threaded code is written
>>>     in a language that was originally designed without thread support
>>>     (e.g.  C), to which a library of threading primitives was
>>>     subsequently added.  There appears to be a general understanding
>>>     that this is not the right approach.  We provide specific
>>>     arguments that a pure library approach, in which the compiler is
>>>     designed independently of threading issues, cannot guarantee
>>>     correctness of the resulting code.  We first review why the
>>>     approach almost works, and then examine some of the surprising
>>>     behavior it may entail.  We further illustrate that there are
>>>     very simple cases in which a pure library-based approach seems
>>>     incapable of expressing an efficient parallel algorithm.  Our
>>>     discussion takes place in the context of C with Pthreads, since
>>>     it is commonly used, reasonably well specified, and does not
>>>     attempt to ensure type-safety, which would entail even stronger
>>>     constraints.  The issues we raise are not specific to that
>>>     context.
>>>
>>>     http://www.hpl.hp.com/techreports/2004/HPL-2004-209.pdf
>>
>> I think the problem being addressed, here,
>
> Did you read the paper?

Yes, hence my comments.  To take (roughly) the cases presented
in the paper:

4.1) You *know* when writing multithreaded code that
control to *any* shared object has to be arbitrated
(this is, IMO, one of the key points the article
tries to skirt... as if wanting NOT to have the
developer be concerned with these issues -- an
admirable goal but not one that rules out threading
libraries as a possible solution).  The examples given
in this section show *no* explicit acknowledgement that
the objects/data are shared nor any mechanism to ensure
that sharing works (i.e., not even a library call is
present!)

4.2) is yet another example of the above.  Except, in
addition to the lack of any formal access control
mechanism, there is now the acknowledgement that a
datum may span "objects".  I.e., yet another case of
wanting to protect the programmer from things he might
have failed to notice (though still not anything that
precludes a library based solution)

4.3) Frankly, I don't see the problem here (too early
in the day?).  Aside from the INEFFICIENCY that is
introduced...  where is the code "broken"?  OK, the
compiler's optimizations may have been unfortunate
but does the code perform as intended?

5.1) Makes the efficiency argument explicit -- and
goes to my comment regarding truly parallel implementations.

   for (my_prime = start; my_prime < 10000; ++my_prime) {
     if (!get(my_prime)) {
       for (mult = my_prime; mult < 100000000; mult += my_prime) {
         if (!get(mult)) {
            set(mult);
         }
       }
     }
   }

is written *assuming* multiple threads can access the array
(sieve) hidden behind get()/set() inexpensively and concurrently.
The author then complains that the implementation of set()/get()
can cause problems -- for exactly the same reasons in 4.x.

I.e., the authors are advocating freeing the developer from
any concerns associated with implementing concurrency.
"Let's let the compiler consider all of these possible
cases and craft some rules that are *different* from the
rules a multithreaded programmer already SHOULD know..."
Yet, complain when safeguarding against those problems
(e.g., by invoking a mutex per shared object) becomes
"expensive":  "Where's *my* free lunch??"

Sure, it would be delightful to *have* such protection
(i.e., scissors that automatically cover their blades
when they detect that you are "running with them").
But, I don't see how that PREVENTS a library based solution
from working.

E.g., wrap the internals of get()/set() with a lock.
The concurrency problems go away -- but performance
plummets.  BECAUSE YOUR THREADS ARE COMPETING FOR TOO
MUCH DATA.

OTOH, having a thread doing this while another thread is
balancing your checkbook and still another is darning
your socks incurs NO performance penalty.

Yeah, its unfortunate that I can't get 500 digits of
precision in all of my math "for free".  But, I don't
*expect* it to be free!

>> boil down to
>> removing the need for the developer to "take precautions"
>> (i.e., manually ensure that the compiler doesn't "get ahead
>> of him") along with wanting to be able to use the language
>> to *efficiently* implement truly parallel threads of
>> execution.  [snip elaboration]
>
> The problem is the compiler is operating at the wrong level of
> abstraction.  Whether the compiler "gets ahead" of a developer
> (a frightening concept in and of itself, but let's ignore
> that) doesn't matter, because the operating environment that
> (non-thread-aware) compilers generate code for doesn't make
> strong enough guarantees about inter-thread or inter-processor
> memory consistency.  To get threads to work usably, at least
> part of the compiler needs to be aware of a lower level of
> abstraction, below the architectural level for a single
> process (which is where essentially all pre-thread-aware
> compilers operate).

I don't see that.  I think that's only the case if you want
the compiler to be able to implement the safeguards *for* you.
And, I only see it pertaining to certain types of optimizations
(if the compiler doesn't make those optimizations, then your
code isn't at risk for them!)

I.e., I don't see how that PRECLUDES the use of a library.

Compilers are unaware of interrupts.  An interrupt can occur
between any two instructions.  Does that mean a you can't write
code in C that will operate in the presence of interrupts?

What it *does* mean is that anything that your code could be
doing that an interrupt might want to ASYNCHRONOUSLY interfere
with needs to be protected against that interference.  Likewise,
anything your code wants to be able to *convey* to your ISR
needs to take precautions that the ISR sees "the whole picture"
and not just *part* of it.

Am I missing something, here?

[toc] | [prev] | [next] | [standalone]


Page 2 of 5 — ← Prev page 1 [2] 3 4 5  Next page →

Back to top | Article view | comp.lang.c


csiph-web