NAME
    IPC::ScoreBoard - IPC similar to the apache scoreboard

SYNOPSIS
     use IPC::ScoreBoard;

     # create an anonymous scoreboard
     my $sb=SB::anon $nslots, $slotsize, $extra;

     # create a file base board
     my $sb=SB::named $filename, $nslots, $slotsize, $extra;

     # open a file based board
     my ($sb, $nslots, $slotsize, $extra)=SB::open $filename;

     # set/set a value
     SB::set $sb, $slotidx, $elidx, $integer_value;
     $value=SB::get $sb, $slotidx, $elidx;
     @values=SB::get_all $sb, $slotidx;

     # increment/decrement
     SB::incr $sb, $slotidx, $elidx, $integer_value;
     SB::decr $sb, $slotidx, $elidx, $integer_value;

     # sum functions
     $sum=SB::sum $sb, $elidx;
     @sums=SB::sum_all $sb;

     # access extra space
     SB::set_extra $sb, $elidx, $integer_value;
     $value=SB::get_extra $sb, $elidx;
     @values=SB::get_all_extra $sb;

     SB::incr_extra $sb, $elidx, $integer_value;
     SB::decr_extra $sb, $elidx, $integer_value;

     # fetch parameters
     $nslots=SB::nslots $sb;
     $slotsize=SB::slotsize $sb;
     $nextra=SB::nextra $sb;

     # does the compiler provide atomic increment/decrement operations?
     if( SB::have_atomics ) {
       # increment and decrement operations are atomic
     }

INSTALLATION
     perl Makefile.PL
     make
     make test
     make install

DEPENDENCIES
    *   perl 5.8.8

    *   File::Map 0.21

DESCRIPTION
    A scoreboard is a set of integer numbers residing in shared memory. It
    is organized as 2-dimensional array where a line in one of the
    dimensions is called a slot. So, in other words the scoreboard is a set
    of slots and each slot is a set of integer numbers.

    The idea is that in a system of processes or threads of execution each
    process *owns* a slot. A process can change the values in its own slot
    at will but must adhere to read-only access to other slots.

    There is one extra slot at the end of the scoreboard that is allowed to
    be used by every process. However this module does not provide any kind
    of locking to synchronize access.

    The extra slot can differ in size from the other normal slots.

    A scoreboard can be anonymous or it can have a name in the file system
    and hence be accessed by unrelated processes.

  What is that good for?
    Suppose a system of processes that handle certain requests. Now, you
    want to implement a monitor that shows the overall number of requests
    handled so far by the system as a whole.

    One way to do that is to use a shared variable that is incremented each
    time a process has finished a request. But access to this variable has
    to be synchronized by some type of locking. Otherwise 2 or even more
    processes can read the shared variable at the same time. Then each of
    them increments its own value and writes it back. In the end only the
    value written by the last process hits the memory. All other increments
    are lost.

    A lock free way could be to have each process increment its own
    variable. Then the monitor would have to sum up all the variables of the
    processes. But the system is now lock-free.

USAGE
    A scoreboard object is a reference to a scalar. Its methods can be
    invoked in the usual object style, "$sb->get(42,19)", or as subroutines,
    "IPC::ScoreBoard::get $sb, 42, 19". The latter variant is a bit faster
    but involves a lot of typing.

    To mitigate that all functions are exported to the "SB::" namespace if
    the module is included via "use". If it is included via "require"
    nothing is exported. Neither is it if the parameter ":noshortcuts" is
    passed to "use":

     use IPC::ScoreBoard;                # generates shortcuts SB::get & co.
     use IPC::ScoreBoard ();             # no shortcuts
     use IPC::ScoreBoard ':noshortcuts'; # no shortcuts
     require IPC::ScoreBoard;            # no shortcuts

    All data access functions throw an exception if access outside the
    boundaries of the slot or scoreboard is tried.

    The following section shows only the shortcut usage. Remember all
    functions can also be called as

     $object_or_class->functionname(@param);

    or as

     IPC::ScoreBoard::functionname $scoreboard, @param;

  Scoreboard creation
   SB::anon $nslots, $slotsize, $nextra
    creates an anonymous scoreboard with space for $nslots slots and
    $slotsize "IV" values per slot. The extra slot contains $nextra "IV"
    values.

    "anon" returns the scoreboard object.

    In case of an error an exception is thrown.

    Example:

     my $sb=IPC::ScoreBoard->anon($nslots, $slotsize, $nextra);
     my $sb=IPC::ScoreBoard::anon $nslots, $slotsize, $nextra;
     my $sb=SB::anon $nslots, $slotsize, $nextra;

   SB::named $filename, $nslots, $slotsize, $nextra
    similar to "anon" but creates a named scoreboard with the name
    $filename.

    Example:

     my $sb=IPC::ScoreBoard->named($filename, $nslots, $slotsize, $nextra);
     my $sb=IPC::ScoreBoard::named $filename, $nslots, $slotsize, $nextra;
     my $sb=SB::named $filename, $nslots, $slotsize, $nextra;

   SB::open $filename
    similar to "anon" but connects to or opens an existing named scoreboard
    with the name $filename.

    Besides the scoreboard object the scoreboard parameters $nslots,
    $slotsize, $nextra are returned:

    Example:

     my ($sb, $nslots, $slotsize, $extra)=IPC::ScoreBoard->open($filename);
     my ($sb, $nslots, $slotsize, $extra)=IPC::ScoreBoard::open $filename;
     my ($sb, $nslots, $slotsize, $extra)=SB::open $filename;

  Data manipulation
   SB::set $sb, $slotidx, $elidx, $value;
    sets the $elidxth (counting from 0) element in slot number $slotidx
    (also counting from 0) to $value. $value is interpreted as integer.

    The new value is returned.

   SB::get $sb, $slotidx, $elidx;
    reads the value at position $elidx in slot number $slotidx.

   SB::incr $sb, $slotidx, $elidx, $amount;
   SB::decr $sb, $slotidx, $elidx, $amount;
    these 2 functions increment or decrement the value at position $elidx in
    slot number $slotidx. $amount is optional. If ommitted 1 is used.

    If supported by the compiler atomic operations are used to do that. That
    means, even if multiple processes increment or decrement a certain value
    in parallel nothing is lost as described in the DESCRIPTION.

    The new value is returned.

   SB::sum $sb, $elidx;
    sums up the values at a position $elidx over all slots (except for the
    extra one).

   SB::get_all $sb, $slotidx;
    returns a list of all values of slot number $slotidx.

   SB::sum_all $sb;
    returns a list of sums. The equivalent in perl could read:

     @sums=map { SB::sum $sb, $_ } 0..$slotsize;

   SB::set_extra $sb, $elidx, $value;
    sets the value at position $elidx in the extra slot.

   SB::get_extra $sb, $elidx;
    reads the value at position $elidx in the extra slot.

   SB::incr_extra $sb, $elidx, $amount;
   SB::decr_extra $sb, $elidx, $amount;
    these 2 functions increment or decrement the value at position $elidx in
    the extra slot. $amount is optional. If ommitted 1 is used.

    If supported by the compiler atomic operations are used to do that. That
    means, even if multiple processes increment or decrement a certain value
    in parallel nothing is lost as described in the DESCRIPTION.

    The new value is returned.

   SB::get_all_extra $sb;
    returns the list of all values from the extra slot.

  Auxiliary functions
   SB::nslots $sb
    returns the number of slots in the scoreboard

   SB::slotsize $sb
    returns the number of "IV"s in each slot

   SB::nextra $sb
    returns the number of "IV"s in the extra slot

   SB::offset_of $sb, $slotidx, $elidx
    converts a slotnumber and an index within the slot into a byte offset
    from the beginning of the scoreboard.

    If both $slotidx and $elidx are given the offset of the slot element is
    returned. If $elidx is ommitted or undefined $slotidx is taken as an
    element index within the extra slot:

     $sb->offset_of(2, 3);    # 3rd IV in 2nd slot
     SB::offset_of($sb, 3);   # 3rd IV of extra slot

    This allows to store data other than integers.

    Example:

     # store "hugo" in extra[2..4]
     substr($$sb, $sb->offset_of(2), 3*$ivlen, pack( "Z".(3*$ivlen), "hugo"));

     # retrieve "hugo"
     (unpack "x".$sb->offset_of(2)."Z*", $$sb)[0]

    Notes on the example:

    *   Make sure the replacement string has exactly the length as given in
        the 3rd "substr" parameter.

    *   Don't use the lvalue form of "substr". It stores a reference to $$sb
        and hence if $$sb goes out of scope the scoreboard won't be
        unmapped.

        Don't do:

         substr($$sb, $sb->offset_of(2), 3*$ivlen)=pack( "Z".(3*$ivlen), "hugo");

    *   Remember, the "Z" pack format stores always a "NULL" byte at the end
        of the string. So, the example works because "hugo" does not contain
        a "NULL" byte. If you need to store binary data a more sophisticated
        format as "W/a" could be used. But watch out for the maximum length.

   SB::have_atomics
    returns true if "IPC::ScoreBoard" has been compiled with a compiler that
    supports atomic increment/decrement operations.

  EXPORT
    Nothing.

SEE ALSO
    *   <http://www.alexonlinux.com/multithreaded-simple-data-type-access-an
        d-atomic-variables>

        for more information about atomic operations

    *   File::Map

        the underlying memory mapper

AUTHOR
    Torsten Förtsch, <torsten.foertsch@gmx.net>

COPYRIGHT AND LICENSE
    Copyright (C) 2010 by Torsten Förtsch

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself, either Perl version 5.10.0 or, at
    your option, any later version of Perl 5 you may have available.

