[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Feature request: plain option for gsub
- From: Sean Conner <sean@...>
- Date: Sat, 23 Aug 2014 03:54:59 -0400
It was thus said that the Great Coroutines once stated:
> On Fri, Aug 22, 2014 at 11:33 PM, Sean Conner <sean@conman.org> wrote:
>
> > Okay, now I'm totally confused as to what you are trying to do. Let's
> > take, for example, LPeg.
> >
> > > lpeg = require "lpeg" -- I'm using 0.12 BTW
> > > x = lpeg.P "Coroutines"
> > > print(type(x))
> > userdata: 0x8835e7c
>
> > Okay, what exactly, are you trying to modify?
>
> Okay. From Lua you have a userdata object.
f = io.open("Mail/lua-list","r")
Okay, I have my userdata.
> You can use # to get the
> size of that, assuming __len isn't doing anything deceptive.
Um. So what should #f return in this case? The size of the file? Works
fine for real files, but how about
f = io.open("/dev/zero","r")
What does
x = lpeg.P "Coroutines"
print(#x)
even mean?
> I want to be able to string.sub() userdata, so I can read
> character-by-character. Promoting a lua_Buffer/userdata to a string
> hashes the userdata and from then on it's known as a string to Lua, and I
> cannot modify it.
Okay, you are definitely associating "userdata" with "large, growable
character array". userdata is more than just that.
> > I also don't fully understand what you mean by:
> >
> >> I dream of a world without data channels and serializing things
>
> The cost of serializing an object and sharing it through some method
> of IPC is more than it needs to be. I take issue with the concept of
> it. When I have brought this up before I'm told to look elsewhere for
> inefficiency, but I am someone who likes to solve benign problems.
> Also lock-free algorithms are a thing. Message-passing will never be
> as quick as zero-copied, shared data ;>
The Amiga did zero-copy message passing. Upside: it was quick.
Downsides:
1) if the sending thread/process crashed, you leaked memory
2) you could only send messages to other threads/processes on the
same system.
3) you could crash the system if you did it wrong.
By 3, I mean doing something like:
struct mymessage
{
struct Message msg;
int important;
}
int blowitup(void)
{
struct MsgPort *port;
struct mymessage mess;
mess.msg.mn_Length = sizeof(mess);
mess.msg.mn_ReplyPort = NULL;
mess.important = 1;
port = FindPort("somemessageport");
if (port)
PutMsg(port,&mess);
}
/* um ... we just blew up the system */
Even if you were careful and allocated the message, you could still cause
havoc:
struct mymessage
{
struct Message msg;
char *important;
}
int blowitup(void)
{
struct MsgPort *port;
struct mymessage *mess;
char *important;
mess = malloc(sizeof(mess));
important = malloc(32);
if ((mess == NULL) || (important == NULL))
{
free(mess);
free(important);
return -1;
}
strcpy(important,"Boom!");
mess->msg.mn_Length = sizeof(mess);
mess->msg.mn_ReplyPort = NULL;
mess->important = important;
port = FindPort("somemessageport");
if (port)
PutMsg(port,mess);
/* Boom! */
free(important);
}
The Amiga could do this because it didn't have virtual memory (even though
it was a multitasking operating system---the two are othogonal and having
one doesn't imply the other) and thus, it worked.
But once you introduce virtual memory, then you have three options:
1) Shared memory. It gets somewhat problematic if process A wants
to send a message to B, who then wants to send it to C. It's not
really an "ad-hoc, let's just do it" type of operation; all the
processes must co-ordinate first, leading to large up-front costs.
And you still have the problem with my second example.
2) Play tricks with virtual memory tables. Messages now become a
minimum of a page size (unless you really like leaking possibly
sensitive information) and must be allocated specially (but that can
be hidden behind a function). Issues to work out: when the message
is passed, is it mapped out of A? Do A and B now have a copy?
But you still have the problem with my second example.
3) Copy the message. QNX does this (it's a message-based
microkernel). Don't discount it---back in the 90s, I knew the
owners of a software company that wrote commerical X Window servers,
and their fastest X server was on QNX, message passing and all.
You still have an issue with copying a pointer value across, so you
still have the problem of my second example.
And all that which leads me to my point---you *still* have serialization
issues, even if you have zero-copy message passing. You can't get away from
it. And on the down side, you are limiting your messaging to a single box.
Getting back to QNX---because it was pure message-passing, you could run a
command on box A, reference a file on box B, pipe the output to a command on
box C and write the output to box D, all from box E. At the command line.
That looked a lot like any other command you would type. On a Unix system.
All because of message passing (and proper serialization).
-spc
- References:
- Re: Feature request: plain option for gsub, Coroutines
- Re: Feature request: plain option for gsub, Dirk Laurie
- Re: Feature request: plain option for gsub, Axel Kittenberger
- Re: Feature request: plain option for gsub, Coroutines
- Re: Feature request: plain option for gsub, Sean Conner
- Re: Feature request: plain option for gsub, Coroutines
- Re: Feature request: plain option for gsub, Sean Conner
- Re: Feature request: plain option for gsub, Coroutines
- Re: Feature request: plain option for gsub, Sean Conner
- Re: Feature request: plain option for gsub, Coroutines