Commit Graph

704 Commits

Author SHA1 Message Date
Avi Kivity
604b13633e distributed: document foreign_ptr<> 2015-06-02 22:37:43 +03:00
Avi Kivity
3fe6bb505e future: document traitless map_reduce() 2015-06-02 22:20:13 +03:00
Avi Kivity
ba0e4e45bc future: disable inline continuations in debug mode
Inline continuations can hide bugs where a stack variable is captured by
reference.  Disable them in debug mode.
2015-06-02 15:12:10 +03:00
Avi Kivity
606368f6f6 shared_ptr: add debug option for detecting copies on wrong cpus
Track the cpu on which the reference count referred to by shared_ptr was
created, and prevent modifying it on the wrong cpu.
2015-06-01 18:18:52 +03:00
Avi Kivity
b0abe9230b doc: fix typo in do_until() 2015-06-01 11:37:42 +03:00
Avi Kivity
23d874f786 doc: low-level memory management 2015-06-01 11:35:37 +03:00
Avi Kivity
3d4314b7e4 doc: disambigute class future from the future documentation module 2015-05-31 19:08:16 +03:00
Avi Kivity
3a63706f97 future: document more future-util functions 2015-05-31 19:00:40 +03:00
Avi Kivity
abaad55a66 future: fix documentation errors
Noted by Nadav.
2015-05-31 18:10:54 +03:00
Avi Kivity
65ff797ec1 doc: add main doxygen page 2015-05-31 17:51:53 +03:00
Avi Kivity
aa519f86a8 future: user-level documentation 2015-05-31 17:29:31 +03:00
Avi Kivity
2877364947 future: separate task class into its own header
tasks are a lower-level concept than future/promise, so move them to their
own header.
2015-05-31 15:49:05 +03:00
Glauber Costa
b77605cdba reactor: call remove instead of unlink
remove() is a convenient glibc wrapper that will unlink() a file and rmdir() a
directory. It will allow us to operate on both without creating a separate
function for a directory.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
2015-05-28 17:56:42 +03:00
Vlad Zolotarov
c547f9a718 fstream: prevent ANY exceptions to be thrown in good get() flow
There is a hidden exception that could be thrown insize file::dma_get_bulk()
if file size is not aligned with fstream::_buffer_size. In this case
file::dma_read_bulk() will be given a _buffer_size as a length for the last data
chunk in the file too. file::dma_read_bulk() will get a short read (till EOF)
and then will try to read beyond it (by calling file::read_maybe_eof())
in order to differentiate between I/O error and EOF. file::read_maybe_eof()
will throw a file::eof_error exception to indicate the EOF, it will be caught
by file::dma_read_bulk() and since we have read some "good" bytes by now this
exception won't be forwarded further. However the damage by throwing the exception
has already been done and we want to avoid this in fstream flow (unless there are
real errors).

In order to prevent the above we will always request file::dma_read_bulk() to
read the amount of data it should be able to deliver (not beyond EOF).

Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
2015-05-28 13:25:40 +03:00
Vlad Zolotarov
b70c9a2e18 file: read_maybe_eof(): Don't throw file::eof_error().
Make read_maybe_eof() return zero-sized buffer when pos is at or beyond
EOF. This will prevent an internal exception throwing inside "file" class
in cases when dma_read_bulk() is going to succeed and return read data, e.g. when
it was called with "offset" less than file size but "offset" + "range_size"
beyond EOF.

Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
2015-05-28 13:25:40 +03:00
Vlad Zolotarov
ae03cfbb5d file: clarify the class interface.
Move read_state helper class, file::dma_read_bulk() and file::read_maybe_eof()
definitions outside the class declaration in order to make reading the class
interface easier.

Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
2015-05-28 13:25:40 +03:00
Avi Kivity
9243187ac2 stream: make subscriptions a little more usable
Requiring next_fn to be available at listen() time means you can't pass
subscriptions around, and it is often hard to create next_fn, since it
usually needs to capture 'this', while this also points to the subscription
itself, creating a chicken and egg problem.

Fix by separating the registration process into two steps: listen() creates
the subscription, and start() accepts the next callback and starts processing
events.
2015-05-28 13:11:40 +03:00
Avi Kivity
ef11234d0c reactor: add counters for file reads, writes, fsyncs, and threaded fallbacks
Reviewed-by: Pekka Enberg <penberg@cloudius-systems.com>
2015-05-27 14:16:58 +03:00
Avi Kivity
bdfe41820a future-util.hh: add missing include 2015-05-26 16:42:15 +03:00
Vlad Zolotarov
7b1f433aed file: Rework read interface
Move the get() logic in fstream.cc into the file::dma_read_bulk()
fixing some issues:
   - Fix the funny "alignment" calculation.
   - Make sure the length is aligned too.
   - Added new functions:
      - dma_read(pos, len): returns a temporary_buffer with read data and
                            doesn't assume/require any alignment from either "pos"
                            or "len". Unlike dma_read_bulk() this function will
                            trim the resulting buffer to the requested size.
      - dma_read_exactly(pos, len): does exactly what dma_read(pos, len) does but it
                                    will also throw and exception if it failed to read
                                    the required number of bytes (e.g. EOF is reached).
   - Changed the names of parameters of dma_read(pos, buf, len) in order to emphasize
     that they have to be aligned.
   - Added a description to dma_read(pos, buf, len) to make it even more clear.

Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
2015-05-26 15:15:39 +03:00
Vlad Zolotarov
796c203d68 core: remove #include "reactor.hh" from future-util.hh
When future-util.hh is included in files included in reactor.hh (e.g. file.hh).

Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
2015-05-26 15:15:28 +03:00
Avi Kivity
d115f9cef6 future: modernize lambda_task, make_task
Use inline, override, final, make_unique.
2015-05-25 22:21:49 +03:00
Avi Kivity
d1bc08e9e7 future: merge two variants of make_task()
Using universal references we can unify the two cases.
2015-05-25 22:18:24 +03:00
Avi Kivity
8812504e4b future: sprinke always_inline attributes in strategic places
gcc makes poor inlining decisions sometimes, which cause all the value-
tracking optimizations to be lost.  Forcing it to inline (particularly
around destructors) allows ready futures to be inlined with fewer always-
true tests and data movements.
2015-05-25 21:27:40 +03:00
Asias He
88e7dcfa86 Remove redundant const in static constexpr const
From http://en.cppreference.com/w/cpp/language/constexpr:

   A constexpr specifier used in an object declaration implies const.

However, We can not change from
   static constexpr const char* TIME_FORMAT = "%a %b %d %I:%M:%S %Z %Y";
to
   static constexpr char* TIME_FORMAT = "%a %b %d %I:%M:%S %Z %Y";

The compiler complains:

   In file included from json/formatter.cc:22:0:
   json/formatter.hh:132:42: error: deprecated conversion from string
   constant to ‘char*’ [-Werror=write-strings]
        static constexpr char* TIME_FORMAT = "%a %b %d %I:%M:%S %Z %Y";

Since, unlike const, constexpr does not modify a type. It just applies
to an object (or function), and incidentally implies const to the
top-level type.
2015-05-25 11:57:19 +03:00
Avi Kivity
0bd48b37ed future: consolidate task_with_state, task_with_ready_state
The internal structs task_with_state and task_with_ready_state are
identical except for their constructors.  Merge them into a new
struct continuation.
2015-05-23 11:40:39 +03:00
Gleb Natapov
0c549eeca6 reactor: fix unintentional timer copying in reactor destructor 2015-05-21 16:33:20 +03:00
Gleb Natapov
f77d3bbf52 net: extend connect() API to allow to bind to specific local address/port 2015-05-20 17:10:00 +03:00
Nadav Har'El
eda6a528eb iostream: consume() - fix hung test
The test tests/memcached/test_ascii_parser hung after the change to
consume(). The problem was that consume() notified the consumer of an
EOF by sending it an empty buffer, and then it expected to get back a
message that it shouldn't read more (by setting the unconsumed buffer),
if it didn't, it continued to send empty buffers in a never-ending loops.

So this patch changes consume() to send one empty buffer to the consumer
on the end-of-file, and then stop (regardless of what the consumer returns).

It would have probably made sense to *not* send an empty buffer to the
consumer after the data is done - not even once - but if we change this
behavior, it will break the existing tests.

Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
Tested-by: Tomasz Grabiec <tgrabiec@cloudius-systems.com>
2015-05-20 14:14:59 +03:00
Nadav Har'El
c5f61666d3 input_stream::consume() overhaul
Our input_stream::consume() mechanism allows feeding data from an input
stream into a consumer, piece by piece, until the consumer doesn't want
any more. It currently assumed the input can block (when reading from disk),
but the consumption is assumed to be immediate. This patch adds support for
blocking in the consumption function: The consumer now returns a future
which it promises to fulfill after consuming the given buffer.

This patch goes further by somewhat simplifying (?) the interface of the
consumer. Instead of receiving a mysterious "done" lambda the consumer
is supposed to call when done (doesn't want any more input), the consumer
now returns a future<optional<temporary_buffer<char>>, which means:

1. The future is fulfilled when the consumer is done with this buffer
   and either wants more - or wants to stop.

2. If the consumer wants to stop, it returns the *remaining* part of the
   buffer it didn't want to process (this will be pushed back into the
   input stream).

3. If the consumer is not done, and wants to consume more, it returns an
   unset optional.

Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
2015-05-19 19:33:18 +03:00
Avi Kivity
1cf95e4bd8 Merge branch 'thread' of github.com:cloudius-systems/seastar-dev
This patchset adds thread support to seastar.  Threads can use the normal
seastar API, and may also "block" by calling future<>::get() on an
unavailable future.  Synchronous and asynchronous code may be intermixed.

Threads may not issue blocking operating system calls.
2015-05-18 15:27:22 +03:00
Avi Kivity
784e03aa31 thread: use setjmp/longjmp for context switches
swapcontext() is expensive as it invokes system calls.  Replace it with
setjmp()/longjmp().  We still use setcontext() initially, since that's
the most reasonable portable method of setting up a stack.

Context switch time (measured by thread_context_switch) is reduced to
120ns (from 450ns), with inefficiencies in the test itself and in future<>
dominating.
2015-05-17 17:22:48 +03:00
Avi Kivity
cd0ae463b3 core: thread support
Add a thread class that can be used to launch a blockable thread of
execution.  Within a thread, future<>::get() can be called on an
unavailable future, in which case it blocks until the future is made ready.
2015-05-17 15:57:11 +03:00
Nadav Har'El
902d5b21ca sleep: Fix use-after-free in sleep()
The implementation of sleep() looks like a game of Seastar golf - doing
something in the minimum number of lines possible :-) Unfortunately, it
looks very clever, but not quite right. sleep() usually works correctly,
but the sanitizer (in the debug build) catches a use after free.

The problem was that we delete an object which contains a timer which
contains the callback (and std::function) - from inside this callback.

The workaround in this patch is to use our future chaining to only delete
the sleeper object after its future became ready - and at that point, none
of the sleeper object or code is needed any more.

This patch also includes a regression test for this issue. The test looks
silly (just sleeps and checks nothing), but in the debugging build it
failed (with a sanitizer reporting use-after-free) before this patch.

Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
2015-05-14 11:26:58 +03:00
Avi Kivity
2f10793898 core: add open_flags::exclusive (O_EXCL) 2015-05-13 13:23:18 +03:00
Avi Kivity
bf527c2842 future: add range-based parallel_for_each variant 2015-05-13 10:53:13 +03:00
Avi Kivity
f3c8994535 distributed: add map_reduce() variant accepting an initial value
Separating the initial value (and accumulator) from the reducer function
can result in simpler invocations.

Unfortunately, the name conflicts with another variant, so we have to name
the method map_reduce0.
2015-05-12 16:57:50 +03:00
Avi Kivity
50d65f1d86 smp: protect lifetime of function parameter to submit_to()
When submit_to() calls to a different core, and when the function to
be executed is a temporary (the usual case), we copy it to the heap for
the duration of execution.  However when the function happens to execute
locally, we don't copy it, which can lead to a use-after-free if the function
defers.

Fix by detecting the case of local execution of a temporary function, and
copying it to the heap in that case.
2015-05-12 14:33:18 +03:00
Avi Kivity
6173d1af62 Merge branch 'calle/scollectd-fixes' of github.com:cloudius-systems/seastar-dev
collectd fixes, from Calle.
2015-05-12 12:42:19 +03:00
Calle Wilund
ad5feda8ae Collectd: Fix registration/deregistration and reg. anchor managment
Obviously, I was sleeping or something when I wrote the reg/unreg code, since
using copy semantics for anchors is equivalent with double unregistrations.
Luckily, unregister was broken as well, so counters did stay active. Which
however broke things once actual non-persistent counters were added. Doh.

* Anchors must be non-copyable
* Above makes creating std::vector<registration> from initializer list
tricky, so added helper type "registrations" which inherits vector<reg>
but constructs from initializer_list<type_instance_id>, avoiding illegal
copying.
* Both register and unregister were broken (map semantics does not overwrite
on insert, only [] or iterator operation).
* Modified the various registration callsites to use registrations and move
semantics.
2015-05-12 11:30:44 +02:00
Calle Wilund
2646fa188f Collectd: Add virtual destructor to value_list
Since we bind actual std::functions etc, a virtual destructor is needed.
2015-05-12 11:30:44 +02:00
Calle Wilund
e941b5a378 Collectd: Make sure get_instance_ids only returns active id:s 2015-05-12 11:30:44 +02:00
Calle Wilund
db9869639c Collectd: change string types to sstring 2015-05-12 11:30:44 +02:00
Avi Kivity
4cea444fb2 collectd: avoid using an exception as end-of-packet indicator
Collectd uses an exception to signal that the buffer space in the packet
is exhausted and a new packet needs to be started.  This violates the
"exceptions are for exceptional conditions" guideline, but more practically,
makes it hard to use the gdb "catch throw" command to trap exceptions.

Fix by using a data member to store the overflow condition instead.
2015-05-11 18:02:41 +03:00
Avi Kivity
0e23702dfd core: add make_directory() API 2015-05-11 13:33:33 +03:00
Amnon Heiman
9477e41577 collectd: Add an API to scollectd data
The scollectd is an infrastructure that allows different part of the
code to register internal counters and the infrastructure would send it
periodically to an external server.

This patch adds and API to the scollectd that allows to inquire a
register value and the names of the registered values.

The collectd_value structure is used to return a single value that can
be of type: double or signed and unsigned 64 bit long.

The definition of the API are found in scollectd_api.hh

The inquiries are for the local cpu, it is up to the caller to call a
relevent cpu.

Signed-off-by: Amnon Heiman <amnon@cloudius-systems.com>
2015-05-07 15:23:28 +03:00
Avi Kivity
f3afe9051f Merge branch 'shared_ptr'
const support for lw_shared_ptr<>.
2015-05-06 13:27:00 +03:00
Amnon Heiman
f4f6c0a4a3 smp: add all_cpus() helper
This adds a static method to return a range object to smp.
with this patch it is possible to use:

for (auto i : smp::all_cpus())

Signed-off-by: Amnon Heiman <amnon@cloudius-systems.com>
2015-05-06 11:49:45 +03:00
Avi Kivity
fe9c5a2750 shared_ptr: const correctness for lw_shared_ptr::use_count() 2015-05-06 11:41:51 +03:00
Avi Kivity
211c77bf52 shared_ptr: add const support for lw_shared_ptr 2015-05-06 11:41:33 +03:00