diff options
Diffstat (limited to 'libcult/examples')
23 files changed, 1411 insertions, 0 deletions
diff --git a/libcult/examples/cli/cli.cxx b/libcult/examples/cli/cli.cxx new file mode 100644 index 0000000..922a23d --- /dev/null +++ b/libcult/examples/cli/cli.cxx @@ -0,0 +1,65 @@ +// file : examples/cli/cli.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/types.hxx> + +#include <cult/cli/options.hxx> +#include <cult/cli/options-spec.hxx> +#include <cult/cli/options-parser.hxx> + +#include <iostream> + +using std::cerr; +using std::endl; + +using namespace Cult; + +namespace +{ + extern Char const help[] = "help"; + extern Char const version[] = "version"; + extern Char const outdir[] = "outdir"; +} + +typedef +CLI::Options<help, Boolean, + version, Boolean, + outdir, String> +Options; + +Int +main (Int argc, Char* argv[]) +{ + try + { + Options options (CLI::parse<Options> (argc, argv)); + + if (options.value<help> ()) + { + cerr << "usage: " << argv[0] << " [--help] [--version] [--outdir <dir>]" + << endl; + return 0; + } + + if (options.value<version> ()) + { + cerr << argv[0] << " 1.2.3" << endl; + return 0; + } + + if (String dir = options.value<outdir> ()) + { + cerr << "outdir: " << dir << endl; + } + } + catch (CLI::UnexpectedOption const& e) + { + cerr << "unexpected option " << e.option () <<endl; + } + catch (CLI::OptionFormat const& e) + { + cerr << "bad format for " << e.option () << endl; + } +} diff --git a/libcult/examples/cli/makefile b/libcult/examples/cli/makefile new file mode 100644 index 0000000..004f135 --- /dev/null +++ b/libcult/examples/cli/makefile @@ -0,0 +1,48 @@ +# file : examples/cli/makefile +# author : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make + +cxx_tun := cli.cxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +cult.l := $(out_root)/cult/cult.l +cult.l.cpp-options := $(out_root)/cult/cult.l.cpp-options + +cli := $(out_base)/cli +clean := $(out_base)/.clean + + +# Build. +# +$(cli): $(cxx_obj) $(cult.l) + +$(cxx_obj) $(cxx_od): $(cult.l.cpp-options) + +$(call include-dep,$(cxx_od)) + + +# Convenience alias for default target. +# +$(out_base)/: $(cli) + + +# Clean. +# +$(clean): $(cli).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) + +# Dependencies. +# +$(call import,$(src_root)/cult/makefile) diff --git a/libcult/examples/dr/xdr/makefile b/libcult/examples/dr/xdr/makefile new file mode 100644 index 0000000..6a4fa8f --- /dev/null +++ b/libcult/examples/dr/xdr/makefile @@ -0,0 +1,49 @@ +# file : examples/dr/xdr/makefile +# author : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +cxx_tun := xdr.cxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +cult.l := $(out_root)/cult/cult.l +cult.l.cpp-options := $(out_root)/cult/cult.l.cpp-options + +xdr := $(out_base)/xdr +clean := $(out_base)/.clean + + +# Build. +# +$(xdr): $(cxx_obj) $(cult.l) + +$(cxx_obj) $(cxx_od): $(cult.l.cpp-options) + +$(call include-dep,$(cxx_od)) + + +# Convenience alias for default target. +# +$(out_base)/: $(xdr) + + +# Clean. +# +$(clean): $(xdr).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) + + +# Dependencies. +# +$(call import,$(src_root)/cult/makefile) diff --git a/libcult/examples/dr/xdr/xdr.cxx b/libcult/examples/dr/xdr/xdr.cxx new file mode 100644 index 0000000..38e948d --- /dev/null +++ b/libcult/examples/dr/xdr/xdr.cxx @@ -0,0 +1,87 @@ +// file : examples/dr/xdr/xdr.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/types.hxx> + +#include <cult/dr/xdr/input-stream.hxx> +#include <cult/dr/xdr/output-stream.hxx> + +#include <iostream> + +using namespace Cult; +using namespace DR::XDR; + +using std::cerr; +using std::endl; + +Int +main () +{ + try + { + OutputStream o (8); + + o << true << false; + + UnsignedInt8 a8 (0xDE); + UnsignedInt16 a16 (0xDEAD); + UnsignedInt32 a32 (0xDEADBEEF); + UnsignedInt64 a64 (0xDEADBEEFDEADBEEFULL); + + o << a8 << a16 << a32 << a64; + + Int8 b8 (-8); + Int16 b16 (-16); + Int32 b32 (-32); + Int64 b64 (-64); + + o << b8 << b16 << b32 << b64; + + String s ("reasonably loooooooooooooong string with some junk in it"); + + o << s; + + InputStream i (o.buffer ()); + + Boolean t, f; + String s1; + + i >> t >> f; + i >> a8 >> a16 >> a32 >> a64; + i >> b8 >> b16 >> b32 >> b64; + i >> s1; + + if (!t + || f + || a8 != 0xDE + || a16 != 0xDEAD + || a32 != 0xDEADBEEF + || a64 != 0xDEADBEEFDEADBEEFULL + || b8 != -8 + || b16 != -16 + || b32 != -32 + || b64 != -64 + || s1 != s) return 1; + + try + { + i >> t; + } + catch (Extraction const&) + { + return 0; + } + } + catch (Insertion const&) + { + cerr << "insertion" << endl; + } + catch (Extraction const&) + { + cerr << "extraction" << endl; + } + + return 1; +} diff --git a/libcult/examples/makefile b/libcult/examples/makefile new file mode 100644 index 0000000..d264910 --- /dev/null +++ b/libcult/examples/makefile @@ -0,0 +1,36 @@ +# file : examples/makefile +# author : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make +include $(scf_root)/configuration.make + +default := $(out_base)/ +clean := $(out_base)/.clean + +examples := $(out_base)/cli \ + $(out_base)/mm/shptr \ + $(out_base)/mm/transfer \ + $(out_base)/trace + +ifeq ($(cult_threads),y) +examples += $(out_base)/sched/main \ + $(out_base)/sched/cancel +endif + + +ifeq ($(cult_network),y) +examples += $(out_base)/os/net/ipv4/datagram \ + $(out_base)/os/net/ipv4/multicast +endif + +ifeq ($(cult_dr),y) +examples += $(out_base)/dr/xdr +endif + + +$(default): $(addsuffix /,$(examples)) +$(clean): $(addsuffix /.clean,$(examples)) + +$(foreach e,$(subst $(out_base),$(src_base),$(examples)),$(call import,$e/makefile)) diff --git a/libcult/examples/mm/shptr/makefile b/libcult/examples/mm/shptr/makefile new file mode 100644 index 0000000..2bf1598 --- /dev/null +++ b/libcult/examples/mm/shptr/makefile @@ -0,0 +1,48 @@ +# file : examples/mm/shptr/makefile +# author : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +cxx_tun := shptr.cxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +cult.l := $(out_root)/cult/cult.l +cult.l.cpp-options := $(out_root)/cult/cult.l.cpp-options + +shptr := $(out_base)/shptr +clean := $(out_base)/.clean + + +# Build. +# +$(shptr): $(cxx_obj) $(cult.l) + +$(cxx_obj) $(cxx_od): $(cult.l.cpp-options) + +$(call include-dep,$(cxx_od)) + + +# Convenience alias for default target. +# +$(out_base)/: $(shptr) + + +# Clean. +# +$(clean): $(shptr).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) + +# Dependencies. +# +$(call import,$(src_root)/cult/makefile) diff --git a/libcult/examples/mm/shptr/shptr.cxx b/libcult/examples/mm/shptr/shptr.cxx new file mode 100644 index 0000000..cb026d4 --- /dev/null +++ b/libcult/examples/mm/shptr/shptr.cxx @@ -0,0 +1,73 @@ +// file : examples/mm/shptr/shptr.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/mm/shptr.hxx> +#include <cult/mm/new.hxx> // MM::locate +#include <cult/mm/counter.hxx> // MM::inc_ref + +#include <iostream> + +using std::cerr; +using std::endl; + +using namespace Cult; +using namespace MM; + +struct Foo +{ + virtual ~Foo () {} + char c; +}; + +struct Bar: virtual Foo {char c;}; + +struct Baz: virtual Foo {char c;}; + +struct Fox: Bar, Baz {}; + + +struct A +{ + char c[8]; +}; + +struct B +{ + char c[8]; +}; + +struct C : A, B +{ + char c[8]; +}; + +int +main () +{ + { + Baz* bp (new Fox); + Foo* fp (bp); + + Counter* cp (locate (fp, *counted)); + + inc_ref (bp); + + cp->dec_ref (); + + if (cp->dec_ref ()) cerr << "good: destroying" << endl; + else cerr << "bad: leaking" << endl; + + delete bp; + } + + { + Shptr<Fox> pfox (new Fox); + Shptr<Bar> pbar (pfox); + + Shptr<Foo> pfoo; + + pfoo = pbar; + } +} diff --git a/libcult/examples/mm/transfer/makefile b/libcult/examples/mm/transfer/makefile new file mode 100644 index 0000000..3380f10 --- /dev/null +++ b/libcult/examples/mm/transfer/makefile @@ -0,0 +1,48 @@ +# file : examples/mm/transfer/makefile +# author : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +cxx_tun := transfer.cxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +cult.l := $(out_root)/cult/cult.l +cult.l.cpp-options := $(out_root)/cult/cult.l.cpp-options + +transfer := $(out_base)/transfer +clean := $(out_base)/.clean + + +# Build. +# +$(transfer): $(cxx_obj) $(cult.l) + +$(cxx_obj) $(cxx_od): $(cult.l.cpp-options) + +$(call include-dep,$(cxx_od)) + + +# Convenience alias for default target. +# +$(out_base)/: $(transfer) + + +# Clean. +# +$(clean): $(transfer).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) + +# Dependencies. +# +$(call import,$(src_root)/cult/makefile) diff --git a/libcult/examples/mm/transfer/transfer.cxx b/libcult/examples/mm/transfer/transfer.cxx new file mode 100644 index 0000000..81014d0 --- /dev/null +++ b/libcult/examples/mm/transfer/transfer.cxx @@ -0,0 +1,117 @@ +// file : examples/mm/transfer/transfer.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/mm/evptr.hxx> + +#include <iostream> + +using std::cerr; +using std::endl; + +using namespace Cult; + +unsigned long count = 0; +unsigned long clone_count = 0; + +struct Type +{ + Type () + { + ++count; + } + + ~Type () + { + --count; + } + + Evptr<Type> + clone () const + { + ++clone_count; + return Evptr<Type> (new Type); + } + + Void + f () const + { + Int i = i_; + ++i; + } + + Int i_; +}; + + +Evptr<Type> +source () +{ + return Evptr<Type> (new Type); +} + +Void +sink (Evptr<Type> a, Boolean r = true) +{ + if (r) + { + sink (a, false); + } + else + { + Evptr<Type> b (a); + + cerr << "\tshare count: " << b.count () << endl; + + // Any of these will trigger cloning. + // + b->f (); + } +} + +Int +main () +{ + // case 1 + // + { + cerr << "sink (new type)" << endl; + + clone_count = 0; + sink (new Type); + + cerr << "\tclone count: " << clone_count << endl + << endl; + } + + // case 2 + // + { + cerr << "sink (source ())" << endl; + + clone_count = 0; + sink (source ()); + + cerr << "\tclone count: " << clone_count << endl + << endl; + } + + + // case 3 + // + { + cerr << "sink (p)" << endl; + + clone_count = 0; + + Evptr<Type> p (new Type); + sink (p); + + cerr << "\tclone count: " << clone_count << endl + << endl; + } + + + cerr << "balance: " << count << endl; +} diff --git a/libcult/examples/os/net/ipv4/datagram/client.cxx b/libcult/examples/os/net/ipv4/datagram/client.cxx new file mode 100644 index 0000000..863fc25 --- /dev/null +++ b/libcult/examples/os/net/ipv4/datagram/client.cxx @@ -0,0 +1,66 @@ +// file : examples/os/net/ipv4/datagram/client.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/types.hxx> + +#include <cult/os/net/ipv4/address.hxx> +#include <cult/os/net/ipv4/datagram-socket.hxx> + +#include <iostream> +#include <unistd.h> // usleep + +#include "protocol.hxx" + +using std::cerr; +using std::endl; + +using namespace Cult; +using namespace OS::Net::IPv4; + +class Args {}; + +Int +main (Int argc, Char* argv[]) +{ + try + { + if (argc < 2) + throw Args (); + + Address addr (argv[1], 10000); + + DatagramSocket socket; + + Message msg; + msg.sn = 0; + + cerr << "message size : " << sizeof (msg) << " bytes" << endl; + cerr << "send buffer : " << socket.send_buffer_size () << " bytes" << endl; + + for (Index i = 0; i < payload_size; i++) + { + msg.payload[i] = i; + } + + for (; msg.sn < message_count; msg.sn++) + { + socket.send (&msg, sizeof (msg), addr); + + // ::usleep (10); + } + + return 0; + } + catch (OS::Exception const& e) + { + cerr << "errno: " << strerror (e.code ()) << endl; + } + catch (Args const&) + { + cerr << "usage: client <IPv4 address>" << endl; + } + + return 1; +} diff --git a/libcult/examples/os/net/ipv4/datagram/makefile b/libcult/examples/os/net/ipv4/datagram/makefile new file mode 100644 index 0000000..2dc8e1b --- /dev/null +++ b/libcult/examples/os/net/ipv4/datagram/makefile @@ -0,0 +1,55 @@ +# file : examples/os/net/ipv4/datagram/makefile +# author : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make + +client_cxx_tun := client.cxx +server_cxx_tun := server.cxx + +client_cxx_obj := $(addprefix $(out_base)/,$(client_cxx_tun:.cxx=.o)) +server_cxx_obj := $(addprefix $(out_base)/,$(server_cxx_tun:.cxx=.o)) + +cxx_obj := $(client_cxx_obj) $(server_cxx_obj) +cxx_od := $(cxx_obj:.o=.o.d) + +cult.l := $(out_root)/cult/cult.l +cult.l.cpp-options := $(out_root)/cult/cult.l.cpp-options + +client := $(out_base)/client +server := $(out_base)/server +clean := $(out_base)/.clean + +# Convenience alias for default target. +# +$(out_base)/: $(client) $(server) + +# Build. +# + +$(client): $(client_cxx_obj) $(cult.l) +$(server): $(server_cxx_obj) $(cult.l) + +$(cxx_obj) $(cxx_od): $(cult.l.cpp-options) + +$(call include-dep,$(cxx_od)) + + +# Clean. +# +$(clean): $(client).o.clean \ + $(server).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) + +# Dependencies. +# +$(call import,$(src_root)/cult/makefile) diff --git a/libcult/examples/os/net/ipv4/datagram/protocol.hxx b/libcult/examples/os/net/ipv4/datagram/protocol.hxx new file mode 100644 index 0000000..0f418e8 --- /dev/null +++ b/libcult/examples/os/net/ipv4/datagram/protocol.hxx @@ -0,0 +1,20 @@ +// file : examples/os/net/ipv4/datagram/protocol.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef PROTOCOL_HXX +#define PROTOCOL_HXX + +#include <cult/types.hxx> + +Cult::UnsignedShort const payload_size = 256; +Cult::UnsignedLong const message_count = 100; + +struct Message +{ + Cult::UnsignedLong sn; + Cult::UnsignedShort payload[payload_size]; +}; + +#endif // PROTOCOL_HXX diff --git a/libcult/examples/os/net/ipv4/datagram/server.cxx b/libcult/examples/os/net/ipv4/datagram/server.cxx new file mode 100644 index 0000000..e788056 --- /dev/null +++ b/libcult/examples/os/net/ipv4/datagram/server.cxx @@ -0,0 +1,123 @@ +// file : examples/os/net/ipv4/datagram/server.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/types.hxx> +#include <cult/containers/vector.hxx> + +#include <cult/os/net/ipv4/address.hxx> +#include <cult/os/net/ipv4/datagram-socket.hxx> + +#include <iostream> +#include <cstring> // memcmp + +#include "protocol.hxx" + +using std::cerr; +using std::endl; + +using namespace Cult; +using namespace OS::Net::IPv4; + +typedef Containers::Vector<Boolean> StatusList; + +Int +main () +{ + try + { + Address addr (INADDR_ANY, 10000); + + DatagramSocket socket (addr); + + Message expected_msg; + expected_msg.sn = 0; + + for (UnsignedShort i = 0; i < payload_size; ++i) + { + expected_msg.payload[i] = i; + } + + StatusList received (message_count, 0); + StatusList damaged (message_count, 0); + StatusList duplicate (message_count, 0); + + Message msg; + + while (true) + { + socket.recv (&msg, sizeof (msg)); + + if (received[msg.sn]) + { + duplicate[msg.sn] = true; + } + else + { + received[msg.sn] = true; + + if (std::memcmp (expected_msg.payload, msg.payload, payload_size) != 0) + { + damaged[msg.sn] = true; + } + } + + if (msg.sn + 1 == message_count) break; + } + + UnsignedLong lost_count (0), damaged_count (0), duplicate_count (0); + + for (StatusList::Iterator i (received.begin ()), end (received.end ()); + i != end; + ++i) + if (!*i) ++lost_count; + + for (StatusList::Iterator i (damaged.begin ()), end (damaged.end ()); + i != end; + ++i) + if (*i) ++damaged_count; + + for (StatusList::Iterator i (duplicate.begin ()), end (duplicate.end ()); + i != end; + ++i) + if (*i) ++duplicate_count; + + cerr << "lost : " << lost_count << endl + << "damaged : " << damaged_count << endl + << "duplicate : " << duplicate_count << endl << endl; + + if (lost_count != 0) + { + cerr << "lost message dump:" << endl; + + UnsignedLong total = 0; + + for (StatusList::Iterator + begin (received.begin ()), i (begin), end (received.end ()); + i != end;) + { + if (!*i) + { + UnsignedLong count = 1; + + for (StatusList::Iterator j = i + 1; j < end && !*j; j++, count++) ; + + cerr << '\t' << i - begin << " : " << count << endl; + + i += count; + total += count; + } + else + ++i; + } + + if (total != lost_count) + cerr << "trouble" << endl; + } + } + catch (OS::Exception const& e) + { + cerr << "errno: " << e.code () << endl; + } +} diff --git a/libcult/examples/os/net/ipv4/multicast/client.cxx b/libcult/examples/os/net/ipv4/multicast/client.cxx new file mode 100644 index 0000000..863fc25 --- /dev/null +++ b/libcult/examples/os/net/ipv4/multicast/client.cxx @@ -0,0 +1,66 @@ +// file : examples/os/net/ipv4/datagram/client.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/types.hxx> + +#include <cult/os/net/ipv4/address.hxx> +#include <cult/os/net/ipv4/datagram-socket.hxx> + +#include <iostream> +#include <unistd.h> // usleep + +#include "protocol.hxx" + +using std::cerr; +using std::endl; + +using namespace Cult; +using namespace OS::Net::IPv4; + +class Args {}; + +Int +main (Int argc, Char* argv[]) +{ + try + { + if (argc < 2) + throw Args (); + + Address addr (argv[1], 10000); + + DatagramSocket socket; + + Message msg; + msg.sn = 0; + + cerr << "message size : " << sizeof (msg) << " bytes" << endl; + cerr << "send buffer : " << socket.send_buffer_size () << " bytes" << endl; + + for (Index i = 0; i < payload_size; i++) + { + msg.payload[i] = i; + } + + for (; msg.sn < message_count; msg.sn++) + { + socket.send (&msg, sizeof (msg), addr); + + // ::usleep (10); + } + + return 0; + } + catch (OS::Exception const& e) + { + cerr << "errno: " << strerror (e.code ()) << endl; + } + catch (Args const&) + { + cerr << "usage: client <IPv4 address>" << endl; + } + + return 1; +} diff --git a/libcult/examples/os/net/ipv4/multicast/makefile b/libcult/examples/os/net/ipv4/multicast/makefile new file mode 100644 index 0000000..cb35bf6 --- /dev/null +++ b/libcult/examples/os/net/ipv4/multicast/makefile @@ -0,0 +1,55 @@ +# file : examples/os/net/ipv4/multicast/makefile +# author : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make + +client_cxx_tun := client.cxx +server_cxx_tun := server.cxx + +client_cxx_obj := $(addprefix $(out_base)/,$(client_cxx_tun:.cxx=.o)) +server_cxx_obj := $(addprefix $(out_base)/,$(server_cxx_tun:.cxx=.o)) + +cxx_obj := $(client_cxx_obj) $(server_cxx_obj) +cxx_od := $(cxx_obj:.o=.o.d) + +cult.l := $(out_root)/cult/cult.l +cult.l.cpp-options := $(out_root)/cult/cult.l.cpp-options + +client := $(out_base)/client +server := $(out_base)/server +clean := $(out_base)/.clean + +# Convenience alias for default target. +# +$(out_base)/: $(client) $(server) + +# Build. +# + +$(client): $(client_cxx_obj) $(cult.l) +$(server): $(server_cxx_obj) $(cult.l) + +$(cxx_obj) $(cxx_od): $(cult.l.cpp-options) + +$(call include-dep,$(cxx_od)) + + +# Clean. +# +$(clean): $(client).o.clean \ + $(server).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) + +# Dependencies. +# +$(call import,$(src_root)/cult/makefile) diff --git a/libcult/examples/os/net/ipv4/multicast/protocol.hxx b/libcult/examples/os/net/ipv4/multicast/protocol.hxx new file mode 100644 index 0000000..a4057de --- /dev/null +++ b/libcult/examples/os/net/ipv4/multicast/protocol.hxx @@ -0,0 +1,20 @@ +// file : examples/os/net/ipv4/multicast/protocol.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef PROTOCOL_HXX +#define PROTOCOL_HXX + +#include <cult/types.hxx> + +Cult::UnsignedShort const payload_size = 256; +Cult::UnsignedLong const message_count = 100; + +struct Message +{ + Cult::UnsignedLong sn; + Cult::UnsignedShort payload[payload_size]; +}; + +#endif // PROTOCOL_HXX diff --git a/libcult/examples/os/net/ipv4/multicast/server.cxx b/libcult/examples/os/net/ipv4/multicast/server.cxx new file mode 100644 index 0000000..5d8fe99 --- /dev/null +++ b/libcult/examples/os/net/ipv4/multicast/server.cxx @@ -0,0 +1,134 @@ +// file : examples/os/net/ipv4/datagram/server.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/types.hxx> +#include <cult/containers/vector.hxx> + +#include <cult/os/net/ipv4/address.hxx> +#include <cult/os/net/ipv4/multicast-socket.hxx> + +#include <iostream> +#include <cstring> // memcmp + +#include "protocol.hxx" + +using std::cerr; +using std::endl; + +using namespace Cult; +using namespace OS::Net::IPv4; + +typedef Containers::Vector<Boolean> StatusList; + +class Args {}; + +Int +main (Int argc, Char* argv[]) +{ + try + { + if (argc < 2) + throw Args (); + + Address addr (argv[1], 10000); + + MulticastSocket socket; + + socket.join (addr); + + Message expected_msg; + expected_msg.sn = 0; + + for (UnsignedShort i = 0; i < payload_size; ++i) + { + expected_msg.payload[i] = i; + } + + StatusList received (message_count, 0); + StatusList damaged (message_count, 0); + StatusList duplicate (message_count, 0); + + Message msg; + + while (true) + { + socket.recv (&msg, sizeof (msg)); + + if (received[msg.sn]) + { + duplicate[msg.sn] = true; + } + else + { + received[msg.sn] = true; + + if (std::memcmp (expected_msg.payload, msg.payload, payload_size) != 0) + { + damaged[msg.sn] = true; + } + } + + if (msg.sn + 1 == message_count) break; + } + + UnsignedLong lost_count (0), damaged_count (0), duplicate_count (0); + + for (StatusList::Iterator i (received.begin ()), end (received.end ()); + i != end; + ++i) + if (!*i) ++lost_count; + + for (StatusList::Iterator i (damaged.begin ()), end (damaged.end ()); + i != end; + ++i) + if (*i) ++damaged_count; + + for (StatusList::Iterator i (duplicate.begin ()), end (duplicate.end ()); + i != end; + ++i) + if (*i) ++duplicate_count; + + cerr << "lost : " << lost_count << endl + << "damaged : " << damaged_count << endl + << "duplicate : " << duplicate_count << endl << endl; + + if (lost_count != 0) + { + cerr << "lost message dump:" << endl; + + UnsignedLong total = 0; + + for (StatusList::Iterator + begin (received.begin ()), i (begin), end (received.end ()); + i != end;) + { + if (!*i) + { + UnsignedLong count = 1; + + for (StatusList::Iterator j = i + 1; j < end && !*j; j++, count++) ; + + cerr << '\t' << i - begin << " : " << count << endl; + + i += count; + total += count; + } + else + ++i; + } + + if (total != lost_count) + cerr << "trouble" << endl; + } + } + catch (OS::Exception const& e) + { + cerr << "errno: " << e.code () << endl; + } + catch (Args const&) + { + cerr << "usage: client <IPv4 address>" << endl; + } +} diff --git a/libcult/examples/sched/cancel/cancel.cxx b/libcult/examples/sched/cancel/cancel.cxx new file mode 100644 index 0000000..ee71449 --- /dev/null +++ b/libcult/examples/sched/cancel/cancel.cxx @@ -0,0 +1,63 @@ +// file : examples/sched/cancel/cancel.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/types.hxx> + +#include <cult/mm/shptr.hxx> + +#include <cult/sched/lock.hxx> +#include <cult/sched/mutex.hxx> +#include <cult/sched/thread.hxx> +#include <cult/sched/condition.hxx> + + +#include <iostream> +#include <unistd.h> // sleep + +using std::cerr; +using std::endl; + +using namespace Cult; +using namespace Sched; + +Void* +cond_wait_thread_proc (Void*) +{ + try + { + Mutex mutex; + Condition cond (mutex); + + Lock lock (mutex); + + cond.wait (); + } + /* + catch (std::thread_canceled const& e) + { + cerr << "caught thread_canceled" << endl; + throw; + } + */ + catch (...) + { + cerr << "presumably caught thread_canceled" << endl; + throw; + } + + return 0; +} + + +Int +main () +{ + Shptr<Thread> thread (new Thread (cond_wait_thread_proc)); + + sleep (1); + + thread->cancel (); + thread->join (); +} diff --git a/libcult/examples/sched/cancel/makefile b/libcult/examples/sched/cancel/makefile new file mode 100644 index 0000000..38a96bd --- /dev/null +++ b/libcult/examples/sched/cancel/makefile @@ -0,0 +1,48 @@ +# file : examples/sched/cancel/makefile +# author : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +cxx_tun := cancel.cxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +cult.l := $(out_root)/cult/cult.l +cult.l.cpp-options := $(out_root)/cult/cult.l.cpp-options + +cancel := $(out_base)/cancel +clean := $(out_base)/.clean + + +# Build. +# +$(cancel): $(cxx_obj) $(cult.l) + +$(cxx_obj) $(cxx_od): $(cult.l.cpp-options) + +$(call include-dep,$(cxx_od)) + + +# Convenience alias for default target. +# +$(out_base)/: $(cancel) + + +# clean +# +$(clean): $(cancel).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) + +# Dependencies. +# +$(call import,$(src_root)/cult/makefile) diff --git a/libcult/examples/sched/main/main.cxx b/libcult/examples/sched/main/main.cxx new file mode 100644 index 0000000..58cc2cc --- /dev/null +++ b/libcult/examples/sched/main/main.cxx @@ -0,0 +1,43 @@ +// file : examples/sched/main/main.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/types.hxx> + +#include <cult/mm/shptr.hxx> +#include <cult/sched/thread.hxx> + +#include <iostream> +#include <unistd.h> // sleep + +using namespace Cult; +using namespace Sched; + +using std::cerr; +using std::endl; + +Void* +thread_func (Void*) +{ + cerr << "second thread: going to sleep for a few seconds" << endl; + + sleep (2); + + cerr << "second thread: woke up, now exiting" << endl; + + return 0; +} + + +Int +main () +{ + Shptr<Thread> self (new Thread); + + Shptr<Thread> other (new Thread (thread_func)); + + cerr << "initial thread: exiting" << endl; + + Thread::exit (0); +} diff --git a/libcult/examples/sched/main/makefile b/libcult/examples/sched/main/makefile new file mode 100644 index 0000000..945237f --- /dev/null +++ b/libcult/examples/sched/main/makefile @@ -0,0 +1,48 @@ +# file : examples/sched/main/makefile +# author : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +cxx_tun := main.cxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +cult.l := $(out_root)/cult/cult.l +cult.l.cpp-options := $(out_root)/cult/cult.l.cpp-options + +main := $(out_base)/main +clean := $(out_base)/.clean + + +# Build. +# +$(main): $(cxx_obj) $(cult.l) + +$(cxx_obj) $(cxx_od): $(cult.l.cpp-options) + +$(call include-dep,$(cxx_od)) + + +# Convenience alias for default target. +# +$(out_base)/: $(main) + + +# Clean. +# +$(clean): $(main).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) + +# Dependencies. +# +$(call import,$(src_root)/cult/makefile) diff --git a/libcult/examples/trace/makefile b/libcult/examples/trace/makefile new file mode 100644 index 0000000..57e2b7b --- /dev/null +++ b/libcult/examples/trace/makefile @@ -0,0 +1,48 @@ +# file : examples/trace/makefile +# author : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make + +cxx_tun := trace.cxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +cult.l := $(out_root)/cult/cult.l +cult.l.cpp-options := $(out_root)/cult/cult.l.cpp-options + +trace := $(out_base)/trace +clean := $(out_base)/.clean + + +# Build. +# +$(trace): $(cxx_obj) $(cult.l) + +$(cxx_obj) $(cxx_od): $(cult.l.cpp-options) + +$(call include-dep,$(cxx_od)) + + +# Convenience alias for default target. +# +$(out_base)/: $(trace) + + +# Clean. +# +$(clean): $(trace).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) + +# Dependencies. +# +$(call import,$(src_root)/cult/makefile) diff --git a/libcult/examples/trace/trace.cxx b/libcult/examples/trace/trace.cxx new file mode 100644 index 0000000..e2a09d4 --- /dev/null +++ b/libcult/examples/trace/trace.cxx @@ -0,0 +1,51 @@ +// file : examples/trace/trace.cxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <cult/types.hxx> + +#include <cult/trace/log.hxx> +#include <cult/trace/record.hxx> +#include <cult/trace/stream.hxx> + +#include <ostream> + +using namespace Cult; + +struct Foo {}; + +std::ostream& +operator<< (std::ostream& o, Foo const&) +{ + return o << "::Foo"; +} + +Trace::Stream tout ("Examples::Trace", 4); + +Int +main () +{ + using Trace::Record; + + Trace::Log::instance ().level (9); + + Record a ("main", 2); + a << "notationally burdensome"; + tout << a; + + Record b ("main", 2); + tout << (b << "a bit better, but still burdensome"); + + tout << (Record ("main", 2) << "this is" + << " somewhat" + << " twisted but nice to be able to"); + + tout << "concise, using default level"; + + tout << 9 << "concise, using custom level"; + + Foo f; + + tout << 3 << f << " " << 5; +} |