Commit Graph

101 Commits

Author SHA1 Message Date
Avi Kivity
dacf81745e core: add circular_buffer
Since we have lots of queues, we need an efficient queue structure,
esp. for moveable types.  libstdc++'s std::deque is quite hairy,
and boost's circular_buffer_space_optimized uses assignments instead of
constructors, which are both slower and less available than constructors.

This patch implements a growable circular buffer for these needs.
2014-10-02 14:32:32 +03:00
Avi Kivity
42db87a8c2 core: add helper functions for "transferring" objects
Here, transferring is defined as moving an object to a new location
(either via a move or copy constructor) and destroying the source.  This
is useful when implementing containers.
2014-10-02 14:28:14 +03:00
Tomasz Grabiec
6fa3212888 core: fix missing error propagation when intermediate future is involved
Test case (added in the next patch):

    promise<> p1;
    promise<> p2;

    auto f = p1.get_future().then([f = std::move(p2.get_future())] () mutable {
        return std::move(f); // this future will fail
    }).then([] {
        // never reached, that's ok
    });

    p1.set_value();
    p2.set_exception(std::runtime_error("boom"));

    // f should get resolved eventually with error, but was not
2014-10-01 13:45:28 +02:00
Tomasz Grabiec
d9bf08c1b3 core: introduce future::finally()
The callback passed to it will be executed when future gets resolved,
successfully or not. The returned future will mimic the state of the
target future.
2014-10-01 13:45:28 +02:00
Tomasz Grabiec
fcb55c1f04 core: introduce future::forward_to()
It causes that when future is resolved, the target promise will be
resolved too with the same state.
2014-10-01 13:45:28 +02:00
Tomasz Grabiec
07d6df11a8 core: introduce make_exception_future() which works with exception objects 2014-10-01 13:45:25 +02:00
Tomasz Grabiec
125a696d6c core: introduce promise::set_exception() which works with exception objects 2014-10-01 13:45:22 +02:00
Tomasz Grabiec
061bccd084 core: timer: add support for periodicy
Simplifies the client side which uses periodic timers.
2014-10-01 13:21:10 +02:00
Tomasz Grabiec
48a86b7073 core: make timer callbacks synchronous with state changes
It allows for simpler client code because the client can assume that
when cancel() returns the callback will not run and thus there's no
need to handle the race between timer teardown and execution of the
callback.
2014-10-01 13:21:10 +02:00
Tomasz Grabiec
eeea3640f2 core: make future::rescue() return a future<>
This will allow to compose rescue() just like then().
2014-10-01 13:21:09 +02:00
Tomasz Grabiec
5f2e06beda core: make future's result obtainable via future::rescue()
This will allow the user to have one handler for both success and
failure. This simplifies client code a bit when both paths need to
work on the same object. Having to split the function into two
callbacks, one of which is passed to then() and the other to rescue()
on a resulting promise, would make it necessary to wrap the object in
a shared_ptr, which is suboptimal.
2014-10-01 13:21:02 +02:00
Avi Kivity
4f5059fa75 app template: support configuration files
~/.config/seastar/seastar.conf
2014-09-30 21:29:53 +03:00
Avi Kivity
4f83aab5f0 ragel: remove unused variable 2014-09-30 10:43:01 +03:00
Avi Kivity
3ea40b2848 core: get rid of input_stream::_scanned
With input_stream::read_until() gone, it's not really needed.
2014-09-29 17:53:04 +03:00
Avi Kivity
cd27c4342d core: drop input_stream::read_until()
Superceded by consume().
2014-09-29 17:41:56 +03:00
Avi Kivity
9b2290228b core: add infrastructure for building Ragel parsers 2014-09-29 15:17:42 +03:00
Avi Kivity
7724a616fd core: add input_stream::consume()
This method, intended for request parsers, receives a stream of temporary
buffers until it determines that parsing is done, at which point it can
return any unconsumed partial buffer back to the input stream.

It is intended as a replacement for read_until(), since it can parse in a
single pass.
2014-09-29 15:17:42 +03:00
Gleb Natapov
ca0a0b60e1 smp: Fix smp::submit_to to handle submission to a local cpu
Handle submission to a local cpu by executing a function immediately
and returning ready future.
2014-09-28 14:03:42 +03:00
Gleb Natapov
4c51d387d7 smp: remove debug output 2014-09-28 13:22:05 +03:00
Tomasz Grabiec
099c4cfcc2 core: get rid of reactor::_next_timeout
timer_set maintains next timeout so no need to duplicate it.

This also fixes a potential issue, if upon timer expiry no timer is
pending we did not update _next_timeout which will result in timer fd
not being updated upon next arm().
2014-09-25 20:51:57 +03:00
Tomasz Grabiec
1c58e8e45b core: introduce application template 2014-09-24 15:11:35 +03:00
Gleb Natapov
074bc17c71 Stop all smp thread on SIGINT
Execute stop function on all threads on SIGINT. Join them all before
exit.
2014-09-24 13:12:37 +03:00
Gleb Natapov
6253166d0b Extend inter_thread_work_queue to support messaged without return value 2014-09-24 13:12:35 +03:00
Gleb Natapov
0a93385a4d Add smp support
This patch adds an ability to specify how much threads seastart should
spawn. Each thread run its own instance of event loop. Separate
communication channel is created between each pair of threads.
2014-09-24 13:12:33 +03:00
Gleb Natapov
0c7d511858 Allow creation of readable_eventfd from writeable_eventfd and vice-versa
It is needed for two seastart threads to get two sided of the same file
for communication.
2014-09-24 13:12:29 +03:00
Gleb Natapov
a452ede21e Remove unneeded friend declaration 2014-09-24 13:12:24 +03:00
Gleb Natapov
cfbfce3d6d Separate inter_thread_work_queue from thread_pool
Currently thread_pool implements cross-thread communication channel
 internally. Separate communication logic into its own class to
 reuse it for smp communication in later patches.
2014-09-24 13:12:16 +03:00
Asias He
236418d262 net: Support TCP checksum offload
It gives ~5% httpd improvements on monster.

csum-offload option is added, e.g., to disable:

./httpd --network-stack native --csum-offload off
2014-09-24 11:03:39 +03:00
Avi Kivity
a1f3708fab packet: optimize sharing
Move reference counting into the deleter core, instead of relegating it
to a shared_deleter (which has to be allocated) and an external reference
counted (also allocated).  This dramatically reduces dynamic allocations.
2014-09-23 18:57:11 +03:00
Avi Kivity
26d713e341 Remove internal_deleter 2014-09-23 18:10:10 +03:00
Avi Kivity
9994e09792 temporary_buffer: stop using internal_deleter
Not much point now since packet doesn't use it.
2014-09-23 18:08:46 +03:00
Avi Kivity
e223f748ec core: great deleter rename
deleter::share() is causing massive amounts of allocation.  First,
since usually a packet's deleter is not a shared_deleter, we need to
allocate that shared_deleter.  Second, we need an external reference
count which requires yet another allocation.

Making reference counting part of the deleter class would solve both of
these problems, but we cannot easily do that, since users hold
std::unique_ptr<deleter> which is clearly not sharable.

We could do a massive s/unique_ptr/shared_ptr/ here, but that would have
the side effect of making sharing "too easy" - you simply copy the pointer.
We'd like to keep it explicit.

So to make the change easier, rename the existing unique_ptr<deleter> as
plain "deleter", whereas the old "deleter" becomes deleter::impl:

  old name              new name
  --------              --------
  deleter               deleter::impl
  unique_ptr<deleter>   deleter

with exactly the same semantics.  A later patch can then add explicit sharing.
2014-09-23 11:15:31 +03:00
Avi Kivity
bca61c198f core: add non-vectored data_sink::put() specialization
Often the caller doesn't have a vector, just a single buffer, so allow
the implementation to optimize for that.
2014-09-23 10:37:56 +03:00
Avi Kivity
bddbb3d938 temporary_buffer: add release() method
This allows the caller to take responsibility for deleting the data.

Useful when different data structures use the deleter infrastructure.
2014-09-23 10:37:56 +03:00
Tomasz Grabiec
9816422a67 core: fix SIGSEGV in future::then()
This fixes SIGSEGV which happens when a promise gets resolved and
dies before the callback is registerred via then(). The latter assumes
that _promise must not be nullptr if the state is not resolved
yet. The dying promise should move the resolved state into the
future's local state.
2014-09-22 23:11:13 +03:00
Tomasz Grabiec
ef03d2957f core: make complete_epoll_event() cancel out the right event.
Led to hangs if the client interleaved readable() with writable()
2014-09-22 23:11:12 +03:00
Avi Kivity
195ee5c82f bitset: make functions inline to please compiler 2014-09-22 17:18:46 +03:00
Pekka Enberg
4550632738 Make count_leading_zeros() an inline function
Mark the function as inline to avoid Clang complaining about unused function.
2014-09-22 16:36:56 +03:00
Avi Kivity
af1c015526 core: add stream/subscription abstraction
The future/promise pair is for single-shot use only, which makes it
less useful for repetitive processing.

Add a stream/subscription abstraction, where a stream can produce data
which is repetitively consumed by the subscription.  End-or-stream (or
error condition) is provided by a future.

Inspired by Dart's Stream class.
2014-09-22 11:25:54 +03:00
Avi Kivity
3b1d37ff2f future: implement available()
As the whole point of future/promise is to decouple the producer from the
consumer, available() is not generally useful.  However it can still be
useful in special cases when we want to know who got there first.

One of them is deciding when to drop packets -- if the consumer is not
ready, and no queue space is available, we should just drop the packet
instead of waiting for the consumer.
2014-09-22 11:25:54 +03:00
Avi Kivity
1d11ecfbcd future: implement move assignment 2014-09-22 11:25:54 +03:00
Avi Kivity
64ce457053 future: fix move constructor
If we're no longer tracking the promise (either gone, or never existed),
we shouldn't update it.
2014-09-22 11:25:54 +03:00
Avi Kivity
3168a2fc7c Allow providing options to configure network stacks 2014-09-17 17:44:58 +03:00
Avi Kivity
f81760aba7 spit out temporary_buffer into its own file 2014-09-17 12:42:30 +03:00
Tomasz Grabiec
4311f5dafa array_map: introduce at() 2014-09-16 18:48:14 +03:00
Avi Kivity
812ac77d2f net: spit out packet class into its own files 2014-09-16 10:13:09 +03:00
Tomasz Grabiec
52ab797536 rename engine::start() to engine::when_started()
The imperative form suggests that in addition to returning a future it
performs some action and thus is needed regardless of whether we want
to add a callback or not. But in fact it does not do anything, just
gives away a future.

Signed-off-by: Tomasz Grabiec <tgrabiec@cloudius-systems.com>
2014-09-16 09:59:13 +03:00
Avi Kivity
22e29a7001 timer: add accessor for arming state 2014-09-15 19:23:41 +03:00
Avi Kivity
8ca94a8ea8 timer: disarm the timer after expiring it 2014-09-15 19:23:18 +03:00
Avi Kivity
f7a0a3cdc6 future: reduce allocations
Instead of keeping the future state in heap storage, referenced from
the promise/future/task, keep the state in the promise or future and only
allocate it on the heap as a last resort (for a stack).

Improves httpd throughtput by ~20%.
2014-09-15 14:31:58 +03:00