Hoare, Communicating Sequential Processes, and JCSP

Ulf Wiger <>
Wed Feb 12 11:56:36 CET 2003


On 12 Feb 2003, Luke Gorrie wrote:

>I'd quite like to hear more about where Erlang comes from,
>if you can dig up some juicy details from your memory banks
>:-)
>
>Actually I've recently taken up Erlang compuarchaeology as
>a hobby, after Bjarne Däcker and Göran Båge were nice
>enough to get me some old manuals for EriPascal (a quite
>Erlang-like concurrent extension of Pascal for realtime
>system programming) and its ancestor the APN163
>processor/operating system that had processes and
>very-simple message passing. But following this trail by
>itself doesn't cover all of Erlang influences, since I
>don't see where the Dijkstra/Hoare/??? ingredients really
>came in. So there might be some more groovy stuff to check
>out.. but what?
>
>History wants to know!

OK, I failed to find an external reference to any High-Level
PLEX (Programming Language for EXchange Switches), but did
eventually find an internal link, and will give you a
little code snippet.  (:

HLPLEX is a more modern version of PLEX, the original
programming language for the AXE. PLEX is about as
proprietary as it gets, since it requires special
(proprietary) Ericsson-made processors to function
reasonably well (for several years, work has been underway
to come up with a system based on a commercial CPU that can
rival the home made processors in PLEX execution speed --
the high-end Alphas are the only ones that have come close,
I think...

HLPLEX was designed to overcome some problems seen in PLEX
programming (basically, the event based style of programming
normally seen in UML, concurrent C++, etc.) It has
processes, selective receive with automatic buffering,
something similar to structs, etc. Also cute features like
GOTO etc.

Here's some example code. Behold and enjoy! (:



PROCESS DIGD_object [SAE          (500) --SAE number for DIGD command handling process.
                     INITIAL_SIZE (1)   --Size at inital load.
                     ADDITIONAL   (1)]; --Size at all times after reload and restarts.

<lots of template code snipped here and there>

-----------------------------------
-- 7.3.1.7  PROCESS BODY
-----------------------------------

BEGIN
                   --PROCESS DIGD_obclass CREATED by--
                   --the management function.       --

  OBJECTCLASS DIGD () ON mfs_ep;

                   --EVENTPATH mfs_ep is opened towards DIBSD by --
                   --the management function.                    --
                   --When object class DIGD is created it remains--
                   --in a waitfor state until the management     --
                   --function sends a request to perform an      --
                   --action.(Create, delete, set or get.)        --

  GOTOSTATE waiting_for_a_request;

--------------------------------------------
-- 7.3.1.7.1  State waiting_for_a_request
--------------------------------------------

WAITFOR waiting_for_a_request

--===============================================--
                   --EVENT's   preparebgref
                   --          prepareDIGD
                   --          getbgref
                   --          getDIGDattributes
                   --          getsubscrandbsnb10     --ARE ALLOWED.--
--===============================================--

  EVENT bgref_obcode1.preparebgref
--Command BUBGI
          (bgreference => bg_ptr,
           request     => mf_request,
           extent      => one_or_all) ON mfs_ep;


        SENDEVENT bgref_obcode2.preparebgrefcnf
                    () ON mfs_ep;

        GOTOSTATE waitforbgrefaction;

--------------------
-- prepareDIGD -----
--------------------

  EVENT prepareDIGD (request      => mf_request,
                     digdinstance => dibsd_ptr) on mfs_ep;

    CASE mf_request OF

      (createZ):
                       -->>Find a vacant record<<--

        hlp_statement_counter := resetZ;         -- Reset counters before starting.
        break_counter         := resetZ;

        size_of_file := SIZE (file => BGC_ISDN_SUB_FILE);

        FOR dibsd_ptr := 1 TO size_of_file DO
          IF dibsd_ptr->record_in_use = FALSE THEN --Equivalent to object state
                                                --DIGD_vacant--
            GOTO unused_rec_found;
          END IF;
          IF hlp_statement_counter > max_hlp_statements THEN
            IF break_counter > max_breakZ THEN
              BREAK 5 s;
              break_counter := resetZ;
              hlp_statement_counter := resetZ;
            ELSE
              BREAK 0 s;
              break_counter := break_counter + 1;
              hlp_statement_counter := resetZ;
            END IF;
          END IF;
          hlp_statement_counter := hlp_statement_counter + 1;
        END FOR;

                       -->>.....End of Find a vacant record.....<<--

        SENDEVENT reject(reason    => faultcodeZ,
                         faultcode => fc_storage_shortage_in_DIGD_file) ON mfs_ep;

        TERMINATE;       --Close eventpath to mfs_ep --


USW... This, in its turn led to some code generation of PLEX
code. This generated code would look something like this
(tons snipped of course):

<first, a signal entry point>

ENTER ZZCREATEOBJ WITH
       HLPSIGDATA1,                    ! LOCAL SEIZURE CASE ID !
       HLPSIGDATA2,                    ! INITIATING PROCESS POINTER !
       HLPSIGDATA3,                    ! INITIATING EVENT PATH ID !
       HLPSIGDATA4,                    ! RETURN LABEL !
       HLPSIGDATA5;                    ! INITIATING BLOCK REFERENCE !
     TUTIL161 = HLPSIGDATA5;
     BRANCH ON HLPSIGDATA1
       TO HLPGENLABEL87 IF 1
       ELSE TO FLABORT;

HLPGENLABEL87)
                                       ! ALLOCATION OF IDLE INDIVIDUAL !
     FOR FIRST HLP466RECP FROM HLP466CLASTSEIZED-1 UNTIL 1
       WHERE HLP466RECP:HLP466RECSTATE=0
     GOTO HLPGENLABEL88;

     FOR FIRST HLP466RECP FROM HLP466CPREPNUM-1 UNTIL HLP466CLASTSEIZED
       WHERE HLP466RECP:HLP466RECSTATE=0
     GOTO HLPGENLABEL88;
                                       ! END OF ALLOCATION CODE !
                                       !>>>>>>>>>>>>>>>>>>>>>>>
                                        >>  ZZOBJEXCEPT      >>
                                        >>>>>>>>>>>>>>>>>>>>>>>!
     SEND ZZOBJEXCEPT REFERENCE TUTIL161 WITH
       HLPSIGDATA2,                    ! INITIATING PROCESS POINTER !
       1,                              ! SYSTEM DEFINED EXCEPTION !
       HLPSIGDATA4,                    ! RETURN LABEL !
       2,                              ! CONGESTION CASE !
       3,                              ! USER DEFINED EXCEPTION VALUE !
       COWNREF,                        ! BLOCK REFERENCE OF OBJECT OWNER !
       500;                            ! SAE NUMBER !
     EXIT;

Super-cool, eh?

You can see how the Erlang designers could find lots
of influences within the company, PLEX, which propted the
design of HLPLEX, which influenced EriPascal, which in its
turn influenced OSE/Delta and Erlang, at least as far as the
concurrency programming techniques are concerned.

I'm sure those who were actually involved will correct me if
I've misrepresented things. Personally, I've written exactly
as many lines of *PLEX as I have COBOL, i.e. not a single
one.

/Uffe
-- 
Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson AB, Connectivity and Control Nodes




More information about the erlang-questions mailing list