Hacker News new | past | comments | ask | show | jobs | submit login
Mill: Go-style concurrency in C (millc.org)
155 points by rumcajz on May 1, 2015 | hide | past | favorite | 46 comments



Finally, something that purports to have Go-style concurrency that actually provides the equivalent of select{}!

Lots of things just provide chans, which are fancy thread-safe queues and are fairly easy to implement. Getting select{} right is the tricky (and powerful) part.


Is this specific to what Go offers, or is it just a CSP implementation? I can't tell from a glance at the page, but let's give credit where credit is due if it's coming from Hoare's ideas.


It descends from the external choice operator in CSP, which offers a choice of events to the environment and lets any one of them happen (=~ accepting input on one of a number of channels, but CSP's semantics are a bit different from a typical PL).


it's CSP as extended by golang, i.e. with channels rather than named processes.


Uh...

CSP communication occurs by synchronising events between (possibly unnamed) processes. Each process offers events, and some events are only permitted to occur when every process in a synchronisation group offers them. Channels (which are a concept going back to CSP) are essentially families of events (so the set of events in.x for any x would also be referred to as the channel in).

The main difference between CSP and the languages that are sort of based on it (and this is a difference that predates Go by a long time -- it's visible in occam, for example) is that CSP events aren't directional or procedural like channels, they're just things that sort of happen (so they don't have to be written from one place and read in another -- they can occur with only one process running, or can be used to synchronise between more than two processes, or one process can restrict another by not offering events).

Communicating through named processes would be closer to the actor model than to CSP.


Is this how the term OO got degenerated?

In Communicating Sequential Processes, you only communicate via messages (C) & the processes (P) sequentially (S) run to completion.

Go is not CSP. It is fair to say it was inspired by CSP. Go has a preemptive scheduler, and passing shared memory references is idiomatic and at times unavoidable.


Go-the-language does not have a preemptive scheduler, just guarantees about how various means of synchronization interact.

In fact, Go-the-implementation is only partially preemptive, I believe: in addition to calls into the runtime, calling any function can now be a scheduling event. But if you have a tight loop with no function calls (just arithmetic, perhaps), that goroutine will not yield control. A true preemptive scheduler would be able to take control from that goroutine.


Not so. http://golang.org/doc/go1.2#preemption

[edit: hmm. Possibly I've mis-parsed that.]


I'm pretty sure you parsed that wrong :)


Yes, you're right. But original . re CSP stands :)


Sure. I don't really know much about CSP.


"Is this how the term OO got degenerated?"

I have a theory that there exists no software engineering term that is unambiguously understood by all language communities to be the same thing. If there is one, it won't be for long.

Another recent fun one: "Continuation". Used to mean something very specific in the programming language theory community, it is now nearly indistinguishable from "thread" in many communities.


I agree and it is not good, at all. There is a serious impedance mismatch between industry and academia. The former wants them young and barefoot and the latter hasn't figured out how to convey the (at this point in time) substantial body of work in the field to those that elect for a 4 year (!) CS degree.

Compare to state of affairs in medicine, as an example.


The story is quite interesting if you have not read it. One of my favorite reads.

http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay...



It exists, it's just not always called "select": http://blog.drewolson.org/clojure-go-comparison/#selectandal...


Getting the stacks right is also quite difficult. As is moving the goroutines to different threads to allow other goroutines in the same thread to continue running.


Right, that's one of the main points. The other one is calling invoking C functions as coroutines.


> Finally, something that purports to have Go-style concurrency that actually provides the equivalent of select{}!

About a week ago I released a library to access Go's channels and goroutines (as implemented by gccgo) from C: https://github.com/stefantalpalaru/golib

It has Go's runtime select.


The name clash with the CPU architecture[1] is by accident?

[1] - https://en.wikipedia.org/wiki/Mill_CPU_Architecture


Would this be sort of like libthread on Plan 9/plan9port? But a bit nicer? Anyway, really cool project.

Though I'm kind of bummed that libthread is as obscure as it is...


>> Though I'm kind of bummed that libthread is as obscure as it is...

I am as well. That's the coolest thing about Go imo, Go basically distills down a lot of the coolest stuff from Plan 9, and took it to the 'masses'. Edit; that just my impression, I'm not a Go user.

It would be very useful to have syntactic sugar over coroutines and channels in C. There are quiet a few coroutine libs around, but having it in the language would be compelling.


Edit; that just my impression, I'm not a Go user.

Basically it, I think. Go is the logical evolution of the Limbo language used to write native applications for the Inferno OS, itself evolving from Rob Pike's research with Alef and Newsqueak. The direct heritage spans at least a couple of decades, intermingled with the Plan 9 toolchain and interfaces.


The funcionality is more or less the same, however, the API is much more user-friendly than in plan 9. It's stolen from Go after all.


Anyone else getting a malware warning from the site's icon.ico file? Avast's not letting me access it on mac; could someone post a mirror that would get around the issue?

Alternatively, can someone confirm/disconfirm that the ico's bad news?


Kaspersky just blocked the whole site for me.

EDIT: Looks like it doesn't like http://millc.org/main.css which is innocuous. >>shrugs<< looks like a false positive.


Weird. It's a totally plain CSS file.


You can check the project directly here: https://github.com/sustrik/mill


Yeah I'm getting it too, it doesn't like favicon.ico and main.css.


There's no icon.ico file there afaics.


  $ gcc -o test test.c mill.c
  mill.c:221:13: error: conflicting types for 'wait'
   static void wait(int fd, short events) {
               ^
  In file included from /usr/include/stdlib.h:65:0,
                   from mill.c:33:
  /usr/include/sys/wait.h:248:7: note: previous declaration of 'wait' was here
   pid_t wait(int *) __DARWIN_ALIAS_C(wait);
         ^


Are you on OS X? he says it's only expected to work on linux...


ah thank you


I suppose "choose" was used for multiplexing channel reads to avoid clashing with select(2) (<sys/select.h>) on BSD/POSIX systems..?


Yep. Same way "case" and "default" cannot be used because they clash with C keywords. I was thinking of using "elect" initially, but that looks too much like a typo.


I bet this is an absolute nightmare to step through with gdb


How's it work under the hood?



And computed gotos, which just jumps to a pointer, which is a gcc extension. That's totally crazy, but sort of awesome.


Getcontext/setcontext has always allowed for coroutines in C. This just adds a sugar layer of nonblocking functions that allows a runtime layer to switch between contexts (coroutines), just like Go.


The ucontext stuff is nice but why was it deprecated?

It's generally not a problem on x86, but in my experience for other platforms, it gets messy quickly.

It would be nice if a replacement or a "de-deprecated" was around.


That question has seriously bothered me too. OS threads are not a replacement as they are preemptive. The deprecation was way premature.


makecontext cannot be correctly represented by the C type system.


I'm not very good at C, but from my understanding this library uses longjmp functions which means it's cooperative multithreading rather than preemptive isn't it?


correct


Here's a short toy implementation of the same principle: http://250bpm.com/blog:48




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: