[Dev] [Cynara] Async admin API proposal

Jacek Bukarewicz j.bukarewicz at samsung.com
Mon Aug 25 16:03:08 GMT 2014


Hi,

On 08/25/2014 12:52 PM, Patrick Ohly wrote:
>>
>> I think that cynara_async_check not returning error code would make life
>> harder for clients that actually need response in place of the call
>> (that is the case for dbus-daemon I guess ?).
> My question above was about the case where we either force dbus-daemon
> to get the result through the callback (clearly not optimal) or have a
> separate cynara_check_nonblocking() (I just made up the name, more on it
> below).
>
> The sequence in dbus-daemon then would be:
>
> - cynara_check_nonblocking()
> - error and result handling
> - if no answer available, suspend connection
> - cynara_async_check()
> - no error checking needed here
> - return to main event processing
> - when check completed, try connection again
I'm ok with such approach (as I am with immediate callback invocation). 
Adding one function won't add much more complexity to the library while 
it will make it more functional.

It has been pointed out that calling poll with POLLHUP event could 
negate the benefits of cache. I made a simple benchmark for syscalls by 
running test binary with strace -T.
Results show that this syscall is rather fast when compared to the 
others (full results in attached file).
On Exynos 4412 (ARM Cortex-A9) it took 32 microseconds for it to finish 
on no disconnection case. When socket is disconnected it took 56 
microseconds.
On Intel processor (i7-3770 CPU @ 3.40GHz) such check took 4 
microseconds (no disconnection). When socket was disconnected time grows 
to 31 microseconds
Test was run with CPU scaling governors set to performance to reduce 
variability.
This single call might be the biggest consumer of the CPU cycles for 
"check cache" function, but I don't think we have an option of not 
calling it.


>
>> To sum up, I don't see any practical benefits of this function returning
>> void. Returning such value doesn't force the client to handle it fully
>> in the place of the call but just gives such possibility which I see as
>> advantage rather than a drawback.
> So you are saying that the error should get returned twice, once from
> cynara_async_check() and again to the callback? I find that confusing.
> In the callback it would be hard to tell whether an error is new or has
> already been handled.
I agree that it's confusing and I don't insist on that. I just felt that 
not returning error code can make the API less practical.


Best regards,

-- 
Jacek Bukarewicz
Samsung R&D Institute Poland
Samsung Electronics
j.bukarewicz at samsung.com

-------------- next part --------------
Exynos 4412 (4-core Cortex-A9):

execve("/usr/bin/usleep", ["/usr/bin/usleep"], [/* 32 vars */]) = 0 <0.000451>
brk(0)                                  = 0x12000 <0.000034>
uname({sys="Linux", node="localhost", ...}) = 0 <0.000029>
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6fae000 <0.000038>
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory) <0.000046>
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 <0.000047>
fstat64(3, {st_mode=S_IFREG|0644, st_size=36598, ...}) = 0 <0.000028>
mmap2(NULL, 36598, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb6f89000 <0.000032>
close(3)                                = 0 <0.000026>
open("/lib/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3 <0.000047>
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\250\364\0\0004\0\0\0"..., 512) = 512 <0.000037>
fstat64(3, {st_mode=S_IFREG|0755, st_size=229588, ...}) = 0 <0.000032>
mmap2(NULL, 147776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6f64000 <0.000037>
mprotect(0xb6f80000, 28672, PROT_NONE)  = 0 <0.000041>
mmap2(0xb6f87000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0xb6f87000 <0.000053>
close(3)                                = 0 <0.000027>
open("/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 <0.000051>
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0}w\1\0004\0\0\0"..., 512) = 512 <0.000032>
fstat64(3, {st_mode=S_IFREG|0755, st_size=1221056, ...}) = 0 <0.000029>
mmap2(NULL, 951728, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6e7b000 <0.000035>
mprotect(0xb6f56000, 32768, PROT_NONE)  = 0 <0.000038>
mmap2(0xb6f5e000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xdb000) = 0xb6f5e000 <0.000052>
mmap2(0xb6f61000, 9648, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb6f61000 <0.000046>
close(3)                                = 0 <0.000027>
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6fad000 <0.000037>
set_tls(0xb6fad6d0, 0xb6fb1000, 0xb6faddb8, 0xb6fad6d0, 0xb6fb1000) = 0 <0.000028>
mprotect(0xb6f5e000, 8192, PROT_READ)   = 0 <0.000037>
mprotect(0xb6f87000, 4096, PROT_READ)   = 0 <0.000036>
mprotect(0x10000, 4096, PROT_READ)      = 0 <0.000033>
mprotect(0xb6fb0000, 4096, PROT_READ)   = 0 <0.000035>
munmap(0xb6f89000, 36598)               = 0 <0.000048>
socket(PF_LOCAL, SOCK_STREAM, 0)        = 3 <0.000051>
connect(3, {sa_family=AF_LOCAL, sun_path="/tmp/cynara-dummy.socket"}, 110) = 0 <0.000081>
poll([{fd=3, events=POLLHUP}], 1, 0)    = 0 (Timeout) <0.000032>
read(3, "", 1023)                       = 0 <2.836886>
poll([{fd=3, events=POLLHUP}], 1, 0)    = 1 ([{fd=3, revents=POLLHUP}]) <0.000056>
close(3)                                = 0 <0.000059>
exit_group(0)                           = ?
+++ exited with 0 +++


Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz:
execve("bin/usleep", ["bin/usleep"], [/* 52 vars */]) = 0 <0.000182>
[ Process PID=414 runs in 32 bit mode. ]
brk(0)                                  = 0x88a5000 <0.000069>
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory) <0.000059>
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffffffff7704000 <0.000040>
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory) <0.000008>
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 <0.000022>
fstat64(3, {st_mode=S_IFREG|0644, st_size=130546, ...}) = 0 <0.000045>
mmap2(NULL, 130546, PROT_READ, MAP_PRIVATE, 3, 0) = 0xfffffffff76e4000 <0.000038>
close(3)                                = 0 <0.000005>
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory) <0.000005>
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 <0.000007>
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0@\226\1\0004\0\0\0"..., 512) = 512 <0.000007>
fstat64(3, {st_mode=S_IFREG|0755, st_size=1734120, ...}) = 0 <0.000005>
mmap2(NULL, 1747676, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xfffffffff7539000 <0.000005>
mprotect(0xf76dd000, 4096, PROT_NONE)   = 0 <0.000008>
mmap2(0xf76de000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a4) = 0xfffffffff76de000 <0.000016>
mmap2(0xf76e1000, 10972, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xfffffffff76e1000 <0.000005>
close(3)                                = 0 <0.000005>
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffffffff7538000 <0.000004>
set_thread_area(0xffbf41e0)             = 0 <0.000004>
mprotect(0xf76de000, 8192, PROT_READ)   = 0 <0.000005>
mprotect(0x8049000, 4096, PROT_READ)    = 0 <0.000005>
mprotect(0xf7727000, 4096, PROT_READ)   = 0 <0.000005>
munmap(0xf76e4000, 130546)              = 0 <0.000008>
socket(PF_FILE, SOCK_STREAM, 0)         = 3 <0.000009>
connect(3, {sa_family=AF_FILE, path="/tmp/cynara-dummy.socket"}, 110) = 0 <0.000015>
poll([{fd=3, events=POLLHUP}], 1, 0)    = 0 (Timeout) <0.000004>
read(3, "", 1023)                       = 0 <2.357402>
poll([{fd=3, events=POLLHUP}], 1, 0)    = 1 ([{fd=3, revents=POLLHUP}]) <0.000031>
close(3)                                = 0 <0.000084>
exit_group(0)


More information about the Dev mailing list