LIBCCCO(3)               BSD Library Functions Manual               LIBCCCO(3)

     cchhaannaalltt cchhaanncclloossee cchhaannccrreeaattee cchhaannffrreeee cchhaannnnbbrreeccvv cchhaannnnbbrreeccvvpp cchhaannnnbbsseenndd
     cchhaannnnbbsseennddpp cchhaannooppeenn cchhaannrreeccvv cchhaannrreeccvvpp cchhaannsseenndd cchhaannsseennddpp pprrooccccrreeaattee
     pprroocceexxiitt pprrooccffrreeee pprrooccggeettnnaammee pprroocciinniitt pprroocckkiillll pprrooccrraanndd pprrooccsseettnnaammee
     pprrooccsslleeeepp pprrooccssrraanndd -- parallel programming procedures


     typedef struct Chan     Chan;
     typedef struct Alt      Alt;
     typedef struct Proc     Proc;

     Proc*   proccreate(void (*fn)(void*), void* arg, int stksz);
     void    procfree(Proc* proc);
     int     procinit(Proc* proc, void (*fn)(void*), void* arg, int stksz);
     void    prockill(Proc* proc);
     void    procsetname(const char*, ...);
     char*   procgetname(void);
     void    procsleep(long dur);
     void    procexit(void);
     void    procsrand(long seed);
     long    procrand(void);
     Chan*   chancreate(long nel, long elsz);
     void    chanfree(Chan* chan);
     int     chanopen(Chan* chan);
     void    chanclose(Chan* chan);
     void    chanalt(Alt*);
     int     chanrecv(Chan* c, void* p);
     void*   chanrecvp(Chan* c);
     int     channbrecv(Chan* c, void* p);
     void*   channbrecvp(Chan* c);
     int     chansend(Chan* c, void* p);
     int     chansendp(Chan* c, void* p);
     int     channbsend(Chan* c, void* p);
     int     channbsendp(Chan* c, void* p);

     Libccco is a parallel programming library inspired by several programming
     languages including Limbo, Occam, Alef, and Go, as well as the Plan 9 and
     Inferno operating systems.  Its programming interface similar to that
     provided by Plan 9's libthread.

     Processes have a 1:1 correspondence with system threads.  A _P_r_o_c holds
     the state of a process.  A program's main thread should not call any of
     the procedures prefixed with _p_r_o_c_; they only behave correctly if called
     by a process.  Processes may, in turn, create new processes.

     _P_r_o_c_c_r_e_a_t_e and _p_r_o_c_i_n_i_t create a new process that will run _f_n_(_a_r_g_)_. The
     size of the process's stack is specified by _s_t_k_s_z_; if _s_t_k_s_z is zero, the
     system's default stack size for threads will be used.  _P_r_o_c_c_r_e_a_t_e returns
     a pointer to a newly allocated _P_r_o_c_, so the pointer must be freed later
     by _p_r_o_c_f_r_e_e_. On the other hand, _P_r_o_c structures that were initialized by
     a prior call to _p_r_o_c_i_n_i_t must be destroyed by _p_r_o_c_k_i_l_l_. _P_r_o_c_c_r_e_a_t_e
     returns a null pointer if it encounters an error.  _P_r_o_c_i_n_i_t returns a
     non-zero value if it encounters an error.

     _P_r_o_c_e_x_i_t terminates the calling process; any _P_r_o_c structures associated
     with it will remain intact.

     _P_r_o_c_s_l_e_e_p blocks the calling process for at least _d_u_r seconds.

     _P_r_o_c_s_e_t_n_a_m_e sets the calling process's current name, and _p_r_o_c_g_e_t_n_a_m_e
     returns it.  The pointer returned by _p_r_o_c_g_e_t_n_a_m_e is valid until the next
     call to _p_r_o_c_s_e_t_n_a_m_e_.

     Channels are a means of communication and synchronization between two or
     more processes (including the program's main thread in this special
     case).  A _C_h_a_n holds the state of a channel.

     _C_h_a_n_o_p_e_n opens a channel of _n_e_l elements _e_l_s_z bytes in size, and ini-
     tialises the _C_h_a_n indicated by _c_h_a_n_. If _n_e_l is zero, the channel will be
     unbuffered.  _C_h_a_n_o_p_e_n returns a non-zero value if it encounters an error.
     The channel must later be closed and the _C_h_a_n destroyed by _c_h_a_n_c_l_o_s_e_.

     _C_h_a_n_c_r_e_a_t_e allocates a new _C_h_a_n and opens a channel of _n_e_l elements _e_l_s_z
     bytes in size.  If _n_e_l is zero, the channel will be unbuffered.
     _C_h_a_n_c_r_e_a_t_e returns a null pointer if it encounters an error.  The
     returned pointer must later be freed (and the channel closed) by

   CChhaannnneell ooppeerraattiioonnss
     Once a channel is open, it can be used to transfer data.  Channel opera-
     tions follow a naming scheme that indicates the differences in their be-
     haviour.  The naming scheme is _c_h_a_n_[_n_b_]_s_e_n_d_[_p_] and _c_h_a_n_[_n_b_]_r_e_c_v_[_p_]_, where
     _n_b indicates that the operation is non-blocking, and _p indicates that the
     operation transfers a pointer rather than a value.  Channel operations
     operate on one element in the channel per call.

     A _s_e_n_d operation on a buffered channel proceeds if there is space for an
     element in the buffer, otherwise it blocks until space becomes available.
     If the channel is unbuffered, a _s_e_n_d blocks until a _r_e_c_v occurs in
     another process; likewise, a _r_e_c_v blocks until a _s_e_n_d occurs.  A _s_e_n_d
     operation returns -1 if it encounters an error, 1 otherwise.  A non-
     blocking _s_e_n_d returns 0 if it would have blocked.

     A _r_e_c_v operation on a buffered channel blocks until at least one element
     becomes available in the buffer.  A _r_e_c_v operation returns -1 if it
     encounters an error, 1 otherwise.  A non-blocking _r_e_c_v returns 0 if it
     would have blocked.  Exceptions to this convention are _c_h_a_n_r_e_c_v_p and
     _c_h_a_n_n_b_r_e_c_v_p_, both of which return a null pointer if they encounter an
     error, as will _c_h_a_n_n_b_r_e_c_v_p if it would have blocked.

   RRaannddoomm nnuummbbeerrss
     Because interleaved or simultaneous calls to C's _r_a_n_d and _s_r_a_n_d proce-
     dures by multiple processes result in undefined behaviour, libccco pro-
     vides a pseudo-random number generator (henceforward called a RNG).

     _P_r_o_c_s_r_a_n_d seeds the RNG with _s_e_e_d_. _P_r_o_c_r_a_n_d returns a random integer
     between 0 and 2,147,483,647, provided the RNG has been seeded (otherwise
     the return value is undefined).

     Each process has its own RNG, so calls to _p_r_o_c_r_a_n_d will yield a repro-
     ducible period regardless of whether other processes have called _p_r_o_c_r_a_n_d
     or _p_r_o_c_s_r_a_n_d_. Likewise, calls to _p_r_o_c_s_r_a_n_d will not interfere with other

     The RNG's underlying mechanism is a Mersenne twister (MT19937) populated
     by repeated applications of an equation taken from a Pok~A(C)mon video

     Alting is not yet implemented.

     Unbuffered channels only mimic unbuffered behaviour; they actually use a
     one-element buffer. This keeps the implementation of unbuffered channel
     operations as straightforward as possible.

BSD                             March 25, 2013                             BSD