Programmare il computer
 

Linux syscalls e wrapper glibc

Massimo Soricetti 30 Set 2014 17:14
Sto vedendo che nella glibc esistono molte funzioni che sono solo dei
wrapper per le syscall del kernel. In pratica uno usa i wrapper glibc
invece di fare una syscall.

Così uno è disaccoppiato dalla versione del kernel, nel senso che il
buon funzionamento del suo programma è garan*****o dalla libc a
prescindere da quale versione di kernel sta usando... ma vale la pena?

Voglio dire: non è che le chiamate di sistema Linux cambiano ogni
mattina come quelle di Gnome <grin>: ormai l'interfaccia kernel è bella
stabile. E' ancora giustificato usare i wrapper?
fmassei@gmail.com 30 Set 2014 17:40
On Tuesday, September 30, 2014 5:14:51 PM UTC+2, Massimo Soricetti wrote:
> Sto vedendo che nella glibc esistono molte funzioni che sono solo dei
> wrapper per le syscall del kernel. In pratica uno usa i wrapper glibc
> invece di fare una syscall.
>
> Cos� uno � disaccoppiato dalla versione del kernel, nel senso che il
> buon funzionamento del suo programma � garan*****o dalla libc a
> prescindere da quale versione di kernel sta usando... ma vale la pena?
>
> Voglio dire: non � che le chiamate di sistema Linux cambiano ogni
> mattina come quelle di Gnome <grin>: ormai l'interfaccia kernel � bella
> stabile. E' ancora giustificato usare i wrapper?
>

Considerando quello che danno e quanto pesano direi proprio di sì, che ne
vale la pena.

Ciao!
fmassei@gmail.com 30 Set 2014 17:49
On Tuesday, September 30, 2014 5:40:31 PM UTC+2, fma...@gmail.com wrote:
> Considerando quello che danno e quanto pesano direi proprio di sì, che ne
> vale la pena.
>

Mi spiego meglio và, sennò come al solito sembro solo antipatico :D
In un'applicazione, il tempo speso in CPU o IO è di ordini di grandezza
superiore a quello speso nelle syscall che chiama, syscall che girano in un
tempo di ordini di grandezza superiore al tempo necessario per effettuare
una chiamata a funzione.

Va da se che ridurre l'I/O o migliorare gli algoritmi per girare in meno
cicli a livello di applicazione, o al massimo, per gli sviluppatori kernel,
ottimizzare una syscall, è tempo-uomo meglio speso ;)

Oltretutto, nessuno t'impedisce di chiamare direttamente una syscall, se
proprio vuoi: se non lo fa nessuno i motivi sono quelli che t'ho elencato.

Ciao!
Massimo Soricetti 30 Set 2014 21:31
On 30/09/2014 17:49, fmassei@gmail.com wrote:
>
> Va da se che ridurre l'I/O o migliorare gli algoritmi per girare in meno
> cicli a livello di applicazione, o al massimo, per gli sviluppatori kernel,
> ottimizzare una syscall, è tempo-uomo meglio speso ;)

Per ogni syscall c'è da fare un context switch e un passaggio da codice
utente a codice privilegiato e quindi è una faccenda lunga, questo lo so
anch'io; e sono d'accordo che la glibc possa "syscallare" molto meno,
per esempio passandomi memoria via malloc pescandola da un pool che si è
riservata all'avvio invece di chiederla al kernel ogni volta.
Oppure quando chiedo dati come il PID del mio programma e simili.

Ma nel caso di un wrapper questo vantaggio sparisce. Ogni chiamata a un
syscall wrapper è una syscall PIU' l'overhead del wrapper.

Quindi, perché fornirli? Erano lì ai tempi di Linux 0.99.vattelapesca e
allora si lasciano per compatibilità?
enoquick 30 Set 2014 23:19
Il 30/09/2014 14:31, Massimo Soricetti ha scritto:
> On 30/09/2014 17:49, fmassei@gmail.com wrote:
>>
>> Va da se che ridurre l'I/O o migliorare gli algoritmi per girare in meno
>> cicli a livello di applicazione, o al massimo, per gli sviluppatori
>> kernel,
>> ottimizzare una syscall, è tempo-uomo meglio speso ;)
>
> Per ogni syscall c'è da fare un context switch e un passaggio da codice
> utente a codice privilegiato e quindi è una faccenda lunga, questo lo so
> anch'io; e sono d'accordo che la glibc possa "syscallare" molto meno,
> per esempio passandomi memoria via malloc pescandola da un pool che si è
> riservata all'avvio invece di chiederla al kernel ogni volta.
> Oppure quando chiedo dati come il PID del mio programma e simili.
>
> Ma nel caso di un wrapper questo vantaggio sparisce. Ogni chiamata a un
> syscall wrapper è una syscall PIU' l'overhead del wrapper.
>
> Quindi, perché fornirli? Erano lì ai tempi di Linux 0.99.vattelapesca e
> allora si lasciano per compatibilità?

perche' la glibc e' portabile
Se le syscall devono essere chiamate direttamente da chi ne vuole fare
uso deve tenere conto della piattaforma che usa nonche' fare chiamate in
assembly (una syscall non la si puo' chiamare da puro C)
Massimo Soricetti 1 Ott 2014 00:31
On 30/09/2014 23:19, enoquick wrote:
> Se le syscall devono essere chiamate direttamente da chi ne vuole fare
> uso deve tenere conto della piattaforma che usa nonche' fare chiamate in
> assembly (una syscall non la si puo' chiamare da puro C)

man syscalls(2)
man intro(2)
fmassei@gmail.com 1 Ott 2014 00:57
On Tuesday, September 30, 2014 9:31:56 PM UTC+2, Massimo Soricetti wrote:
> Ma nel caso di un wrapper questo vantaggio sparisce. Ogni chiamata a un
> syscall wrapper � una syscall PIU' l'overhead del wrapper.
>

Hai dribblato i miei punti e non hai aggiunto niente alla domanda inizale:
ancora una volta, sì, c'è l'overhead del wrapper, ma non importa a nessuno.
Prova a calcolare l'overhead del wrapper come percentuale sul tempo totale,
se ci tieni. Non postare il risultato, è ovvio.

Ciao!
Massimo Soricetti 1 Ott 2014 14:22
On 01/10/2014 00:57, fmassei@gmail.com wrote:
>
> Hai dribblato i miei punti e non hai aggiunto niente alla domanda inizale

Io chiedevo "perché" e tu rispondi "non importa"... sarà pure vero, ma
non era quello che chiedevo io :-)
enoquick 1 Ott 2014 14:43
Il 30/09/2014 17:31, Massimo Soricetti ha scritto:
> On 30/09/2014 23:19, enoquick wrote:
>> Se le syscall devono essere chiamate direttamente da chi ne vuole fare
>> uso deve tenere conto della piattaforma che usa nonche' fare chiamate in
>> assembly (una syscall non la si puo' chiamare da puro C)
>
> man syscalls(2)
> man intro(2)
>

E no, quello non vale
E' un wrapper sulla chiamata assembly
fmassei@gmail.com 1 Ott 2014 16:26
On Wednesday, October 1, 2014 2:22:56 PM UTC+2, Massimo Soricetti wrote:
> On 01/10/2014 00:57, fmassei@gmail.com wrote:
>> Hai dribblato i miei punti e non hai aggiunto niente alla domanda inizale
>
> Io chiedevo "perché" e tu rispondi "non importa"... sarà pure vero, ma
> non era quello che chiedevo io :-)
>

Uhm, forse ho capito.. beh, è prassi comune per ogni libreria che vuole essere
robusta avere un wrapper su *ogni* dipendenza esterna. Il fatto che ora sia
stabile non significa che lo fosse anni fa o che un giorno non potrebbe
risultare comodo avere un posto dove mettere un hook.
Sul "perché c'è ancora" poi, son sicuro che se mandi una patch al responsabile
della glibc rimuovendoli ti verrà risposto: "ma perché le vuoi levare, che
noia ti danno? :D"

Ciao!
Alessandro Soraruf 1 Ott 2014 19:22
On 30/09/2014 17:14, Massimo Soricetti wrote:
> Voglio dire: non è che le chiamate di sistema Linux cambiano ogni
> mattina come quelle di Gnome


Od*****, ogni mattina magari no, ma proprio stabilissime non direi, visto
che conosci le man, man 2 syscalls:

The list of system calls that are available as at kernel 3.5
(or in a
few cases only on older kernels) is as follows:

System call Kernel Notes

âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ

_llseek(2) 1.2
_newselect(2)
_sysctl(2)
accept(2)
accept4(2) 2.6.28
access(2)
acct(2)
add_key(2) 2.6.11
adjtimex(2)
alarm(2)
alloc_hugepages(2) 2.5.36 Removed in 2.5.44
bdflush(2) Deprecated (does
nothing) since 2.6
bind(2)
brk(2)
cacheflush(2) 1.2 Not on x86
capget(2) 2.2
capset(2) 2.2
chdir(2)
chmod(2)
chown(2)
chown32(2) 2.4
chroot(2)
clock_adjtime(2) 2.6.39
clock_getres(2) 2.6
clock_gettime(2) 2.6
clock_nanosleep(2) 2.6
clock_settime(2) 2.6
clone(2)
close(2)
connect(2)
creat(2)
create_module(2) Removed in 2.6
delete_module(2)

dup(2)
dup2(2)
dup3(2) 2.6.27
epoll_create(2) 2.6
epoll_create1(2) 2.6.27
epoll_ctl(2) 2.6
epoll_pwait(2) 2.6.19
epoll_wait(2) 2.6
eventfd(2) 2.6.22
eventfd2(2) 2.6.27
execve(2)
exit(2)
exit_group(2) 2.6
faccessat(2) 2.6.16
fadvise64(2) 2.6
fadvise64_64(2) 2.6
fallocate(2) 2.6.23
fanotify_init(2) 2.6.37
fanotify_mark(2) 2.6.37
fchdir(2)
fchmod(2)
fchmodat(2) 2.6.16
fchown(2)
fchown32(2) 2.4
fchownat(2) 2.6.16
fcntl(2)
fcntl64(2) 2.4
fdatasync(2)
fgetxattr(2) 2.6; 2.4.18
finit_module(2) 3.8
flistxattr(2) 2.6; 2.4.18
flock(2) 2.0
fork(2)
free_hugepages(2) 2.5.36 Removed in 2.5.44
fremovexattr(2) 2.6; 2.4.18
fsetxattr(2) 2.6; 2.4.18
fstat(2)
fstat64(2) 2.4
fstatat64(2) 2.6.16
fstatfs(2)
fstatfs64(2) 2.6
fsync(2)
ftruncate(2)
ftruncate64(2) 2.4
futex(2) 2.6
futimesat(2) 2.6.16
get_kernel_syms(2) Removed in 2.6
get_mempolicy(2) 2.6.6
get_robust_list(2) 2.6.17
get_thread_area(2) 2.6
getcpu(2) 2.6.19
getcwd(2) 2.2
getdents(2) 2.0
getdents64(2) 2.4
getegid(2)
getegid32(2) 2.4
geteuid(2)
geteuid32(2) 2.4
getgid(2)
getgid32(2) 2.4
getgroups(2)
getgroups32(2) 2.4
ge*****imer(2)
getpeername(2)
getpagesize(2) 2.0 Not on x86

getpgid(2)
getpgrp(2)
getpid(2)
getppid(2)
getpriority(2)
getresgid(2) 2.2
getresgid32(2) 2.4
getresuid(2) 2.2
getresuid32(2) 2.4
getrlimit(2)
getrusage(2)
getsid(2) 2.0
getsockname(2)
getsockopt(2)
gettid(2) 2.4.11
gettimeofday(2)
getuid(2)
getuid32(2) 2.4
getxattr(2) 2.6; 2.4.18
init_module(2)
inotify_add_watch(2) 2.6.13
inotify_init(2) 2.6.13
inotify_init1(2) 2.6.27
inotify_rm_watch(2) 2.6.13
io_cancel(2) 2.6
io_destroy(2) 2.6
io_getevents(2) 2.6
io_setup(2) 2.6
io_submit(2) 2.6
ioctl(2)
ioperm(2)
iopl(2)
ioprio_get(2) 2.6.13
ioprio_set(2) 2.6.13
ipc(2)
kcmp(2) 3.5
kern_features(2) 3.7 Sparc64
kexec_load(2) 2.6.13
keyctl(2) 2.6.11
kill(2)
lchown(2) 2.2
lchown32(2) 2.4
lgetxattr(2) 2.6; 2.4.18
link(2)
linkat(2) 2.6.16
listen(2)
listxattr(2) 2.6; 2.4.18
llistxattr(2) 2.6; 2.4.18
lookup_dcookie(2) 2.6
lremovexattr(2) 2.6; 2.4.18
lseek(2)
lsetxattr(2) 2.6; 2.4.18
lstat(2)
lstat64(2) 2.4
madvise(2) 2.4
madvise1(2) 2.4
mbind(2) 2.6.6
migrate_pages(2) 2.6.16
mincore(2) 2.4
mkdir(2)
mkdirat(2) 2.6.16
mknod(2)
mknodat(2) 2.6.16
mlock(2)
mlockall(2)

mmap(2)
mmap2(2) 2.4
modify_ldt(2)
mount(2)
move_pages(2) 2.6.18
mprotect(2)
mq_getsetattr(2) 2.6.6
mq_notify(2) 2.6.6
mq_open(2) 2.6.6
mq_timedreceive(2) 2.6.6
mq_timedsend(2) 2.6.6
mq_unlink(2)
mremap(2) 2.0
msgctl(2)
msgget(2)
msgrcv(2)
msgsnd(2)
msync(2) 2.0
munlock(2)
munlockall(2)
munmap(2)
name_to_handle_at(2) 2.6.39
nanosleep(2) 2.0
nfsservctl(2) 2.2 Removed in 3.1
nice(2)
oldfstat(2)
oldlstat(2)
oldolduname(2)
oldstat(2)
olduname(2)
open(2)
open_by_handle_at(2) 2.6.39
openat(2) 2.6.16
pause(2)
pcicon*****_iobase(2) 2.2.15; 2.4 Not on x86
pcicon*****_read(2) 2.0.26; 2.2 Not on x86
pcicon*****_write(2) 2.0.26; 2.2 Not on x86
perf_event_open(2) 2.6.31 Was called
perf_counter_open()
in 2.6.31; renamed
in 2.6.32
personality(2) 1.2
pipe(2)
pipe2(2) 2.6.27
pivot_root(2) 2.4
poll(2) 2.2
ppoll(2) 2.6.16
prctl(2) 2.2
pread64(2) Added as "pread" in
2.2; renamed
"pread64" in 2.6
preadv(2) 2.6.30
prlimit(2) 2.6.36
process_vm_readv(2) 3.2
process_vm_writev(2) 3.2
pselect6(2) 2.6.16
ptrace(2)
pwrite64(2) Added as "pwrite" in
2.2; renamed
"pwrite64" in 2.6
pwritev(2) 2.6.30
query_module(2) 2.2 Removed in 2.6
quotactl(2)
read(2)
readahead(2) 2.4.13

readdir(2)
readlink(2)
readlinkat(2) 2.6.16
readv(2) 2.0
reboot(2)
recv(2)
recvfrom(2)
recvmsg(2)
recvmmsg(2) 2.6.33
remap ******* pages(2) 2.6
removexattr(2) 2.6; 2.4.18
rename(2)
renameat(2) 2.6.16
request_key(2) 2.6.11
restart_syscall(2) 2.6
rmdir(2)
rt_sigaction(2) 2.2
rt_sigpending(2) 2.2
rt_sigprocmask(2) 2.2
rt_sigqueueinfo(2) 2.2
rt_sigreturn(2) 2.2
rt_sigsuspend(2) 2.2
rt_sigtimedwait(2) 2.2
rt_tgsigqueueinfo(2) 2.6.31
s390_runtime_instr(2) 3.7 s390 only
sched_get_priority_max(2) 2.0
sched_get_priority_min(2) 2.0
sched_getaffinity(2) 2.6
sched_getparam(2) 2.0
sched_getscheduler(2) 2.0
sched_rr_get_interval(2) 2.0
sched_setaffinity(2) 2.6
sched_setparam(2) 2.0
sched_setscheduler(2) 2.0
sched_yield(2) 2.0
select(2)
semctl(2)
semget(2)
semop(2)
semtimedop(2) 2.6; 2.4.22
send(2)
sendfile(2) 2.2
sendfile64(2) 2.6; 2.4.19
sendmmsg(2) 3.0
sendmsg(2)
sendto(2)
set_mempolicy(2) 2.6.6
set_robust_list(2) 2.6.17
set_thread_area(2) 2.6
set_tid_address(2) 2.6
setdomainname(2)
setfsgid(2) 1.2
setfsgid32(2) 2.4
setfsuid(2) 1.2
setfsuid32(2) 2.4
setgid(2)
setgid32(2) 2.4
setgroups(2)
setgroups32(2) 2.4
sethostname(2)
se*****imer(2)
setns(2) 3.0
setpgid(2)
setpriority(2)
setregid(2)

setregid32(2) 2.4
setresgid(2) 2.2
setresgid32(2) 2.4
setresuid(2) 2.2
setresuid32(2) 2.4
setreuid(2)
setreuid32(2) 2.4
setrlimit(2)
setsid(2)
setsockopt(2)
settimeofday(2)
setuid(2)
setuid32(2) 2.4
setup(2) Removed in 2.2
setxattr(2) 2.6; 2.4.18
sgetmask(2)
shmat(2)
shmctl(2)
shmdt(2)
shmget(2)
shutdown(2)
sigaction(2)
sigaltstack(2) 2.2
signal(2)
signalfd(2) 2.6.22
signalfd4(2) 2.6.27
sigpending(2)
sigprocmask(2)
sigreturn(2)
sigsuspend(2)
socket(2)
socketcall(2)
socketpair(2)
splice(2) 2.6.17
spu_create(2) 2.6.16 PowerPC only
spu_run(2) 2.6.16 PowerPC only
ssetmask(2)
stat(2)
stat64(2) 2.4
statfs(2)
statfs64(2) 2.6
stime(2)
subpage_prot(2) 2.6.25 PowerPC if
CON*****_PPC_64K_PAGES
swapoff(2)
swapon(2)
symlink(2)
symlinkat(2) 2.6.16
sync(2)
sync ******* range(2) 2.6.17
sync ******* range2(2) 2.6.22 Architecture-spe-
cific variant of
sync ******* range(2)
syncfs(2) 2.6.39
sysfs(2) 1.2
sysinfo(2)
syslog(2)
tee(2) 2.6.17
tgkill(2) 2.6
time(2)
timer_create(2) 2.6
timer_delete(2) 2.6
timer_getoverrun(2) 2.6
timer_gettime(2) 2.6
timer_settime(2) 2.6

timerfd_create(2) 2.6.25
timerfd_gettime(2) 2.6.25
timerfd_settime(2) 2.6.25
times(2)
tkill(2) 2.6; 2.4.22
truncate(2)
truncate64(2) 2.4
ugetrlimit(2) 2.4
umask(2)
umount(2)
umount2(2) 2.2
uname(2)
unlink(2)
unlinkat(2) 2.6.16
unshare(2) 2.6.16
uselib(2)
ustat(2)
utime(2)
utimensat(2) 2.6.22
utimes(2) 2.2
utrap_install(2) Sparc
vfork(2)
vhangup(2)
vm86old(2)
vmsplice(2) 2.6.17
wait4(2)
waitid(2) 2.6.10
waitpid(2)
write(2)
writev(2) 2.0

Senza contare che dipende dall'architettura il come le chiami, ad esempio:

exit(0);

in i386 diventa (chiamata a interrupt 0x80h):

mov eax, 1
mov ebx, 0
int 80h

in x86_64 diventa (instruciont syscall):

mov rax,60
mov rdi,0
syscall

Ciao
A.
fmassei@gmail.com 1 Ott 2014 19:45
On Wednesday, October 1, 2014 7:22:17 PM UTC+2, Alessandro Soraruf wrote:
> On 30/09/2014 17:14, Massimo Soricetti wrote:
>> Voglio dire: non и che le chiamate di sistema Linux cambiano ogni
>> mattina come quelle di Gnome
>
> Od*****, ogni mattina magari no, ma proprio stabilissime non direi, visto
> che conosci le man, man 2 syscalls:
>

<snip>
Però la retrocompatibilità è praticamente sempre garan*****a.

> Senza contare che dipende dall'architettura il come le chiami, ad esempio:
>
> exit(0);
>
> in i386 diventa (chiamata a interrupt 0x80h):
>
> mov eax, 1
> mov ebx, 0
> int 80h
>

Però non è così da anni, almeno che non setti un processore d'altri tempi:
"syscall" viene chiamata invece di "int 80h" da più di 10 anni di default.
La differenza era tra processori intel e amd, che avevano opcodes diversi,
ma il concetto era sempre di non dover fare un int per una syscall: dovrei
andarmi a vedere il codice ma sinceramente non c'ho proprio voglia XD

Son comunque d'accordo sul sentimento e l'idea che esprimi, come ho già
scritto.

Ciao!

Links
Giochi online
Dizionario sinonimi
Leggi e codici
Ricette
Testi
Webmatica
Hosting gratis
   
 

Programmare il computer | Tutti i gruppi | it.comp.programmare | Notizie e discussioni programmare | Programmare Mobile | Servizio di consultazione news.