git: 2beeeacdb8 - main - update translation of articles/linux-emulation to Russian
Vladlen Popolitov <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.cvs.doc |
|---|---|
| Message-ID | <[email protected]> |
The branch main has been updated by vladlen: URL: https://cgit.FreeBSD.org/doc/commit/?id=2beeeacdb81796f293bd980f30047b8a4bb76c35 commit 2beeeacdb81796f293bd980f30047b8a4bb76c35 Author: Vladlen Popolitov <[email protected]> AuthorDate: 2025-10-13 20:44:58 +0000 Commit: Vladlen Popolitov <[email protected]> CommitDate: 2025-10-13 20:44:58 +0000 update translation of articles/linux-emulation to Russian Reviewed by: andy Differential Revision: https://reviews.freebsd.org/D51965 --- .../ru/articles/linux-emulation/_index.adoc | 973 +++++ .../content/ru/articles/linux-emulation/_index.po | 4415 ++++++++++++++++++++ 2 files changed, 5388 insertions(+) diff --git a/documentation/content/ru/articles/linux-emulation/_index.adoc b/documentation/content/ru/articles/linux-emulation/_index.adoc new file mode 100644 index 0000000000..9d60209b00 --- /dev/null +++ b/documentation/content/ru/articles/linux-emulation/_index.adoc @@ -0,0 +1,973 @@ +--- +authors: + - + author: 'Roman Divacky' + email: [email protected] +description: 'Ð¢ÐµÑ Ð½Ð¸ÑеÑкое опиÑание внÑÑÑеннего ÑÑÑÑойÑÑва ÑÐ»Ð¾Ñ ÑмÑлÑÑии Linux в FreeBSD' +tags: ["Emulation", "Linuxulator", "kernel", "FreeBSD"] +title: 'ÐмÑлÑÑÐ¸Ñ Linux® в FreeBSD' +trademarks: ["freebsd", "ibm", "adobe", "netbsd", "realnetworks", "oracle", "linux", "sun", "general"] +--- + += ÐмÑлÑÑÐ¸Ñ Linux(R) в FreeBSD +:doctype: article +:toc: macro +:toclevels: 1 +:icons: font +:sectnums: +:sectnumlevels: 6 +:source-highlighter: rouge +:experimental: +:images-path: articles/linux-emulation/ + +ifdef::env-beastie[] +ifdef::backend-html5[] +include::shared/authors.adoc[] +include::shared/mirrors.adoc[] +include::shared/releases.adoc[] +include::shared/attributes/attributes-{{% lang %}}.adoc[] +include::shared/{{% lang %}}/teams.adoc[] +include::shared/{{% lang %}}/mailing-lists.adoc[] +include::shared/{{% lang %}}/urls.adoc[] +:imagesdir: ../../../images/{images-path} +endif::[] +ifdef::backend-pdf,backend-epub3[] +include::../../../../shared/asciidoctor.adoc[] +endif::[] +endif::[] + +ifndef::env-beastie[] +include::../../../../../shared/asciidoctor.adoc[] +endif::[] + +[.abstract-title] +ÐнноÑаÑÐ¸Ñ + +ÐÑа магиÑÑеÑÑÐºÐ°Ñ Ð´Ð¸ÑÑеÑÑаÑÐ¸Ñ Ð¿Ð¾ÑвÑÑена Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑÐ»Ð¾Ñ ÑмÑлÑÑии Linux(R) (Ñак назÑваемого _Linuxulator_). ÐадаÑа ÑоÑÑоÑла в обновлении ÑÐ»Ð¾Ñ Ð´Ð»Ñ ÑооÑвеÑÑÑÐ²Ð¸Ñ ÑÑнкÑионалÑноÑÑи Linux(R) 2.6. РкаÑеÑÑве ÑÑалонной ÑеализаÑии бÑло вÑбÑано ÑдÑо Linux(R) 2.6.16. ÐонÑепÑÐ¸Ñ Ð¾Ñнована на ÑеализаÑии NetBSD. ÐолÑÑÐ°Ñ ÑаÑÑÑ ÑабоÑÑ Ð±Ñла вÑполнена леÑом 2006 года в ÑÐ°Ð¼ÐºÐ°Ñ Ð¿ÑогÑÐ°Ð¼Ð¼Ñ Google Summer of Code Ð´Ð»Ñ ÑÑÑденÑов. ÐÑновное внимание ÑделÑлоÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑжки _NPTL_ (новой библио Ñеки поÑоков POSIX(R)) в Ñлой ÑмÑлÑÑии, вклÑÑÐ°Ñ _TLS_ (локалÑное Ñ ÑанилиÑе поÑоков), _ÑÑÑÑекÑÑ (futex)_ (бÑÑÑÑÑе мÑÑÑÐµÐºÑ Ñ Ð² полÑзоваÑелÑÑком пÑоÑÑÑанÑÑве), _PID mangling_ и некоÑоÑÑе дÑÑгие вÑоÑоÑÑепеннÑе аÑпекÑÑ. РпÑоÑеÑÑе бÑло вÑÑвлено и иÑпÑавлено множеÑÑво Ð¼ÐµÐ»ÐºÐ¸Ñ Ð¿Ñоблем. ÐÐ¾Ñ ÑабоÑа бÑла инÑегÑиÑована в оÑновной ÑепозиÑоÑий иÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ кода FreeBSD и Ð²Ð¾Ð¹Ð´ÐµÑ Ð² пÑедÑÑоÑÑий Ñелиз 7.0R. ÐÑ, команда ÑазÑабоÑÑиков ÑмÑлÑÑии, ÑабоÑаем над Ñем, ÑÑÐ¾Ð±Ñ ÑделаÑÑ ÑмÑлÑÑÐ¸Ñ Linux(R) 2.6 ÑÑандаÑÑнÑм Ñлоем ÑмÑлÑÑии в FreeBSD. + +''' + +toc::[] + +[[intro]] +== Ðведение + +РпоÑледние неÑколÑко Ð»ÐµÑ Ð¾Ð¿ÐµÑаÑионнÑе ÑиÑÑÐµÐ¼Ñ Ñ Ð¾ÑкÑÑÑÑм иÑÑ Ð¾Ð´Ð½Ñм кодом на оÑнове UNIX(R) наÑали ÑиÑоко иÑполÑзоваÑÑÑÑ Ð½Ð° ÑеÑвеÑнÑÑ Ð¸ клиенÑÑÐºÐ¸Ñ Ð¼Ð°ÑÐ¸Ð½Ð°Ñ . СÑеди ÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑионнÑÑ ÑиÑÑем Ñ Ñ Ð¾Ñел Ð±Ñ Ð²ÑделиÑÑ Ð´Ð²Ðµ: FreeBSD â за наÑледие BSD, пÑовеÑеннÑÑ Ð²Ñеменем ÐºÐ¾Ð´Ð¾Ð±Ð°Ð·Ñ Ð¸ множеÑÑво инÑеÑеÑнÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑей, и Linux(R) â за ÑиÑокÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑкÑÑ Ð±Ð°Ð·Ñ, акÑивное ÑообÑеÑÑво ÑазÑабоÑÑиков и поддеÑÐ¶ÐºÑ ÐºÑÑпнÑÑ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ð¹. FreeBSD ÑаÑе иÑполÑзÑеÑÑÑ Ð½Ð° ÑÐµÑ Ð²ÐµÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ð°Ñ , вÑполнÑÑÑÐ¸Ñ ÑложнÑе ÑеÑевÑе задаÑи, и Ñеже â на наÑÑолÑнÑÑ ÐºÐ¾Ð¼Ð¿ÑÑÑеÑÐ°Ñ Ð¾Ð±ÑÑнÑÑ Ð¿Ð¾Ð»ÑзоваÑеР»ÐµÐ¹. Ð Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº Linux(R) Ñакже пÑименÑеÑÑÑ Ð½Ð° ÑеÑвеÑÐ°Ñ , он гоÑаздо попÑлÑÑнее ÑÑеди домаÑÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑзоваÑелей. ÐÑо пÑÐ¸Ð²Ð¾Ð´Ð¸Ñ Ðº ÑиÑÑаÑии, когда Ð´Ð»Ñ Linux(R) доÑÑÑпно множеÑÑво пÑопÑиеÑаÑнÑÑ Ð¿ÑогÑамм, коÑоÑÑе не поддеÑживаÑÑ FreeBSD. + +ÐÑÑеÑÑвенно, Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑÑ Ð² возможноÑÑи запÑÑка Linux(R) бинаÑников в ÑиÑÑеме FreeBSD, и именно ÑÑÐ¾Ð¼Ñ Ð¿Ð¾ÑвÑÑена Ð´Ð°Ð½Ð½Ð°Ñ ÑабоÑа: ÑмÑлÑÑии ÑдÑа Linux(R) в опеÑаÑионной ÑиÑÑеме FreeBSD. + +ÐеÑом 2006 года ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Google Inc. ÑпонÑиÑовала пÑоекÑ, напÑавленнÑй на ÑаÑÑиÑение ÑÐ»Ð¾Ñ ÑмÑлÑÑии Linux(R) (Ñак назÑваемого Linuxulator) в FreeBSD Ð´Ð»Ñ Ð²ÐºÐ»ÑÑÐµÐ½Ð¸Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑей Linux(R) 2.6. ÐÐ°Ð½Ð½Ð°Ñ Ð´Ð¸ÑÑеÑÑаÑÐ¸Ñ Ð½Ð°Ð¿Ð¸Ñана в ÑÐ°Ð¼ÐºÐ°Ñ ÑÑого пÑоекÑа. + +[[inside]] +== ÐзглÑд изнÑÑÑи... + +Ð ÑÑом Ñазделе Ð¼Ñ ÑаÑÑмоÑÑим каждÑÑ Ð¸Ð· ÑаÑÑмаÑÑиваемÑÑ Ð¾Ð¿ÐµÑаÑионнÑÑ ÑиÑÑем. Ðак они ÑабоÑаÑÑ Ñ ÑиÑÑемнÑми вÑзовами, ÑÑеймами пÑеÑÑваний и дÑÑгими низкоÑÑовневÑми аÑпекÑами. Также Ð¼Ñ Ð¾Ð¿Ð¸Ñем, как они инÑеÑпÑеÑиÑÑÑÑ Ð¾Ð±Ñие пÑимиÑÐ¸Ð²Ñ UNIX(R), Ñакие как PID, поÑоки и Ñ. д. Ð ÑÑеÑÑем подÑазделе Ð¼Ñ Ð¿Ð¾Ð³Ð¾Ð²Ð¾Ñим о Ñом, как в Ñелом Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñеализована ÑмÑлÑÑÐ¸Ñ UNIX(R) на UNIX(R). + +[[what-is-unix]] +=== ЧÑо Ñакое UNIX(R) + +UNIX(R) â ÑÑо опеÑаÑÐ¸Ð¾Ð½Ð½Ð°Ñ ÑиÑÑема Ñ Ð´Ð¾Ð»Ð³Ð¾Ð¹ иÑÑоÑией, коÑоÑÐ°Ñ Ð¿Ð¾Ð²Ð»Ð¸Ñла поÑÑи на вÑе оÑÑалÑнÑе опеÑаÑионнÑе ÑиÑÑемÑ, иÑполÑзÑемÑе в наÑÑоÑÑее вÑемÑ. ÐаÑÐ¸Ð½Ð°Ñ Ñ 1960-Ñ Ð³Ð¾Ð´Ð¾Ð², ÐµÑ ÑазÑабоÑка пÑодолжаеÑÑÑ Ð¸ по Ñей Ð´ÐµÐ½Ñ (Ñ Ð¾ÑÑ Ð² ÑазнÑÑ Ð¿ÑоекÑÐ°Ñ ). ÐÑкоÑе ÑазвиÑие UNIX(R) ÑазделилоÑÑ Ð½Ð° два оÑновнÑÑ Ð½Ð°Ð¿ÑавлениÑ: ÑемейÑÑва BSD и System III/V. Ðни взаимно влиÑли дÑÑг на дÑÑга, ÑоÑмиÑÑÑ Ð¾Ð±Ñий ÑÑандаÑÑ UNIX(R). СÑеди вклада, возникÑего в BSD, можно назваÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¿ амÑÑÑ, ÑеÑевой ÑÑек TCP/IP, FFS и многие дÑÑгие. ÐеÑка System V внеÑла Ñвой вклад в пÑимиÑÐ¸Ð²Ñ Ð¼ÐµÐ¶Ð¿ÑоÑеÑÑного взаимоде йÑÑÐ²Ð¸Ñ SysV, копиÑование пÑи запиÑи и Ñ. д. Самого UNIX(R) болÑÑе не ÑÑÑеÑÑвÑеÑ, но его идеи бÑли иÑполÑÐ·Ð¾Ð²Ð°Ð½Ñ Ð¼Ð½Ð¾Ð³Ð¸Ð¼Ð¸ дÑÑгими опеÑаÑионнÑми ÑиÑÑемами по вÑÐµÐ¼Ñ Ð¼Ð¸ÑÑ, обÑазовав Ñак назÑваемÑе UNIX(R)-подобнÑе опеÑаÑионнÑе ÑиÑÑемÑ. РнаÑи дни наиболее влиÑÑелÑнÑми из Ð½Ð¸Ñ ÑвлÑÑÑÑÑ Linux(R), Solaris и, возможно (в некоÑоÑой ÑÑепени), FreeBSD. СÑÑеÑÑвÑÑÑ ÐºÐ¾ÑпоÑаÑивнÑе пÑоизводнÑе UNIX(R) (AIX, HP-UX и Ñ. д.), но они вÑÑ Ð±Ð¾Ð»ÑÑе мигÑиÑÑÑÑ Ð½Ð° ÑпомÑнÑÑÑе ÑиÑÑемÑ. ÐавайÑе поР´Ð²ÐµÐ´Ñм иÑог ÑипиÑнÑм Ñ Ð°ÑакÑеÑиÑÑикам UNIX(R). + +[[tech-details]] +=== Ð¢ÐµÑ Ð½Ð¸ÑеÑкие деÑали + +ÐÐ°Ð¶Ð´Ð°Ñ Ð·Ð°Ð¿ÑÑÐµÐ½Ð½Ð°Ñ Ð¿ÑогÑамма пÑедÑÑавлÑÐµÑ Ñобой пÑоÑеÑÑ, коÑоÑÑй оÑÑÐ°Ð¶Ð°ÐµÑ ÑоÑÑоÑние вÑÑиÑлений. ÐÑполнÑÑÑийÑÑ Ð¿ÑоÑеÑÑ ÑазделÑеÑÑÑ Ð¼ÐµÐ¶Ð´Ñ Ð¿ÑоÑÑÑанÑÑвом ÑдÑа и полÑзоваÑелÑÑким пÑоÑÑÑанÑÑвом. ÐекоÑоÑÑе опеÑаÑии могÑÑ Ð²ÑполнÑÑÑÑÑ ÑолÑко из пÑоÑÑÑанÑÑва ÑдÑа (напÑимеÑ, ÑабоÑа Ñ Ð¾Ð±Ð¾ÑÑдованием), но пÑоÑеÑÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ пÑоводиÑÑ Ð±Ð¾Ð»ÑÑÑÑ ÑаÑÑÑ Ñвоего вÑемени в полÑзоваÑелÑÑком пÑоÑÑÑанÑÑве. ЯдÑо â ÑÑо меÑÑо, где пÑоиÑÑ Ð¾Ð´Ð¸Ñ ÑпÑавление пÑоÑе ÑÑами, обоÑÑдованием и низкоÑÑовневÑми деÑалÑми. ЯдÑо пÑедоÑÑавлÑÐµÑ ÑÑандаÑÑнÑй ÑниÑиÑиÑованнÑй UNIX(R) API Ð´Ð»Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑкого пÑоÑÑÑанÑÑва. Ðаиболее важнÑе из Ð½Ð¸Ñ ÑаÑÑмоÑÑÐµÐ½Ñ Ð½Ð¸Ð¶Ðµ. + +[[kern-proc-comm]] +==== Ðбмен даннÑми Ð¼ÐµÐ¶Ð´Ñ ÑдÑом и полÑзоваÑелÑÑким пÑоÑеÑÑом + +ÐбÑий API UNIX(R) опÑеделÑÐµÑ ÑиÑÑемнÑй вÑзов как ÑпоÑоб пеÑедаÑи команд из полÑзоваÑелÑÑкого пÑоÑеÑÑа ÑдÑÑ. Ðаиболее ÑаÑпÑоÑÑÑанÑÐ½Ð½Ð°Ñ ÑеализаÑÐ¸Ñ Ð¸ÑполÑзÑÐµÑ Ð»Ð¸Ð±Ð¾ пÑеÑÑвание, либо ÑпеÑиализиÑованнÑÑ Ð¸Ð½ÑÑÑÑкÑÐ¸Ñ (напÑимеÑ, инÑÑÑÑкÑии `SYSENTER`/`SYSCALL` Ð´Ð»Ñ ia32). СиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ Ð¾Ð¿ÑеделÑÑÑÑÑ Ð¿Ð¾ номеÑÑ. ÐапÑимеÑ, в FreeBSD ÑиÑÑемнÑй вÑзов Ð½Ð¾Ð¼ÐµÑ 85 â ÑÑо man:swapon[2], а Ð½Ð¾Ð¼ÐµÑ 132 â man:mkfifo[2]. ÐекоÑоÑÑе ÑиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ ÑÑебÑÑÑ Ð¿Ð°ÑамеÑÑов, коÑоÑÑе пеÑедаÑÑÑÑ Ð¸Ð· п олÑзоваÑелÑÑкого пÑоÑÑÑанÑÑва в пÑоÑÑÑанÑÑво ÑдÑа ÑазлиÑнÑми ÑпоÑобами (завиÑÐ¸Ñ Ð¾Ñ ÑеализаÑии). СиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ ÑвлÑÑÑÑÑ ÑÐ¸Ð½Ñ ÑоннÑми. + +ÐÑе один возможнÑй ÑпоÑоб взаимодейÑÑÐ²Ð¸Ñ â иÑполÑзование _пÑеÑÑваниÑ_. ÐÑеÑÑÐ²Ð°Ð½Ð¸Ñ Ð¿ÑоиÑÑ Ð¾Ð´ÑÑ Ð°ÑÐ¸Ð½Ñ Ñонно поÑле Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ Ð¾Ð¿Ñеделенного ÑобÑÑÐ¸Ñ (деление на нолÑ, оÑибка ÑÑÑаниÑÑ Ð¸ Ñ.д.). ÐÑеÑÑвание Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑозÑаÑнÑм Ð´Ð»Ñ Ð¿ÑоÑеÑÑа (оÑибка ÑÑÑаниÑÑ) или пÑивеÑÑи к ÑеакÑии, напÑимеÑ, оÑпÑавке _Ñигнала_ (деление на нолÑ). + +[[proc-proc-comm]] +==== Ðбмен даннÑми Ð¼ÐµÐ¶Ð´Ñ Ð¿ÑоÑеÑÑами + +СÑÑеÑÑвÑÑÑ Ð´ÑÑгие API (System V IPC, ÑазделÑÐµÐ¼Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ Ð¸ Ñ.д.), но наиболее важнÑм API ÑвлÑÑÑÑÑ ÑигналÑ. Ð¡Ð¸Ð³Ð½Ð°Ð»Ñ Ð¾ÑпÑавлÑÑÑÑÑ Ð¿ÑоÑеÑÑами или ÑдÑом и пÑинимаÑÑÑÑ Ð¿ÑоÑеÑÑами. ÐекоÑоÑÑе ÑÐ¸Ð³Ð½Ð°Ð»Ñ Ð¼Ð¾Ð³ÑÑ Ð±ÑÑÑ Ð¿ÑоигноÑиÑÐ¾Ð²Ð°Ð½Ñ Ð¸Ð»Ð¸ обÑабоÑÐ°Ð½Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑкой пÑоÑедÑÑой, дÑÑгие пÑиводÑÑ Ðº пÑедопÑеделÑÐ½Ð½Ð¾Ð¼Ñ Ð´ÐµÐ¹ÑÑвиÑ, коÑоÑое нелÑÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ Ð¸Ð»Ð¸ игноÑиÑоваÑÑ. + +[[proc-mgmt]] +==== УпÑавление пÑоÑеÑÑами + +ÐÑоÑеÑÑÑ ÑдÑа обÑабаÑÑваÑÑÑÑ Ð¿ÐµÑвÑми в ÑиÑÑеме (Ñак назÑваемÑй init). ÐаждÑй запÑÑеннÑй пÑоÑеÑÑ Ð¼Ð¾Ð¶ÐµÑ ÑоздаÑÑ ÑÐ²Ð¾Ñ Ð¸Ð´ÐµÐ½ÑиÑнÑÑ ÐºÐ¾Ð¿Ð¸Ñ, иÑполÑзÑÑ ÑиÑÑемнÑй вÑзов man:fork[2]. ÐÑли Ð²Ð²ÐµÐ´ÐµÐ½Ñ Ð½ÐµÐºÐ¾ÑоÑÑе немного изменÑннÑе веÑÑии ÑÑого ÑиÑÑемного вÑзова, но Ð±Ð°Ð·Ð¾Ð²Ð°Ñ ÑеманÑика оÑÑаÑÑÑÑ Ñой же. ÐаждÑй запÑÑеннÑй пÑоÑеÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑевÑаÑиÑÑÑÑ Ð² дÑÑгой пÑоÑеÑÑ, иÑполÑзÑÑ ÑиÑÑемнÑй вÑзов man:exec[3]. ÐÑли Ð²Ð²ÐµÐ´ÐµÐ½Ñ Ð½ÐµÐºÐ¾ÑоÑÑе модиÑикаÑии ÑÑого ÑиÑÑемного вÑзова , но вÑе они ÑлÑÐ¶Ð°Ñ Ð¾Ð´Ð½Ð¾Ð¹ и Ñой же базовой Ñели. ÐÑоÑеÑÑÑ Ð·Ð°Ð²ÐµÑÑаÑÑ ÑÐ²Ð¾Ñ ÑÑÑеÑÑвование, вÑзÑÐ²Ð°Ñ ÑиÑÑемнÑй вÑз ов man:exit[2]. ÐаждÑй пÑоÑеÑÑ Ð¸Ð´ÐµÐ½ÑиÑиÑиÑÑеÑÑÑ ÑникалÑнÑм номеÑом, назÑваемÑм PID. У каждого пÑоÑеÑÑа еÑÑÑ Ð¾Ð¿ÑеделÑннÑй ÑодиÑÐµÐ»Ñ (иденÑиÑиÑиÑÑемÑй его PID). + +[[thread-mgmt]] +==== УпÑавление поÑоками + +ТÑадиÑионнÑй UNIX(R) не опÑеделÑÐµÑ Ð½Ð¸ÐºÐ°ÐºÐ¾Ð³Ð¾ API или ÑеализаÑии Ð´Ð»Ñ Ð¿Ð¾Ñоков, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº POSIX(R) опÑеделÑÐµÑ Ñвой API Ð´Ð»Ñ Ð¿Ð¾Ñоков, но ÑеализаÑÐ¸Ñ Ð¾ÑÑаеÑÑÑ Ð½ÐµÐ¾Ð¿Ñеделенной. ТÑадиÑионно ÑÑÑеÑÑвовало два ÑпоÑоба ÑеализаÑии поÑоков: обÑабоÑка Ð¸Ñ ÐºÐ°Ðº оÑделÑнÑÑ Ð¿ÑоÑеÑÑов (поÑоки 1:1) или обеÑÑÑвание вÑей гÑÑÐ¿Ð¿Ñ Ð¿Ð¾Ñоков в один пÑоÑеÑÑ Ñ ÑпÑавлением поÑоками в полÑзоваÑелÑÑком пÑоÑÑÑанÑÑве (поÑоки 1:N). СÑавнение оÑновнÑÑ Ð¾ÑобенноÑÑей каждого Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð° : + +ÐоÑоки 1:1 + +- ÑÑжеловеÑнÑе поÑоки +- планиÑование не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¾ полÑзоваÑелем (ÑаÑÑиÑно ÑмÑгÑено + благодаÑÑ POSIX(R) API) ++ Ð½ÐµÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи в обÑÑÑке ÑиÑÑемнÑÑ Ð²Ñзовов ++ Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑ Ð½ÐµÑколÑко пÑоÑеÑÑоÑов + +ÐоÑоки 1:N + ++ легковеÑнÑе поÑоки ++ планиÑование Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð»ÐµÐ³ÐºÐ¾ изменено полÑзоваÑелем +- СиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¾Ð±ÐµÑнÑÑÑ +- не Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑ Ð±Ð¾Ð»ÐµÐµ одного CPU + +[[what-is-freebsd]] +=== ЧÑо Ñакое FreeBSD? + +ÐÑÐ¾ÐµÐºÑ FreeBSD â одна из ÑÑаÑейÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑионнÑÑ ÑиÑÑем Ñ Ð¾ÑкÑÑÑÑм иÑÑ Ð¾Ð´Ð½Ñм кодом, доÑÑÑпнÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð²Ñедневного иÑполÑзованиÑ. Ðна ÑвлÑеÑÑÑ Ð¿ÑÑмÑм поÑомком оÑигиналÑной UNIX(R), поÑÑÐ¾Ð¼Ñ Ð¼Ð¾Ð¶Ð½Ð¾ ÑÑвеÑждаÑÑ, ÑÑо ÑÑо наÑÑоÑÑÐ°Ñ UNIX(R), Ñ Ð¾ÑÑ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñ Ð»Ð¸ÑензиÑованием не позволÑÑÑ ÑÑого ÑделаÑÑ. ÐаÑало пÑоекÑа оÑноÑиÑÑÑ Ðº наÑÐ°Ð»Ñ 1990-Ñ Ð³Ð¾Ð´Ð¾Ð², когда гÑÑппа полÑзоваÑелей BSD Ñоздала Ð½Ð°Ð±Ð¾Ñ Ð¸ÑпÑавлений Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ 386BSD. Ðа оÑнове ÑÑого набоÑа возникла Ð½Ð¾Ð²Ð°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ð¾Ð½Ð½Ð°Ñ ÑиÑÑема под названием FreeBSD, полÑÑивÑÐ°Ñ ÑÐ²Ð¾Ñ Ð¸Ð¼Ñ Ð±Ð»Ð°Ð³Ð¾Ð´Ð°ÑÑ Ð»Ð¸Ð±ÐµÑалÑной лиÑензии . ÐÑÑÐ³Ð°Ñ Ð³ÑÑппа Ñоздала опеÑаÑионнÑÑ ÑиÑÑÐµÐ¼Ñ NetBSD Ñ Ð´ÑÑгими ÑелÑми. ÐÑ ÑоÑÑедоÑоÑимÑÑ Ð½Ð° FreeBSD. + +FreeBSD â ÑÑо ÑовÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ð¾Ð½Ð½Ð°Ñ ÑиÑÑема на оÑнове UNIX(R), обладаÑÑÐ°Ñ Ð²Ñеми возможноÑÑÑми UNIX(R). ÐÑÑеÑнÑÑÑÐ°Ñ Ð¼Ð½Ð¾Ð³Ð¾Ð·Ð°Ð´Ð°ÑноÑÑÑ, многополÑзоваÑелÑÑкие ÑÑнкÑии, ÑеÑевÑе возможноÑÑи TCP/IP, заÑиÑа памÑÑи, поддеÑжка ÑиммеÑÑиÑной многопÑоÑеÑÑоÑноÑÑи, виÑÑÑалÑÐ½Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ Ñ Ð¾Ð±ÑединÑннÑми VM и кÑÑем бÑÑеÑа â вÑÑ ÑÑо пÑиÑÑÑÑÑвÑеÑ. Ðдной из инÑеÑеÑнÑÑ Ð¸ ÑÑезвÑÑайно полезнÑÑ Ð¾ÑобенноÑÑей ÑвлÑеÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ ÑмÑлÑÑии дÑÑÐ³Ð¸Ñ UNIX(R)-подобнÑÑ Ð¾Ð¿ÐµÑÐ°Ñ Ð¸Ð¾Ð½Ð½ÑÑ ÑиÑÑем. Ðо ÑоÑÑоÑÐ½Ð¸Ñ Ð½Ð° декабÑÑ 2006 года и ÑазÑабоÑÐºÑ 7-CURRENT поддеÑживаÑÑÑÑ ÑледÑÑÑие ÑÑнкÑии ÑмÑлÑÑиР¸: + +* СовмеÑÑимоÑÑÑ FreeBSD/i386 на FreeBSD/amd64 +* FreeBSD/i386 ÑмÑлÑÑÐ¸Ñ Ð½Ð° FreeBSD/ia64 +* ÐмÑлÑÑÐ¸Ñ Linux(R) опеÑаÑионной ÑиÑÑÐµÐ¼Ñ Linux(R) на FreeBSD +* NDIS-ÑмÑлÑÑÐ¸Ñ Ð¸Ð½ÑеÑÑейÑа ÑеÑевÑÑ Ð´ÑайвеÑов Windows +* NetBSD-ÑмÑлÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ NetBSD +* ÐоддеÑжка PECoff Ð´Ð»Ñ Ð¸ÑполнÑемÑÑ Ñайлов FreeBSD в ÑоÑмаÑе PECoff +* ÐмÑлÑÑÐ¸Ñ SVR4 System V revision 4 UNIX(R) + +ÐкÑивно ÑазÑабаÑÑваемÑе ÑмÑлÑÑии â ÑÑо Ñлой Linux(R) и ÑазлиÑнÑе Ñлои FreeBSD-on-FreeBSD. ÐÑÑалÑнÑе в наÑÑоÑÑее вÑÐµÐ¼Ñ Ð½Ðµ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑабоÑаÑÑ ÐºÐ¾ÑÑекÑно или бÑÑÑ Ð¿ÑигоднÑми к иÑполÑзованиÑ. + +[[freebsd-tech-details]] +==== Ð¢ÐµÑ Ð½Ð¸ÑеÑкие деÑали + +FreeBSD â ÑÑо ÑÑадиÑионнÑй ваÑÐ¸Ð°Ð½Ñ UNIX(R) в ÑмÑÑле ÑÐ°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿ÑоÑеÑÑов на две ÑаÑÑи: вÑполнение в пÑоÑÑÑанÑÑве ÑдÑа и вÑполнение в пÑоÑÑÑанÑÑве полÑзоваÑелÑ. СÑÑеÑÑвÑÐµÑ Ð´Ð²Ð° Ñипа Ð²Ñ Ð¾Ð´Ð° пÑоÑеÑÑа в ÑдÑо: ÑиÑÑемнÑй вÑзов (syscall) и ловÑÑка (trap). ÐозвÑÐ°Ñ ÑолÑко один. РпоÑледÑÑÑÐ¸Ñ ÑÐ°Ð·Ð´ÐµÐ»Ð°Ñ Ð¼Ñ Ð¾Ð¿Ð¸Ñем ÑÑи Ð²Ñ Ð¾Ð´Ð°/вÑÑ Ð¾Ð´Ð° в/из ÑдÑа. ÐÑÑ Ð¾Ð¿Ð¸Ñание оÑноÑиÑÑÑ Ðº аÑÑ Ð¸ÑекÑÑÑе i386, Ñак как Linuxulator ÑÑÑеÑÑвÑÐµÑ ÑолÑко Ñам, но конÑепÑÐ¸Ñ ÑÑ Ð¾Ð¶Ð° на дÑÑÐ³Ð¸Ñ Ð°ÑÑ Ð ¸ÑекÑÑÑÐ°Ñ . ÐнÑоÑмаÑÐ¸Ñ Ð±Ñла взÑÑа из [1] и иÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ кода. + +[[freebsd-sys-entries]] +===== СиÑÑемнÑе запиÑи + +Ð FreeBSD ÑÑÑеÑÑвÑÐµÑ Ð°Ð±ÑÑÑакÑиÑ, назÑÐ²Ð°ÐµÐ¼Ð°Ñ Ð·Ð°Ð³ÑÑзÑиком клаÑÑов иÑполнениÑ, коÑоÑÐ°Ñ ÑвлÑеÑÑÑ Ð¿ÑоÑлойкой в ÑиÑÑемном вÑзове man:execve[2]. Ðна иÑполÑзÑÐµÑ ÑÑÑÑкÑÑÑÑ `sysentvec`, опиÑÑваÑÑÑÑ ABI иÑполнÑемого Ñайла. ÐÑа ÑÑÑÑкÑÑÑа ÑодеÑÐ¶Ð¸Ñ Ñакие ÑлеменÑÑ, как ÑаблиÑÑ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ errno, ÑаблиÑÑ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñигналов, ÑазлиÑнÑе ÑÑнкÑии Ð´Ð»Ñ Ð¾Ð±ÑабоÑки ÑиÑÑемнÑÑ Ð²Ñзовов (иÑпÑавление ÑÑека, Ñоздание дампов памÑÑи и Ñ.д.). ÐаждÑй ABI, коÑоÑÑй ÑдÑо FreeBSD подде ÑживаеÑ, должен опÑеделÑÑÑ ÑÑÑ ÑÑÑÑкÑÑÑÑ, Ñак как она иÑполÑзÑеÑÑÑ Ð² далÑнейÑем в коде обÑабоÑки ÑиÑÑемнÑÑ Ð ²Ñзовов и в некоÑоÑÑÑ Ð´ÑÑÐ³Ð¸Ñ Ð¼ÐµÑÑÐ°Ñ . СиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ Ð¾Ð±ÑабаÑÑваÑÑÑÑ Ð¾Ð±ÑабоÑÑиками пÑеÑÑваний, где можно одновÑеменно полÑÑиÑÑ Ð´Ð¾ÑÑÑп как к пÑоÑÑÑанÑÑÐ²Ñ ÑдÑа, Ñак и к полÑзоваÑелÑÑÐºÐ¾Ð¼Ñ Ð¿ÑоÑÑÑанÑÑвÑ. + +[[freebsd-syscalls]] +===== СиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ + +СиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ Ð² FreeBSD вÑполнÑÑÑÑÑ Ð¿ÑÑем пÑеÑÑÐ²Ð°Ð½Ð¸Ñ `0x80` Ñ ÑÑÑановленнÑм в ÑегиÑÑÑе `%eax` номеÑом нÑжного ÑиÑÑемного вÑзова и аÑгÑменÑами, пеÑеданнÑми ÑеÑез ÑÑек. + +Ðогда пÑоÑеÑÑ Ð²ÑзÑÐ²Ð°ÐµÑ Ð¿ÑеÑÑвание `0x80`, ÑÑабаÑÑÐ²Ð°ÐµÑ Ð¾Ð±ÑабоÑÑик ÑиÑÑемного вÑзова `int0x80` (опÑеделÑннÑй в [.filename]#sys/i386/i386/exception.s#), коÑоÑÑй подгоÑÐ°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð°ÑгÑменÑÑ (Ñ.е. копиÑÑÐµÑ Ð¸Ñ Ð² ÑÑек) Ð´Ð»Ñ Ð²Ñзова ÑÑнкÑии на ÑзÑке C man:syscall[2] (опÑеделÑнной в [.filename]#sys/i386/i386/trap.c#), обÑабаÑÑваÑÑей пеÑеданнÑй ÑÑейм пÑеÑÑваниÑ. ÐбÑабоÑка вклÑÑÐ°ÐµÑ Ð¿Ð¾Ð´Ð³Ð¾ÑÐ¾Ð²ÐºÑ ÑиÑÑемного вÑзова (в завиÑимоÑÑи Ð¾Ñ Ð·Ð°Ð¿Ð¸Ñи `sysvec`), опÑеделение ÑазÑÑдноÑÑи ÑиÑÑемного вÑзова (32-биÑнÑй иР»Ð¸ 64-биÑнÑй, ÑÑо влиÑÐµÑ Ð½Ð° ÑÐ°Ð·Ð¼ÐµÑ Ð¿Ð°ÑамеÑÑов), поÑле Ñего паÑамеÑÑÑ ÐºÐ¾Ð¿Ð¸ÑÑÑÑÑÑ, вклÑÑÐ°Ñ Ñам ÑиÑÑемнÑй вÑзов. РаÑем вÑполнÑеÑÑÑ ÑакÑиÑеÑÐºÐ°Ñ ÑÑнкÑÐ¸Ñ ÑиÑÑемного вÑзова Ñ Ð¾Ð±ÑабоÑкой кода возвÑаÑа (оÑобÑе ÑлÑÑаи Ð´Ð»Ñ Ð¾Ñибок `ERESTART` и `EJUSTRETURN`). РзавеÑÑение планиÑÑеÑÑÑ Ð²Ñзов `userret()`, возвÑаÑаÑÑий пÑоÑеÑÑ Ð² полÑзоваÑелÑÑкое пÑоÑÑÑанÑÑво. ÐаÑамеÑÑÑ Ð´Ð»Ñ ÑакÑиÑеÑкого обÑабоÑÑика ÑиÑÑемного вÑзова пеÑедаÑÑÑÑ Ð² виде аÑгÑменÑов `struct thread *td`, `struct syscall args *`, где вÑоÑой паÑамеÑÑ ÑвлÑеÑÑÑ ÑказаÑелем на ÑкопиÑованнÑÑ ÑÑÑÑкÑÑÑÑ Ð¿Ð°ÑамеÑÑов. + +[[freebsd-traps]] +===== ÐовÑÑки (trap) + +ÐбÑабоÑка ловÑÑек в FreeBSD аналогиÑна обÑабоÑке ÑиÑÑемнÑÑ Ð²Ñзовов. ÐÑи возникновении ловÑÑки вÑзÑваеÑÑÑ Ð¾Ð±ÑабоÑÑик на аÑÑемблеÑе. Ðн вÑбиÑаеÑÑÑ Ð¼ÐµÐ¶Ð´Ñ `alltraps`, `alltraps` Ñ ÑÐ¾Ñ Ñанением ÑегиÑÑÑов или `calltrap` в завиÑимоÑÑи Ð¾Ñ Ñипа ловÑÑки. ÐÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик подгоÑÐ°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð°ÑгÑменÑÑ Ð´Ð»Ñ Ð²Ñзова ÑÑнкÑии на ÑзÑке C `trap()` (опÑеделена в [.filename]#sys/i386/i386/trap.c#), коÑоÑÐ°Ñ Ð·Ð°Ñем обÑабаÑÑÐ²Ð°ÐµÑ Ð¿ÑоизоÑедÑÑÑ Ð»Ð¾Ð²ÑÑкÑ. ÐоÑле обÑабоÑки она Ð¼Ð¾Ð¶ÐµÑ Ð¾ÑпÑавиÑÑ Ñигнал пÑоÑÐ µÑÑÑ Ð¸/или веÑнÑÑÑÑÑ Ð² полÑзоваÑелÑÑкое пÑоÑÑÑанÑÑво Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ `userret()`. + +[[freebsd-exits]] +===== ÐÑÑ Ð¾Ð´Ñ + +ÐÑÑ Ð¾Ð´ из ÑдÑа в полÑзоваÑелÑÑкое пÑоÑÑÑанÑÑво пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ñ Ð¸ÑполÑзованием аÑÑемблеÑной пÑоÑедÑÑÑ `doreti`, незавиÑимо Ð¾Ñ Ñого, бÑло ли ÑдÑо вÑзвано ÑеÑез ловÑÑÐºÑ Ð¸Ð»Ð¸ ÑеÑез ÑиÑÑемнÑй вÑзов. ÐÑо воÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑоÑÑоÑние пÑогÑÐ°Ð¼Ð¼Ñ Ð¸Ð· ÑÑека и возвÑаÑÐ°ÐµÑ ÑпÑавление в полÑзоваÑелÑÑкое пÑоÑÑÑанÑÑво. + +[[freebsd-unix-primitives]] +===== ÐÑимиÑÐ¸Ð²Ñ UNIX(R) + +ÐпеÑаÑÐ¸Ð¾Ð½Ð½Ð°Ñ ÑиÑÑема FreeBSD пÑидеÑживаеÑÑÑ ÑÑадиÑионной ÑÑ ÐµÐ¼Ñ UNIX(R), где каждÑй пÑоÑеÑÑ Ð¸Ð¼ÐµÐµÑ ÑникалÑнÑй иденÑиÑикаÑионнÑй номеÑ, Ñак назÑваемÑй _PID_ (ÐденÑиÑикаÑÐ¾Ñ ÐÑоÑеÑÑа). ÐомеÑа PID вÑделÑÑÑÑÑ Ð»Ð¸Ð±Ð¾ линейно, либо ÑлÑÑайнÑм обÑазом в диапазоне Ð¾Ñ `0` до `PID_MAX`. РаÑпÑеделение номеÑов PID оÑÑÑеÑÑвлÑеÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð»Ð¸Ð½ÐµÐ¹Ð½Ð¾Ð³Ð¾ поиÑка в пÑоÑÑÑанÑÑве PID. ÐаждÑй поÑок в пÑоÑеÑÑе полÑÑÐ°ÐµÑ ÑÐ¾Ñ Ð¶Ðµ Ð½Ð¾Ð¼ÐµÑ PID в ÑезÑлÑÑаÑе вÑзова man:getpid[2]. + +РнаÑÑоÑÑее вÑÐµÐ¼Ñ Ð² FreeBSD ÑÑÑеÑÑвÑÐµÑ Ð´Ð²Ð° ÑпоÑоба ÑеализаÑии поÑоков. ÐеÑвÑй ÑпоÑоб â ÑÑо M:N поÑоки, за коÑоÑÑм ÑледÑÐµÑ Ð¼Ð¾Ð´ÐµÐ»Ñ Ð¿Ð¾Ñоков 1:1. Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð¸ÑполÑзÑеÑÑÑ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñека M:N (`libpthread`), но во вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ пеÑеклÑÑиÑÑÑÑ Ð½Ð° поÑоки 1:1 (`libthr`). ÐланиÑÑеÑÑÑ Ð² ближайÑее вÑÐµÐ¼Ñ Ð¿ÐµÑейÑи на библиоÑÐµÐºÑ 1:1 по ÑмолÑаниÑ. ХоÑÑ Ð¾Ð±Ðµ библиоÑеки иÑполÑзÑÑÑ Ð¾Ð´Ð½Ð¸ и Ñе же пÑимиÑÐ¸Ð²Ñ ÑдÑа, доÑÑÑп к ним оÑÑÑеÑÑвлÑеÑÑÑ ÑеÑез ÑазнÑе API. ÐиблиоÑека M:N иÑпР¾Ð»ÑзÑÐµÑ ÑемейÑÑво ÑиÑÑемнÑÑ Ð²Ñзовов `kse_*`, Ñогда как библиоÑека 1:1 иÑполÑзÑÐµÑ ÑемейÑÑво `thr_*`. Ðз-за ÑÑого оÑÑÑÑ ÑÑвÑÐµÑ Ð¾Ð±ÑÐ°Ñ ÐºÐ¾Ð½ÑепÑÐ¸Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑа поÑока, ÑазделÑÐµÐ¼Ð°Ñ Ð¼ÐµÐ¶Ð´Ñ ÑдÑом и полÑзоваÑелÑÑким пÑоÑÑÑанÑÑвом. ÐонеÑно, обе библиоÑеки ÑеализÑÑÑ API иденÑиÑикаÑоÑа поÑока pthread. У каждого поÑока ÑдÑа (как опиÑано в `struct thread`) еÑÑÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¾Ñ td tid, но он недоÑÑÑпен напÑÑмÑÑ Ð¸Ð· полÑзоваÑелÑÑкого пÑоÑÑÑанÑÑва и ÑлÑÐ¶Ð¸Ñ Ð¸ÑклÑÑиÑелÑно нÑждам ÑдÑа. Ðн Ñакже иÑполÑзÑеÑÑÑ Ð² библиоÑеке поÑоков 1:1 в каÑеÑÑве иденÑиÑикаÑоÑа поÑока pthread, но обÑабоÑка ÑÑого иденÑиÑикаÑоÑа внÑÑÑеннÑÑ Ð´Ð»Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñеки и не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ÑполÑзована напÑÑмÑÑ. + +Ðак ÑпоминалоÑÑ Ñанее, в FreeBSD ÑÑÑеÑÑвÑÑÑ Ð´Ð²Ðµ ÑеализаÑии поÑоков. ÐиблиоÑека M:N ÑазделÑÐµÑ ÑабоÑÑ Ð¼ÐµÐ¶Ð´Ñ Ð¿ÑоÑÑÑанÑÑвом ÑдÑа и полÑзоваÑелÑÑким пÑоÑÑÑанÑÑвом. ÐоÑок â ÑÑо ÑÑÑноÑÑÑ, коÑоÑÐ°Ñ Ð¿Ð»Ð°Ð½Ð¸ÑÑеÑÑÑ Ð² ÑдÑе, но Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑедÑÑавлÑÑÑ ÑазлиÑное колиÑеÑÑво полÑзоваÑелÑÑÐºÐ¸Ñ Ð¿Ð¾Ñоков. M полÑзоваÑелÑÑÐºÐ¸Ñ Ð¿Ð¾Ñоков оÑобÑажаÑÑÑÑ Ð½Ð° N поÑоков ÑдÑа, ÑÑо позволÑÐµÑ ÑкономиÑÑ ÑеÑÑÑÑÑ, ÑÐ¾Ñ ÑанÑÑ Ð¿Ñи ÑÑом возможноÑÑÑ Ð¸ÑполÑзоваÑÑ Ð¿ÑеимÑÑеÑÑва многопÑÐ¾Ñ ÐµÑÑоÑного паÑаллелизма. ÐополниÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ ÑеализаÑии можно полÑÑиÑÑ Ð¸Ð· man-ÑÑÑаниÑÑ Ð¸Ð»Ð¸ [1]. ÐÐ¸Ð±Ð»Ð¸Ð¾Ñ ÐµÐºÐ° 1:1 напÑÑмÑÑ Ð¾ÑобÑÐ°Ð¶Ð°ÐµÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑкий поÑок на поÑок ÑдÑа, ÑÑо знаÑиÑелÑно ÑпÑоÑÐ°ÐµÑ ÑÑ ÐµÐ¼Ñ. Ðи одна из ÑÑÐ¸Ñ ÑеализаÑий не вклÑÑÐ°ÐµÑ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼ ÑпÑаведливоÑÑи (Ñакой Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼ бÑл Ñеализован, но недавно ÑдалÑн, поÑколÑÐºÑ Ð²ÑзÑвал ÑеÑÑÑзное замедление и ÑÑложнÑл ÑабоÑÑ Ñ ÐºÐ¾Ð´Ð¾Ð¼). + +[[what-is-linux]] +=== ЧÑо Ñакое Linux(R) + +Linux(R) â ÑÑо UNIX(R)-подобное ÑдÑо, изнаÑалÑно ÑазÑабоÑанное ÐинÑÑом ТоÑвалÑдÑом, а ÑейÑÐ°Ñ Ñазвиваемое множеÑÑвом пÑогÑаммиÑÑов по вÑÐµÐ¼Ñ Ð¼Ð¸ÑÑ. ÐÑ ÑÐ²Ð¾Ð¸Ñ ÑкÑомнÑÑ Ð½Ð°Ñал до ÑегоднÑÑнего днÑ, пÑи ÑиÑокой поддеÑжке ÑÐ°ÐºÐ¸Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ð¹, как IBM или Google, Linux(R) аÑÑоÑииÑÑеÑÑÑ Ñ Ð±ÑÑÑÑÑм Ñемпом ÑазÑабоÑки, полной поддеÑжкой обоÑÑÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ моделÑÑ Ð¾ÑганизаÑии по пÑинÑÐ¸Ð¿Ñ "добÑожелаÑелÑного дикÑаÑоÑа". + +РазÑабоÑка Linux(R) наÑалаÑÑ Ð² 1991 Ð³Ð¾Ð´Ñ ÐºÐ°Ðº лÑбиÑелÑÑкий пÑÐ¾ÐµÐºÑ Ð² УнивеÑÑиÑеÑе ХелÑÑинки, ФинлÑндиÑ. С ÑÐµÑ Ð¿Ð¾Ñ Ð¾Ð½Ð° пÑиобÑела вÑе ÑеÑÑÑ ÑовÑеменной ÐС, подобной UNIX(R): многопÑоÑеÑÑоÑноÑÑÑ, поддеÑжка многополÑзоваÑелÑÑкого Ñежима, виÑÑÑалÑÐ½Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ, ÑеÑевое взаимодейÑÑвие â в обÑем, вÑÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾Ðµ. Также пÑиÑÑÑÑÑвÑÑÑ Ð²ÑÑокоÑÑовневÑе ÑÑнкÑии, Ñакие как виÑÑÑализаÑÐ¸Ñ Ð¸ Ñ. д. + +Ð 2006 Ð³Ð¾Ð´Ñ Linux(R), Ð¿Ð¾Ñ Ð¾Ð¶Ðµ, бÑл наиболее ÑиÑоко иÑполÑзÑемой оÑкÑÑÑой опеÑаÑионной ÑиÑÑемой Ñ Ð¿Ð¾Ð´Ð´ÐµÑжкой незавиÑимÑÑ Ð¿Ð¾ÑÑавÑиков пÑогÑаммного обеÑпеÑениÑ, ÑÐ°ÐºÐ¸Ñ ÐºÐ°Ðº Oracle, RealNetworks, Adobe и дÑÑÐ³Ð¸Ñ . ÐолÑÑÐ°Ñ ÑаÑÑÑ ÐºÐ¾Ð¼Ð¼ÐµÑÑеÑкого пÑогÑаммного обеÑпеÑениÑ, ÑаÑпÑоÑÑÑанÑемого Ð´Ð»Ñ Linux(R), доÑÑÑпна ÑолÑко в бинаÑном виде, поÑÑÐ¾Ð¼Ñ Ð¿ÐµÑекомпилÑÑÐ¸Ñ Ð´Ð»Ñ Ð´ÑÑÐ³Ð¸Ñ Ð¾Ð¿ÐµÑаÑионнÑÑ ÑиÑÑем невозможна. + +ÐолÑÑÐ°Ñ ÑаÑÑÑ ÑазÑабоÑки Linux(R) пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð² ÑиÑÑеме конÑÑÐ¾Ð»Ñ Ð²ÐµÑÑий Git. Git â ÑÑо ÑаÑпÑеделÑÐ½Ð½Ð°Ñ ÑиÑÑема, поÑÑÐ¾Ð¼Ñ Ð½ÐµÑ ÑенÑÑализованного иÑÑоÑника кода Linux(R), но некоÑоÑÑе веÑви ÑÑиÑаÑÑÑÑ Ð¾ÑновнÑми и оÑиÑиалÑнÑми. Ð¡Ñ ÐµÐ¼Ð° нÑмеÑаÑии веÑÑий, иÑполÑзÑÐµÐ¼Ð°Ñ Ð² Linux(R), ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· ÑеÑÑÑÑÑ ÑиÑел: A.B.C.D. РнаÑÑоÑÑее вÑÐµÐ¼Ñ ÑазÑабоÑка ведÑÑÑÑ Ð² веÑке 2.6.C.D, где C обознаÑÐ°ÐµÑ Ð¼Ð°Ð¶Ð¾ÑнÑÑ Ð²ÐµÑÑиÑ, в коÑоÑÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑÑÑ Ð¸Ð»Ð¸ изменÑÑÑÑÑ ÑÑнкÑии, а D â миноÑнÑÑ Ð²ÐµÑÑи Ñ, пÑедназнаÑеннÑÑ ÑолÑко Ð´Ð»Ñ Ð¸ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ñибок. + +ÐополниÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ полÑÑиÑÑ Ð¸Ð· [3]. + +[[linux-tech-details]] +==== Ð¢ÐµÑ Ð½Ð¸ÑеÑкие деÑали + +Linux(R) ÑледÑÐµÑ ÑÑадиÑионной ÑÑ ÐµÐ¼Ðµ UNIX(R), ÑазделÑÑ Ð²Ñполнение пÑоÑеÑÑа на две ÑаÑÑи: ÑдÑо и полÑзоваÑелÑÑкое пÑоÑÑÑанÑÑво. ЯдÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²Ñзвано двÑÐ¼Ñ ÑпоÑобами: ÑеÑез ловÑÑÐºÑ (trap) или ÑеÑез ÑиÑÑемнÑй вÑзов. ÐозвÑÐ°Ñ Ð¾ÑÑÑеÑÑвлÑеÑÑÑ ÑолÑко одним ÑпоÑобом. Ðалее опиÑание оÑноÑиÑÑÑ Ðº Linux(R) 2.6 на аÑÑ Ð¸ÑекÑÑÑе i386(TM). ÐÑа инÑоÑмаÑÐ¸Ñ Ð²Ð·ÑÑа из [2]. + +[[linux-syscalls]] +===== СиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ + +СиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ Ð² Linux(R) вÑполнÑÑÑÑÑ (в полÑзоваÑелÑÑком пÑоÑÑÑанÑÑве) Ñ Ð¸ÑполÑзованием макÑоÑов `syscallX`, где X заменÑеÑÑÑ ÑиÑлом, пÑедÑÑавлÑÑÑим колиÑеÑÑво паÑамеÑÑов данного ÑиÑÑемного вÑзова. ÐÑÐ¾Ñ Ð¼Ð°ÐºÑÐ¾Ñ Ð¿ÑеобÑазÑеÑÑÑ Ð² код, коÑоÑÑй загÑÑÐ¶Ð°ÐµÑ ÑегиÑÑÑ `%eax` номеÑом ÑиÑÑемного вÑзова и вÑполнÑÐµÑ Ð¿ÑеÑÑвание `0x80`. ÐоÑле ÑÑого вÑзÑваеÑÑÑ Ð²Ð¾Ð·Ð²ÑÐ°Ñ Ð¸Ð· ÑиÑÑемного вÑзова, коÑоÑÑй пÑеобÑазÑÐµÑ Ð¾ÑÑиÑаÑелÑнÑе знаÑÐµÐ½Ð¸Ñ Ð²Ð¾Ð·Ð²ÑаÑа в положиÑелÑнÑе знаÑÐµÐ½Ð¸Ñ `errno` и ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ `res` в `-1` в ÑлÑÑае оÑибки. ÐÑи вÑзове пÑеÑÑÐ²Ð°Ð½Ð¸Ñ `0x80` пÑоÑеÑÑ Ð¿ÐµÑÐµÑ Ð¾Ð´Ð¸Ñ Ð² ÑдÑо в о бÑабоÑÑик ловÑÑки ÑиÑÑемного вÑзова. ÐÑа пÑоÑедÑÑа ÑÐ¾Ñ ÑанÑÐµÑ Ð²Ñе ÑегиÑÑÑÑ Ð² ÑÑеке и вÑзÑÐ²Ð°ÐµÑ Ð²ÑбÑаннÑÑ ÑоÑÐºÑ Ð²Ñ Ð¾Ð´Ð° ÑиÑÑемного вÑзова. ÐбÑаÑиÑе внимание, ÑÑо ÑоглаÑение о вÑÐ·Ð¾Ð²Ð°Ñ Linux(R) пÑÐµÐ´Ð¿Ð¾Ð»Ð°Ð³Ð°ÐµÑ Ð¿ÐµÑедаÑÑ Ð¿Ð°ÑамеÑÑов ÑиÑÑемного вÑзова ÑеÑез ÑегиÑÑÑÑ, как показано здеÑÑ: + +. паÑамеÑÑ -> `%ebx` +. паÑамеÑÑ -> `%ecx` +. паÑамеÑÑ -> `%edx` +. паÑамеÑÑ -> `%esi` +. паÑамеÑÑ -> `%edi` +. паÑамеÑÑ -> `%ebp` + +СÑÑеÑÑвÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе иÑклÑÑÐµÐ½Ð¸Ñ Ð¸Ð· ÑÑого пÑавила, где Linux(R) иÑполÑзÑÐµÑ Ð´ÑÑгие ÑоглаÑÐµÐ½Ð¸Ñ Ð¾ вÑÐ·Ð¾Ð²Ð°Ñ (наиболее пÑимеÑаÑелен ÑиÑÑемнÑй вÑзов `clone`). + +[[linux-traps]] +===== ÐовÑÑки (trap) + +ÐбÑабоÑÑики ловÑÑек пÑедÑÑÐ°Ð²Ð»ÐµÐ½Ñ Ð² Ñайле [.filename]#arch/i386/kernel/traps.c#, а болÑÑинÑÑво ÑÑÐ¸Ñ Ð¾Ð±ÑабоÑÑиков Ð½Ð°Ñ Ð¾Ð´ÑÑÑÑ Ð² [.filename]#arch/i386/kernel/entry.S#, где пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð¾Ð±ÑабоÑка ловÑÑек. + +[[linux-exits]] +===== ÐÑÑ Ð¾Ð´Ñ + +ÐозвÑÐ°Ñ Ð¸Ð· ÑиÑÑемного вÑзова обÑабаÑÑваеÑÑÑ ÑÑнкÑией `syscall man:exit[3]`, коÑоÑÐ°Ñ Ð¿ÑовеÑÑеÑ, еÑÑÑ Ð»Ð¸ Ñ Ð¿ÑоÑеÑÑа незавеÑÑÑннÑе задаÑи, заÑем пÑовеÑÑеÑ, иÑполÑзовалиÑÑ Ð»Ð¸ ÑелекÑоÑÑ, пÑедоÑÑавленнÑе полÑзоваÑелем. ÐÑли ÑÑо пÑоизоÑло, пÑименÑеÑÑÑ Ð¸ÑпÑавление ÑÑека, и, наконеÑ, ÑегиÑÑÑÑ Ð²Ð¾ÑÑÑанавливаÑÑÑÑ Ð¸Ð· ÑÑека, а пÑоÑеÑÑ Ð²Ð¾Ð·Ð²ÑаÑаеÑÑÑ Ð² полÑзоваÑелÑÑкое пÑоÑÑÑанÑÑво. + +[[linux-unix-primitives]] +===== ÐÑимиÑÐ¸Ð²Ñ UNIX(R) + +РвеÑÑии 2.6 опеÑаÑÐ¸Ð¾Ð½Ð½Ð°Ñ ÑиÑÑема Linux(R) пеÑеопÑеделила некоÑоÑÑе ÑÑадиÑионнÑе пÑимиÑÐ¸Ð²Ñ UNIX(R), в ÑаÑÑноÑÑи PID, TID и поÑок. PID опÑеделÑеÑÑÑ Ð½Ðµ как ÑникалÑнÑй Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пÑоÑеÑÑа, поÑÑÐ¾Ð¼Ñ Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÑоÑÑÑ Ð¿ÑоÑеÑÑов (поÑоков) man:getppid[2] возвÑаÑÐ°ÐµÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾Ðµ знаÑение. УникалÑÐ½Ð°Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¸Ñ Ð¿ÑоÑеÑÑа обеÑпеÑиваеÑÑÑ TID. ÐÑо ÑвÑзано Ñ Ñем, ÑÑо _NPTL_ (New POSIX(R) Thread Library) опÑеделÑÐµÑ Ð¿Ð¾Ñоки как обÑÑнÑе пÑоÑеÑÑÑ (Ñак назÑÐ²Ð°ÐµÐ¼Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»Ñ 1:1). Создание нового п ÑоÑеÑÑа в Linux(R) 2.6 пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ñ Ð¸ÑполÑзованием ÑиÑÑемного вÑзова `clone` (ваÑианÑÑ fork пеÑеÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ Ñ ÐµÐ³Ð¾ иÑпо лÑзованием). ÐÑÐ¾Ñ ÑиÑÑемнÑй вÑзов clone опÑеделÑÐµÑ Ð½Ð°Ð±Ð¾Ñ Ñлагов, коÑоÑÑе влиÑÑÑ Ð½Ð° поведение пÑоÑеÑÑа клониÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð² оÑноÑении ÑеализаÑии поÑоков. СеманÑика немного ÑазмÑÑа, Ñак как Ð½ÐµÑ ÐµÐ´Ð¸Ð½Ð¾Ð³Ð¾ Ñлага, ÑказÑваÑÑего ÑиÑÑÐµÐ¼Ð½Ð¾Ð¼Ñ Ð²ÑÐ·Ð¾Ð²Ñ ÑоздаÑÑ Ð¿Ð¾Ñок. + +РеализованнÑе Ñлаги клониÑованиÑ: + +* `CLONE_VM` - пÑоÑеÑÑÑ ÑазделÑÑÑ Ð¾Ð±Ñее адÑеÑное пÑоÑÑÑанÑÑво +* `CLONE_FS` â ÑовмеÑÑно иÑполÑзоваÑÑ umask, ÑекÑÑий ÑабоÑий каÑалог и пÑоÑÑÑанÑÑво имÑн +* `CLONE_FILES` - ÑовмеÑÑно иÑполÑзоваÑÑ Ð¾ÑкÑÑÑÑе ÑÐ°Ð¹Ð»Ñ +* `CLONE_SIGHAND` - ÑазделÑÑÑ Ð¾Ð±ÑабоÑÑики Ñигналов и заблокиÑованнÑе ÑÐ¸Ð³Ð½Ð°Ð»Ñ +* `CLONE_PARENT` - иÑполÑзоваÑÑ Ð¾Ð´Ð¸Ð½ пÑоÑеÑÑ Ðº каÑеÑÑве ÑодиÑелÑÑкого +* `CLONE_THREAD` â бÑÑÑ Ð¿Ð¾Ñоком (далÑнейÑие поÑÑÐ½ÐµÐ½Ð¸Ñ Ð½Ð¸Ð¶Ðµ) +* `CLONE_NEWNS` - новое пÑоÑÑÑанÑÑво имен +* `CLONE_SYSVSEM` - ÑовмеÑÑное иÑполÑзование ÑÑÑÑкÑÑÑ Ð¾ÑÐ¼ÐµÐ½Ñ SysV +* `CLONE_SETTLS` - наÑÑÑойка TLS по ÑÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð¼Ñ Ð°Ð´ÑеÑÑ +* `CLONE_PARENT_SETTID` - ÑÑÑановиÑÑ TID в ÑодиÑеле +* `CLONE_CHILD_CLEARTID` - оÑиÑÑиÑÑ TID в доÑеÑнем пÑоÑеÑÑе +* `CLONE_CHILD_SETTID` - ÑÑÑановиÑÑ TID в доÑеÑнем пÑоÑеÑÑе + +`CLONE_PARENT` ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑеалÑного ÑодиÑÐµÐ»Ñ Ð² ÑодиÑÐµÐ»Ñ Ð²ÑзÑваÑÑего пÑоÑеÑÑа. ÐÑо полезно Ð´Ð»Ñ Ð¿Ð¾Ñоков, поÑÐ¾Ð¼Ñ ÑÑо еÑли поÑок A ÑоздаÑÑ Ð¿Ð¾Ñок B, Ð¼Ñ Ñ Ð¾Ñим, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ñок B бÑл пÑивÑзан к ÑодиÑÐµÐ»Ñ Ð²Ñей гÑÑÐ¿Ð¿Ñ Ð¿Ð¾Ñоков. `CLONE_THREAD` Ð´ÐµÐ»Ð°ÐµÑ Ñо же Ñамое, ÑÑо `CLONE_PARENT`, `CLONE_VM` и `CLONE_SIGHAND`, пеÑезапиÑÑÐ²Ð°ÐµÑ PID, ÑÑÐ¾Ð±Ñ Ð¾Ð½ Ñовпадал Ñ PID вÑзÑваÑÑего пÑоÑеÑÑа, ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ñигнал завеÑÑÐµÐ½Ð¸Ñ Ð² "неÑ" и Ð²Ñ Ð¾Ð´Ð¸Ñ Ð² гÑÑÐ¿Ð¿Ñ Ð¿Ð¾Ñоков. `CLONE_SETTLS` наÑÑÑÐ°Ð¸Ð²Ð°ÐµÑ Ð·Ð°Ð¿Ð¸Ñи GDT Ð´Ð»Ñ Ð¾Ð±ÑабоÑки TLS. ÐÐ°Ð±Ð¾Ñ Ñлагов `CLONE_*_*TID` ÑÑÑанавливаеÑ/ÑбÑаÑÑÐ²Ð°ÐµÑ Ð¿ÑедоÑÑавленнÑй полÑзоваÑелем адÑÐµÑ Ð² TID или 0. + +Ðак видно, `CLONE_THREAD` вÑполнÑÐµÑ Ð±Ð¾Ð»ÑÑÑÑ ÑаÑÑÑ ÑабоÑÑ Ð¸ не оÑÐµÐ½Ñ Ñ Ð¾ÑоÑо впиÑÑваеÑÑÑ Ð² ÑÑ ÐµÐ¼Ñ. ÐеÑвонаÑалÑнÑй замÑÑел неÑÑен (даже Ð´Ð»Ñ Ð°Ð²ÑоÑов, ÑоглаÑно комменÑаÑиÑм в коде), но Ñ Ð´ÑмаÑ, изнаÑалÑно бÑл один Ñлаг Ð´Ð»Ñ Ð¿Ð¾Ñоков, коÑоÑÑй заÑем бÑл ÑазделÑн на множеÑÑво дÑÑÐ³Ð¸Ñ Ñлагов, но ÑÑо Ñазделение Ñак и не бÑло завеÑÑено. Также непонÑÑно, Ð´Ð»Ñ Ñего нÑжно ÑÑо Ñазделение, Ñак как glibc не иÑполÑзÑÐµÑ ÐµÐ³Ð¾, и ÑолÑко ÑÑÑное иÑполÑзование clone позволÑÐµÑ Ð¿ ÑогÑаммиÑÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð´Ð¾ÑÑÑп к ÑÑим возможноÑÑÑм. + +ÐÐ»Ñ Ð½ÐµÐ¿Ð¾ÑоÑнÑÑ Ð¿ÑогÑамм PID и TID ÑовпадаÑÑ. ÐÐ»Ñ Ð¿Ð¾ÑоÑнÑÑ Ð¿ÑогÑамм пеÑвÑй поÑок Ð¸Ð¼ÐµÐµÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñе PID и TID, а каждÑй ÑозданнÑй поÑок ÑазделÑÐµÑ ÑÐ¾Ñ Ð¶Ðµ PID и полÑÑÐ°ÐµÑ ÑникалÑнÑй TID (поÑколÑÐºÑ Ð¿ÐµÑедаеÑÑÑ `CLONE_THREAD`), Ñакже ÑодиÑелÑÑкий пÑоÑеÑÑ Ð¾Ð±Ñий Ð´Ð»Ñ Ð²ÑÐµÑ Ð¿ÑоÑеÑÑов, обÑазÑÑÑÐ¸Ñ ÑÑÑ Ð¿Ð¾ÑоÑнÑÑ Ð¿ÑогÑаммÑ. + +Ðод, ÑеализÑÑÑий man:pthread_create[3] в NPTL, опÑеделÑÐµÑ Ñлаги clone ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL + + | CLONE_SETTLS | CLONE_PARENT_SETTID + +| CLONE_CHILD_CLEARTID | CLONE_SYSVSEM +#if __ASSUME_NO_CLONE_DETACHED == 0 + +| CLONE_DETACHED +#endif + +| 0); +.... + +`CLONE_SIGNAL` опÑеделен как + +[.programlisting] +.... +#define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD) +.... + +поÑледний 0 ознаÑаеÑ, ÑÑо Ñигнал не оÑпÑавлÑеÑÑÑ Ð¿Ñи завеÑÑении лÑбого из поÑоков. + +[[what-is-emu]] +=== ЧÑо Ñакое ÑмÑлÑÑÐ¸Ñ + +СоглаÑно ÑловаÑÐ½Ð¾Ð¼Ñ Ð¾Ð¿ÑеделениÑ, ÑмÑлÑÑÐ¸Ñ â ÑÑо ÑпоÑобноÑÑÑ Ð¿ÑогÑÐ°Ð¼Ð¼Ñ Ð¸Ð»Ð¸ ÑÑÑÑойÑÑва имиÑиÑоваÑÑ Ð´ÑÑгÑÑ Ð¿ÑогÑÐ°Ð¼Ð¼Ñ Ð¸Ð»Ð¸ ÑÑÑÑойÑÑво. ÐÑо доÑÑигаеÑÑÑ Ð·Ð° ÑÑÑÑ Ð¿ÑедоÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ñой же ÑеакÑии на заданнÑй ÑÑимÑл, ÑÑо и Ñ ÑмÑлиÑÑемого обÑекÑа. Ðа пÑакÑике в миÑе пÑогÑаммного обеÑпеÑÐµÐ½Ð¸Ñ Ð² оÑновном вÑÑÑеÑаÑÑÑÑ ÑÑи Ñипа ÑмÑлÑÑии â пÑогÑамма, иÑполÑзÑÐµÐ¼Ð°Ñ Ð´Ð»Ñ ÑмÑлÑÑии маÑÐ¸Ð½Ñ (QEMU, ÑазлиÑнÑе ÑмÑлÑÑоÑÑ Ð¸Ð³ÑовÑÑ ÐºÐ¾Ð½Ñолей и Ñ.д.), пÑогÑÐ°Ð¼Ð¼Ð½Ð°Ñ ÑмÑÐ»Ñ ÑÐ¸Ñ Ð°Ð¿Ð¿Ð°ÑаÑного обеÑпеÑÐµÐ½Ð¸Ñ (ÑмÑлÑÑоÑÑ OpenGL, ÑмÑлÑÑÐ¸Ñ Ð±Ð»Ð¾ÐºÐ¾Ð² плаваÑÑей запÑÑой и Ñ.д.) и ÑмÑлÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑионнР¾Ð¹ ÑиÑÑÐµÐ¼Ñ (либо в ÑдÑе опеÑаÑионной ÑиÑÑемÑ, либо в виде пÑогÑÐ°Ð¼Ð¼Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑкого пÑоÑÑÑанÑÑва). + +ÐмÑлÑÑÐ¸Ñ Ð¾Ð±ÑÑно иÑполÑзÑеÑÑÑ Ð² ÑÐµÑ ÑлÑÑаÑÑ , когда пÑименение оÑигиналÑного компоненÑа невозможно или неÑелеÑообÑазно. ÐапÑимеÑ, Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÑÑÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑÑ Ð¸ÑполÑзоваÑÑ Ð¿ÑогÑаммÑ, ÑазÑабоÑаннÑÑ Ð´Ð»Ñ Ð´ÑÑгой опеÑаÑионной ÑиÑÑемÑ. Ð Ñакой ÑиÑÑаÑии на помоÑÑ Ð¿ÑÐ¸Ñ Ð¾Ð´Ð¸Ñ ÑмÑлÑÑиÑ. Ðногда ÑмÑлÑÑÐ¸Ñ â единÑÑвеннÑй возможнÑй ваÑианÑ, напÑимеÑ, когда Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾Ðµ аппаÑаÑное ÑÑÑÑойÑÑво еÑÑ Ð½Ðµ ÑÑÑеÑÑвÑÐµÑ Ð¸Ð»Ð¸ Ñже не вÑпÑÑкаеÑÑÑ. Такое ÑаÑÑÐ ¾ пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð¿Ñи пеÑеноÑе опеÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð½Ð° новÑÑ (еÑÑ Ð½Ðµ ÑÑÑеÑÑвÑÑÑÑÑ) плаÑÑоÑмÑ. Ðногда ÑмÑлÑÑÐ¸Ñ Ð¿Ñо ÑÑо ÑкономиÑеÑки вÑгоднее. + +С ÑоÑки зÑÐµÐ½Ð¸Ñ ÑеализаÑии, ÑÑÑеÑÑвÑÐµÑ Ð´Ð²Ð° оÑновнÑÑ Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð° к ÑмÑлÑÑии. ÐÑ Ð¼Ð¾Ð¶ÐµÑе либо ÑмÑлиÑоваÑÑ Ð²ÑÑ Ñеликом â пÑинимаÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñе Ð²Ñ Ð¾Ð´Ð½Ñе даннÑе иÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ обÑекÑа, поддеÑживаÑÑ Ð²Ð½ÑÑÑеннее ÑоÑÑоÑние и вÑдаваÑÑ ÐºÐ¾ÑÑекÑнÑе вÑÑ Ð¾Ð´Ð½Ñе даннÑе на оÑнове ÑоÑÑоÑÐ½Ð¸Ñ Ð¸/или Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð´Ð°Ð½Ð½ÑÑ . Такой вид ÑмÑлÑÑии не ÑÑебÑÐµÑ ÐºÐ°ÐºÐ¸Ñ -либо ÑпеÑиалÑнÑÑ ÑÑловий и, в пÑинÑипе, Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñеализован где Ñгодно Ð´Ð»Ñ Ð»Ñбого ÑÑÑÑойÑÑва/пÑогÑаммÑ. ÐедоÑÑаÑок в Ñом, ÑÑо ÑеализаÑÐ¸Ñ Ñакой ÑмÑлÑÑии доволÑно Ñложна, ÑÑÑдоÑмка и подвеÑжена оÑибкам. РнекоÑоÑÑÑ ÑлÑÑаÑÑ Ð¼Ð ¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ Ð±Ð¾Ð»ÐµÐµ пÑоÑÑой Ð¿Ð¾Ð´Ñ Ð¾Ð´. ÐÑедÑÑавÑÑе, ÑÑо Ð²Ñ Ñ Ð¾ÑиÑе ÑмÑлиÑоваÑÑ Ð¿ÑинÑеÑ, пеÑаÑаÑÑий Ñлева напÑаво, на пÑинÑеÑе, коÑоÑÑй пеÑаÑÐ°ÐµÑ ÑпÑава налево. ÐÑевидно, ÑÑо Ð½ÐµÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи в Ñложном Ñлое ÑмÑлÑÑии â доÑÑаÑоÑно пÑоÑÑо пеÑевеÑнÑÑÑ Ð¿ÐµÑаÑаемÑй ÑекÑÑ. Ðногда ÑмÑлиÑÑÑÑÐ°Ñ ÑÑеда оÑÐµÐ½Ñ Ð¿Ð¾Ñ Ð¾Ð¶Ð° на ÑмÑлиÑÑемÑÑ, и Ñогда доÑÑаÑоÑно Ñонкого ÑÐ»Ð¾Ñ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð±ÐµÑпеÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ð½Ð¾ÑÑÑÑ ÑабоÑей ÑмÑлÑÑии! Ðак видиÑе, Ñакой Ð¿Ð¾Ð´Ñ Ð ¾Ð´ гоÑаздо менее ÑÑебоваÑелен к ÑеализаÑии, а знаÑиÑ, менее ÑÑÑдоÑмок и подвеÑжен оÑибкам, Ñем пÑедÑдÑÑий. Ðд нако Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾Ðµ ÑÑлови! е â две ÑÑÐµÐ´Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð´Ð¾ÑÑаÑоÑно ÑÑ Ð¾Ð¶Ð¸. ТÑеÑий Ð¿Ð¾Ð´Ñ Ð¾Ð´ ÑоÑеÑÐ°ÐµÑ Ð² Ñебе два пÑедÑдÑÑÐ¸Ñ . ЧаÑе вÑего обÑекÑÑ Ð½Ðµ пÑедоÑÑавлÑÑÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñе возможноÑÑи, поÑÑÐ¾Ð¼Ñ Ð² ÑлÑÑае ÑмÑлÑÑии более моÑного обÑекÑа на менее моÑном пÑÐ¸Ñ Ð¾Ð´Ð¸ÑÑÑ ÑмÑлиÑоваÑÑ Ð¾ÑÑÑÑÑÑвÑÑÑие ÑÑнкÑии Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¿Ð¾Ð»Ð½Ð¾Ð¹ ÑмÑлÑÑии, опиÑанной вÑÑе. + +ÐÑа магиÑÑеÑÑÐºÐ°Ñ Ð´Ð¸ÑÑеÑÑаÑÐ¸Ñ Ð¿Ð¾ÑвÑÑена ÑмÑлÑÑии UNIX(R) на UNIX(R), ÑÑо ÑвлÑеÑÑÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ Ñем ÑлÑÑаем, когда доÑÑаÑоÑно Ñонкого ÑÐ»Ð¾Ñ ÑÑанÑлÑÑии Ð´Ð»Ñ Ð¾Ð±ÐµÑпеÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ð½Ð¾Ð¹ ÑмÑлÑÑии. API UNIX(R) ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· набоÑа ÑиÑÑемнÑÑ Ð²Ñзовов, коÑоÑÑе обÑÑно ÑамодоÑÑаÑоÑÐ½Ñ Ð¸ не влиÑÑÑ Ð½Ð° глобалÑное ÑоÑÑоÑние ÑдÑа. + +СÑÑеÑÑвÑÐµÑ Ð½ÐµÑколÑко ÑиÑÑемнÑÑ Ð²Ñзовов, коÑоÑÑе влиÑÑÑ Ð½Ð° внÑÑÑеннее ÑоÑÑоÑние, но ÑÑо можно ÑеÑиÑÑ, пÑедоÑÑавив некоÑоÑÑе ÑÑÑÑкÑÑÑÑ, поддеÑживаÑÑие дополниÑелÑное ÑоÑÑоÑние. + +ÐмÑлÑÑÐ¸Ñ Ð½Ðµ бÑÐ²Ð°ÐµÑ Ð¸Ð´ÐµÐ°Ð»Ñной, и в ÑмÑлÑÑоÑÐ°Ñ ÑаÑÑо Ñего-Ñо не Ñ Ð²Ð°ÑаеÑ, но обÑÑно ÑÑо не вÑзÑÐ²Ð°ÐµÑ ÑеÑÑÑзнÑÑ Ð¿Ñоблем. ÐÑедÑÑавÑÑе ÑмÑлÑÑÐ¾Ñ Ð¸Ð³Ñовой пÑиÑÑавки, коÑоÑÑй ÑмÑлиÑÑÐµÑ Ð²ÑÑ, кÑоме звÑка. Ðез ÑомнениÑ, игÑÑ Ð¾ÑÑаÑÑÑÑ Ð¸Ð³ÑабелÑнÑми, и ÑмÑлÑÑоÑом можно полÑзоваÑÑÑÑ. Ðозможно, ÑÑо не Ñак комÑоÑÑно, как оÑигиналÑÐ½Ð°Ñ Ð¿ÑиÑÑавка, но ÑÑо пÑиемлемÑй компÑомиÑÑ Ð¼ÐµÐ¶Ð´Ñ Ñеной и ÑдобÑÑвом. + +То же Ñамое каÑаеÑÑÑ UNIX(R) API. ÐолÑÑинÑÑво пÑогÑамм могÑÑ ÑабоÑаÑÑ Ñ Ð¾ÑÐµÐ½Ñ Ð¾Ð³ÑаниÑеннÑм набоÑом ÑиÑÑемнÑÑ Ð²Ñзовов. ÐÑи вÑзовÑ, как пÑавило, ÑвлÑÑÑÑÑ ÑамÑми ÑÑаÑÑми (man:read[2]/man:write[2], ÑемейÑÑво man:fork[2], обÑабоÑка man:signal[3], man:exit[3], API man:socket[2]), поÑÑÐ¾Ð¼Ñ Ð¸Ñ Ð»ÐµÐ³ÐºÐ¾ ÑмÑлиÑоваÑÑ, поÑколÑÐºÑ Ð¸Ñ ÑеманÑика одинакова во вÑÐµÑ ÑовÑеменнÑÑ UNIX(R)-подобнÑÑ ÑиÑÑÐµÐ¼Ð°Ñ . + +[[freebsd-emulation]] +== ÐмÑлÑÑÐ¸Ñ + +=== Ðак ÑабоÑÐ°ÐµÑ ÑмÑлÑÑÐ¸Ñ Ð² FreeBSD + +Ðак ÑпоминалоÑÑ Ñанее, FreeBSD поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð²Ñполнение бинаÑнÑÑ Ñайлов из неÑколÑÐºÐ¸Ñ Ð´ÑÑÐ³Ð¸Ñ UNIX(R)-подобнÑÑ ÑиÑÑем. ÐÑо возможно благодаÑÑ Ð½Ð°Ð»Ð¸ÑÐ¸Ñ Ð² FreeBSD абÑÑÑакÑии, назÑваемой загÑÑзÑик клаÑÑов иÑполнениÑ. Ðн инÑегÑиÑÑеÑÑÑ Ð² ÑиÑÑемнÑй вÑзов man:execve[2], поÑÑÐ¾Ð¼Ñ ÐºÐ¾Ð³Ð´Ð° man:execve[2] ÑобиÑаеÑÑÑ Ð²ÑполниÑÑ Ð±Ð¸Ð½Ð°ÑнÑй Ñайл, он анализиÑÑÐµÑ ÐµÐ³Ð¾ Ñип. + +Ð FreeBSD ÑÑÑеÑÑвÑÑÑ Ð´Ð²Ð° оÑновнÑÑ Ñипа иÑполнÑемÑÑ Ñайлов. ТекÑÑовÑе ÑкÑипÑÑ, подобнÑе shell-ÑкÑипÑам, коÑоÑÑе иденÑиÑиÑиÑÑÑÑÑÑ Ð¿Ð¾ пеÑвÑм двÑм Ñимволам `#!`, и обÑÑнÑе (как пÑавило, _ELF_) бинаÑнÑе ÑайлÑ, пÑедÑÑавлÑÑÑие Ñобой ÑкомпилиÑованнÑе иÑполнÑемÑе обÑекÑÑ. ÐодавлÑÑÑее болÑÑинÑÑво (можно ÑказаÑÑ, вÑе) иÑполнÑемÑÑ Ñайлов в FreeBSD оÑноÑÑÑÑÑ Ðº ÑÐ¸Ð¿Ñ ELF. Ð¤Ð°Ð¹Ð»Ñ ELF ÑодеÑÐ¶Ð°Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº, коÑоÑÑй опÑеделÑÐµÑ ABI опеÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ ELF-Ñайла . СÑиÑÑÐ²Ð°Ñ ÑÑÑ Ð¸Ð½ÑоÑмаÑиÑ, опеÑаÑÐ¸Ð¾Ð½Ð½Ð°Ñ ÑиÑÑема Ð¼Ð¾Ð¶ÐµÑ ÑоÑно опÑеделиÑÑ, к ÐºÐ°ÐºÐ¾Ð¼Ñ ÑÐ¸Ð¿Ñ Ð¾ÑноÑиÑÑÑ Ð´Ð°Ð½Ð½Ñй иÑпоР»Ð½ÑемÑй Ñайл. + +ÐаждÑй ABI ÐС должен бÑÑÑ Ð·Ð°ÑегиÑÑÑиÑован в ÑдÑе FreeBSD. ÐÑо оÑноÑиÑÑÑ Ð¸ к ÑÐ¾Ð´Ð½Ð¾Ð¼Ñ ABI ÐС FreeBSD. Таким обÑазом, когда man:execve[2] вÑполнÑÐµÑ Ð´Ð²Ð¾Ð¸ÑнÑй Ñайл, он пеÑебиÑÐ°ÐµÑ ÑпиÑок заÑегиÑÑÑиÑованнÑÑ API, и когда Ð½Ð°Ñ Ð¾Ð´Ð¸Ñ Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑий, наÑÐ¸Ð½Ð°ÐµÑ Ð¸ÑполÑзоваÑÑ Ð¸Ð½ÑоÑмаÑиÑ, ÑодеÑжаÑÑÑÑÑ Ð² опиÑании ABI ÐС (его ÑаблиÑÑ ÑиÑÑемнÑÑ Ð²Ñзовов, ÑаблиÑÑ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ `errno` и Ñ.д.). Таким обÑазом, каждÑй Ñаз, когда пÑоÑеÑÑ Ð²ÑзÑÐ²Ð°ÐµÑ ÑиÑÑемнÑй вÑзов, он иÑполÑзÑÐµÑ Ñвой ÑобÑÑÐ ²ÐµÐ½Ð½Ñй Ð½Ð°Ð±Ð¾Ñ ÑиÑÑемнÑÑ Ð²Ñзовов вмеÑÑо какого-либо глобалÑного. ÐÑо обеÑпеÑÐ¸Ð²Ð°ÐµÑ Ð¾ÑÐµÐ½Ñ ÑлеганÑнÑй и пÑоÑÑой ÑпоÑоб поддеÑжки вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑазлиÑнÑÑ Ð´Ð²Ð¾Ð¸ÑнÑÑ ÑоÑмаÑов. + +ÐÑиÑода ÑмÑлÑÑии ÑазлиÑнÑÑ ÐС (а Ñакже некоÑоÑÑÑ Ð´ÑÑÐ³Ð¸Ñ Ð¿Ð¾Ð´ÑиÑÑем) пÑивела ÑазÑабоÑÑиков к внедÑÐµÐ½Ð¸Ñ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼Ð° обÑабоÑÑиков ÑобÑÑий. Ð ÑдÑе ÑÑÑеÑÑвÑÐµÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑво меÑÑ, где вÑзÑваеÑÑÑ ÑпиÑок обÑабоÑÑиков ÑобÑÑий. ÐÐ°Ð¶Ð´Ð°Ñ Ð¿Ð¾Ð´ÑиÑÑема Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°ÑегиÑÑÑиÑоваÑÑ Ð¾Ð±ÑабоÑÑик ÑобÑÑий, и они вÑзÑваÑÑÑÑ ÑооÑвеÑÑÑвÑÑÑим обÑазом. ÐапÑимеÑ, пÑи завеÑÑении пÑоÑеÑÑа вÑзÑваеÑÑÑ Ð¾Ð±ÑабоÑÑик, коÑоÑÑй Ð¼Ð¾Ð¶ÐµÑ Ð²ÑполниÑÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼ÑÑ Ð¾ÑиÑÑÐºÑ Ð´Ð»Ñ Ð¿Ð¾Ð´ÑиÑÑÐµÐ¼Ñ . + +Те пÑоÑÑÑе ÑÑедÑÑва пÑедоÑÑавлÑÑÑ Ð¿ÑакÑиÑеÑки вÑÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾Ðµ Ð´Ð»Ñ Ð¸Ð½ÑÑаÑÑÑÑкÑÑÑÑ ÑмÑлÑÑии, и, по ÑÑÑи, ÑÑо единÑÑвенное, ÑÑо ÑÑебÑеÑÑÑ Ð´Ð»Ñ ÑеализаÑии ÑÐ»Ð¾Ñ ÑмÑлÑÑии Linux(R). + +[[freebsd-common-primitives]] +=== ÐбÑие пÑимиÑÐ¸Ð²Ñ Ð² ÑдÑе FreeBSD + +ÐÐ»Ñ ÑабоÑÑ Ñлоев ÑмÑлÑÑии ÑÑебÑеÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÐ°Ñ Ð¿Ð¾Ð´Ð´ÐµÑжка Ñо ÑÑоÑÐ¾Ð½Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑемÑ. Я ÑаÑÑÐºÐ°Ð¶Ñ Ð¾ некоÑоÑÑÑ Ð¿Ð¾Ð´Ð´ÐµÑживаемÑÑ Ð¿ÑимиÑÐ¸Ð²Ð°Ñ Ð² опеÑаÑионной ÑиÑÑеме FreeBSD. + +[[freebsd-locking-primitives]] +==== ÐÑимиÑÐ¸Ð²Ñ ÑÐ¸Ð½Ñ ÑонизаÑии + +Ðобавил: `{attilio}` + +ÐÑимиÑÐ¸Ð²Ñ ÑÐ¸Ð½Ñ ÑонизаÑии FreeBSD оÑÐ½Ð¾Ð²Ð°Ð½Ñ Ð½Ð° идее пÑедоÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾ÑÑаÑоÑно болÑÑого колиÑеÑÑва ÑазлиÑнÑÑ Ð¿ÑимиÑивов Ñаким обÑазом, ÑÑÐ¾Ð±Ñ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ конкÑеÑной Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑей ÑиÑÑаÑии можно бÑло иÑполÑзоваÑÑ Ð½Ð°Ð¸Ð»ÑÑÑий. + +Ðа вÑÑоком ÑÑовне можно вÑделиÑÑ ÑÑи вида пÑимиÑивов ÑÐ¸Ð½Ñ ÑонизаÑии в ÑдÑе FreeBSD: + +* аÑомаÑнÑе опеÑаÑии и баÑÑеÑÑ Ð¿Ð°Ð¼ÑÑи +* блокиÑовки +* баÑÑеÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ + +Ðиже пÑÐ¸Ð²ÐµÐ´ÐµÐ½Ñ Ð¾Ð¿Ð¸ÑÐ°Ð½Ð¸Ñ Ð´Ð»Ñ 3 ÑемейÑÑв. ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ блокиÑовки ÑекомендÑеÑÑÑ Ð¾Ð·Ð½Ð°ÐºÐ¾Ð¼Ð¸ÑÑÑÑ Ñ ÑооÑвеÑÑÑвÑÑÑей ÑпÑавоÑной ÑÑÑаниÑей (где ÑÑо возможно), ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð±Ð¾Ð»ÐµÐµ подÑобнÑе обÑÑÑнениÑ. + +[[freebsd-atomic-op]] +===== ÐÑомаÑнÑе опеÑаÑии и баÑÑеÑÑ Ð¿Ð°Ð¼ÑÑи + +ÐÑомаÑнÑе опеÑаÑии ÑеализÑÑÑÑÑ ÑеÑез Ð½Ð°Ð±Ð¾Ñ ÑÑнкÑий, вÑполнÑÑÑÐ¸Ñ Ð¿ÑоÑÑÑе аÑиÑмеÑиÑеÑкие дейÑÑÐ²Ð¸Ñ Ð½Ð°Ð´ опеÑандами в памÑÑи аÑомаÑнÑм обÑазом по оÑноÑÐµÐ½Ð¸Ñ Ðº внеÑним ÑобÑÑиÑм (пÑеÑÑваниÑм, вÑÑеÑÐ½ÐµÐ½Ð¸Ñ Ð¸ Ñ. д.). ÐÑомаÑнÑе опеÑаÑии могÑÑ Ð³Ð°ÑанÑиÑоваÑÑ Ð°ÑомаÑноÑÑÑ ÑолÑко Ð´Ð»Ñ Ð½ÐµÐ±Ð¾Ð»ÑÑÐ¸Ñ Ñипов даннÑÑ (поÑÑдка велиÑÐ¸Ð½Ñ Ñипа `.long` в аÑÑ Ð¸ÑекÑÑÑе C), поÑÑÐ¾Ð¼Ñ Ð¸Ñ ÑледÑÐµÑ Ñедко иÑполÑзоваÑÑ Ð½Ð°Ð¿ÑÑмÑÑ Ð² конеÑном коде, Ñазве ÑÑо Ð´Ð»Ñ Ð¾ÑÐµÐ½Ñ Ð¿ÑоÑÑÑÑ Ð¾Ð¿ÐµÑаÑÐ ¸Ð¹ (напÑимеÑ, ÑÑÑановки Ñлага в биÑовой каÑÑе). Ðа Ñамом деле доволÑно пÑоÑÑо и ÑаÑÑо можно допÑÑÑиÑÑ ÑеманÑÐ¸Ñ ÐµÑкÑÑ Ð¾ÑибкÑ, полагаÑÑÑ ÑолÑко на аÑомаÑнÑе опеÑаÑии (обÑÑно назÑваемÑе lock-less). ЯдÑо FreeBSD пÑедоÑÑавлÑÐµÑ ÑпоÑоб вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð°ÑомаÑнÑÑ Ð¾Ð¿ÐµÑаÑий в ÑоÑеÑании Ñ Ð±Ð°ÑÑеÑами памÑÑи. ÐаÑÑеÑÑ Ð¿Ð°Ð¼ÑÑи гаÑанÑиÑÑÑÑ, ÑÑо аÑомаÑÐ½Ð°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð¿ÑÐ¾Ð¸Ð·Ð¾Ð¹Ð´ÐµÑ Ð² опÑеделенном поÑÑдке оÑноÑиÑелÑно дÑÑÐ³Ð¸Ñ Ð¾Ð±ÑаÑений к памÑÑи. ÐапÑимеÑ, еÑли нам нÑжно, ÑÑÐ¾Ð±Ñ Ð°ÑомаÑÐ½Ð°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð²ÑполнилаÑÑ ÑолÑко поÑле завеÑÑÐµÐ½Ð¸Ñ Ð²ÑÐµÑ Ð¾Ð¶Ð¸Ð´Ð°ÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑий запиÑи (Ñ ÑоÑки зÑÐµÐ½Ð¸Ñ Ð ¿ÐµÑеÑпоÑÑдоÑÐ¸Ð²Ð°Ð½Ð¸Ñ Ð±ÑÑеÑов инÑÑÑÑкÑий), нам Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ Ñвно иÑполÑзоваÑÑ Ð±Ð°ÑÑÐµÑ Ð¿Ð°Ð¼ÑÑи вмеÑÑе Ñ ÑÑой аÑÐ¾Ð¼Ð°Ñ Ð½Ð¾Ð¹ опеÑаÑией. Таким обÑ! азом, легко понÑÑÑ, поÑÐµÐ¼Ñ Ð±Ð°ÑÑеÑÑ Ð¿Ð°Ð¼ÑÑи игÑаÑÑ ÐºÐ»ÑÑевÑÑ ÑÐ¾Ð»Ñ Ð² поÑÑÑоении вÑÑокоÑÑовневÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовок (ÑÐ°ÐºÐ¸Ñ ÐºÐ°Ðº refcounts, мÑÑÑекÑÑ Ð¸ Ñ. д.). ÐÐ»Ñ Ð¿Ð¾Ð´Ñобного обÑÑÑÐ½ÐµÐ½Ð¸Ñ Ð°ÑомаÑнÑÑ Ð¾Ð¿ÐµÑаÑий обÑаÑиÑеÑÑ Ðº man:atomic[9]. Ðднако важно оÑмеÑиÑÑ, ÑÑо аÑомаÑнÑе опеÑаÑии (и баÑÑеÑÑ Ð¿Ð°Ð¼ÑÑи Ñоже) в идеале Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸ÑполÑзоваÑÑÑÑ ÑолÑко Ð´Ð»Ñ Ð¿Ð¾ÑÑÑÐ¾ÐµÐ½Ð¸Ñ ÑÑонÑенд-блокиÑовок (напÑимеÑ, мÑÑÑекÑов). + +[[freebsd-refcounts]] +===== СÑеÑÑики ÑÑÑлок (refcount) + +СÑеÑÑики ÑÑÑлок (refcounts) â ÑÑо инÑеÑÑейÑÑ Ð´Ð»Ñ ÑабоÑÑ Ñ Ð¿Ð¾Ð´ÑÑеÑом ÑÑÑлок. Ðни ÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ Ñ Ð¸ÑполÑзованием аÑомаÑнÑÑ Ð¾Ð¿ÐµÑаÑий и пÑедназнаÑÐµÐ½Ñ Ð´Ð»Ñ ÑлÑÑаев, когда ÑÑеÑÑик ÑÑÑлок â ÑÑо единÑÑвенное, ÑÑо ÑÑебÑÐµÑ Ð·Ð°ÑиÑÑ, поÑÑÐ¾Ð¼Ñ Ð´Ð°Ð¶Ðµ Ñакие Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼Ñ, как Ñпин-мÑÑÑекÑ, не ÑекомендÑÑÑÑÑ. ÐÑполÑзование инÑеÑÑейÑа refcount Ð´Ð»Ñ ÑÑÑÑкÑÑÑ, где Ñже пÑименÑеÑÑÑ Ð¼ÑÑÑекÑ, ÑаÑÑо ÑвлÑеÑÑÑ Ð¾Ñибкой, Ñак как, веÑоÑÑно, ÑледÑÐµÑ Ð·Ð°ÑиÑиÑÑ ÑÑеÑÑик ÑÑÑлок в ÑÐ°Ð¼ÐºÐ°Ñ Ñже ÑÑÑеÑÑвÑÑÑÐ¸Ñ Ð·Ð°ÑиÑеннÑÑ ÑÑаÑÑков кода. РнаÑÑоÑÑее вÑÐµÐ¼Ñ man-ÑÑÑаниÑа, поÑвÑÑÐµÐ½Ð½Ð°Ñ refcount, оÑÑÑÑÑÑвÑеÑ; дл Ñ Ð¾Ð±Ð·Ð¾Ñа ÑÑÑеÑÑвÑÑÑего API обÑаÑиÑеÑÑ Ðº [.filename]#sys/refcount.h#. + +[[freebsd-locks]] +===== ÐлокиÑовки + +ЯдÑо FreeBSD Ð¸Ð¼ÐµÐµÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑво клаÑÑов блокиÑовок. ÐÐ°Ð¶Ð´Ð°Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовка опÑеделÑеÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÑми ÑникалÑнÑми ÑвойÑÑвами, но, веÑоÑÑно, наиболее важнÑм ÑвлÑеÑÑÑ ÑобÑÑие, ÑвÑзанное Ñ ÐºÐ¾Ð½ÐºÑÑиÑÑÑÑими владелÑÑами (или, дÑÑгими Ñловами, поведение поÑоков, неÑпоÑобнÑÑ Ð·Ð°Ñ Ð²Ð°ÑиÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑовкÑ). Ð¡Ñ ÐµÐ¼Ð° блокиÑовок FreeBSD пÑÐµÐ´Ð»Ð°Ð³Ð°ÐµÑ ÑÑи ÑазлиÑнÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑÑиÑÑÑÑÐ¸Ñ Ð¿Ð¾Ñоков: + +. вÑаÑаÑÑиеÑÑ +. блокиÑÑÑÑие +. ÑпÑÑие + +[NOTE] +==== +номеÑа пÑÐ¸Ð²ÐµÐ´ÐµÐ½Ñ Ð½Ðµ ÑлÑÑайно +==== + +[[freebsd-spinlocks]] +===== ÐÑаÑаÑÑиеÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовки + +Спин-блокиÑовки позволÑÑÑ Ð¾Ð¶Ð¸Ð´Ð°ÑÑим поÑокам пÑодолжаÑÑ ÑабоÑÑ (вÑаÑаÑÑÑÑ), пока они не ÑмогÑÑ Ð·Ð°Ñ Ð²Ð°ÑиÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑовкÑ. ÐажнÑм аÑпекÑом ÑвлÑеÑÑÑ ÑиÑÑаÑиÑ, когда поÑок ÑоÑевнÑеÑÑÑ Ð·Ð° Ñпин-блокиÑÐ¾Ð²ÐºÑ Ð¸ не вÑÑеÑнÑеÑÑÑ. ÐоÑколÑÐºÑ ÑдÑо FreeBSD ÑвлÑеÑÑÑ Ð²ÑÑеÑнÑÑÑим, ÑÑо подвеÑÐ³Ð°ÐµÑ Ñпин-блокиÑовки ÑиÑÐºÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð±Ð»Ð¾ÐºÐ¸Ñовок, коÑоÑÑе можно ÑÑÑÑаниÑÑ ÑолÑко оÑклÑÑением пÑеÑÑваний на вÑÐµÐ¼Ñ Ð¸Ñ ÑдеÑжаниÑ. Ðо ÑÑой и дÑÑгим пÑиÑинам (Ñаким как оÑÑÑÑÑÑвиРµ поддеÑжки ÑаÑпÑоÑÑÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð¿ÑиоÑиÑеÑов, неÑÑÑекÑивноÑÑÑ ÑÑ ÐµÐ¼ баланÑиÑовки нагÑÑзки Ð¼ÐµÐ¶Ð´Ñ CPU и Ñ.д.), Ñпин-бл окиÑовки пÑедназнаÑÐµÐ½Ñ Ð´Ð»Ñ Ð·Ð°ÑиÑÑ Ð¾ÑÐµÐ½Ñ Ð½ÐµÐ±Ð¾Ð»ÑÑÐ¸Ñ ÑÑаÑÑков кода или, в идеале, не Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸ÑполÑзоваÑÑÑÑ Ð²Ð¾Ð²Ñе, еÑли ÑÑо не ÑÑебÑеÑÑÑ Ñвно (об ÑÑом далее). + +[[freebsd-blocking]] +===== ÐлокиÑÑÑÑие + +ÐлокиÑÑÑÑие блокиÑовки позволÑÑÑ Ð¾Ð¶Ð¸Ð´Ð°ÑÑим поÑокам бÑÑÑ Ð²ÑгÑÑженнÑми и заблокиÑованнÑми до ÑÐµÑ Ð¿Ð¾Ñ, пока Ð²Ð»Ð°Ð´ÐµÐ»ÐµÑ Ð±Ð»Ð¾ÐºÐ¸Ñовки не оÑÐ²Ð¾Ð±Ð¾Ð´Ð¸Ñ ÐµÑ Ð¸ не ÑазбÑÐ´Ð¸Ñ Ð¾Ð´Ð¸Ð½ или неÑколÑко конкÑÑенÑов. ЧÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ Ð¿Ñоблем Ñ Ð³Ð¾Ð»Ð¾Ð´Ð°Ð½Ð¸ÐµÐ¼, блокиÑÑÑÑие блокиÑовки пеÑедаÑÑ Ð¿ÑиоÑиÑÐµÑ Ð¾Ñ Ð¾Ð¶Ð¸Ð´Ð°ÑÑÐ¸Ñ Ðº владелÑÑÑ. ÐлокиÑÑÑÑие блокиÑовки Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ ÑеÑез инÑеÑÑÐµÐ¹Ñ ÑÑÑникеÑа и пÑедназнаÑÐµÐ½Ñ Ð´Ð»Ñ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ ÑаÑÑого иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² ÑдÑе, еÑли Ð ½ÐµÑ оÑобÑÑ ÑÑловий. + +[[freebsd-sleeping]] +===== СпÑÑие + +СпÑÑие блокиÑовки (Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸ÐµÐ¼) позволÑÑÑ Ð¾Ð¶Ð¸Ð´Ð°ÑÑим поÑокам бÑÑÑ Ð²ÑÑеÑненнÑми и заÑнÑÑÑ Ð´Ð¾ ÑÐµÑ Ð¿Ð¾Ñ, пока деÑжаÑÐµÐ»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовки не оÑÐ²Ð¾Ð±Ð¾Ð´Ð¸Ñ ÐµÑ Ð¸ не ÑазбÑÐ´Ð¸Ñ Ð¾Ð´Ð¸Ð½ или неÑколÑко ожидаÑÑÐ¸Ñ . ÐоÑколÑÐºÑ Ð±Ð»Ð¾ÐºÐ¸Ñовки Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸ÐµÐ¼ пÑедназнаÑÐµÐ½Ñ Ð´Ð»Ñ Ð·Ð°ÑиÑÑ Ð±Ð¾Ð»ÑÑÐ¸Ñ ÑÑаÑÑков кода и обÑабоÑки аÑÐ¸Ð½Ñ ÑоннÑÑ ÑобÑÑий, они не поддеÑживаÑÑ ÑаÑпÑоÑÑÑанение пÑиоÑиÑеÑов. Ðни Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ ÑеÑез инÑеÑÑÐµÐ¹Ñ man:sleepqueue[9]. + +ÐоÑÑдок Ð·Ð°Ñ Ð²Ð°Ñа блокиÑовок оÑÐµÐ½Ñ Ð²Ð°Ð¶ÐµÐ½, не ÑолÑко из-за возможноÑÑи взаимоблокиÑовки пÑи обÑаÑном поÑÑдке Ð·Ð°Ñ Ð²Ð°Ñа, но и поÑомÑ, ÑÑо Ð·Ð°Ñ Ð²Ð°Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовок должен ÑледоваÑÑ Ð¾Ð¿ÑеделÑннÑм пÑавилам, ÑвÑзаннÑм Ñ Ð¸Ñ Ð¿ÑиÑодой. ÐÑли взглÑнÑÑÑ Ð½Ð° ÑаблиÑÑ Ð²ÑÑе, пÑакÑиÑеÑкое пÑавило заклÑÑаеÑÑÑ Ð² Ñом, ÑÑо еÑли поÑок ÑдеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð±Ð»Ð¾ÐºÐ¸ÑÐ¾Ð²ÐºÑ ÑÑÐ¾Ð²Ð½Ñ n (где ÑÑÐ¾Ð²ÐµÐ½Ñ â ÑÑо ÑиÑло, Ñказанное ÑÑдом Ñ Ñипом блокиÑовки), ÐµÐ¼Ñ Ð·Ð°Ð¿ÑеÑено Ð·Ð°Ñ Ð²Ð°ÑÑваÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовки бо лее вÑÑÐ¾ÐºÐ¸Ñ ÑÑовней, Ñак как ÑÑо наÑÑÑÐ¸Ñ Ð·Ð°Ð´Ð°Ð½Ð½ÑÑ ÑеманÑÐ¸ÐºÑ Ð¿ÑÑи. ÐапÑимеÑ, еÑли поÑок ÑдеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð±Ð»Ð¾ÐºÐ¸ÑÑÑÑÑ Ñ Ð±Ð»Ð¾ÐºÐ¸ÑÐ¾Ð²ÐºÑ (ÑÑÐ¾Ð²ÐµÐ½Ñ 2), ÐµÐ¼Ñ ÑазÑеÑено Ð·Ð°Ñ Ð²Ð°ÑÑваÑÑ Ñпин-блокиÑÐ¾Ð²ÐºÑ (ÑÑÐ¾Ð²ÐµÐ½Ñ 1), но не ÑпÑÑÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑÐ¾Ð²ÐºÑ (ÑÑÐ¾Ð²ÐµÐ½Ñ 3), поÑколÑÐºÑ Ð±Ð»Ð¾ÐºÐ¸ÑÑÑÑие блокиÑовки пÑедназнаÑÐµÐ½Ñ Ð´Ð»Ñ Ð·Ð°ÑиÑÑ Ð±Ð¾Ð»ÐµÐµ коÑоÑÐºÐ¸Ñ Ð¿ÑÑей, Ñем ÑпÑÑие блокиÑовки (однако ÑÑи пÑавила не каÑаÑÑÑÑ Ð°ÑомаÑнÑÑ Ð¾Ð¿ÐµÑаÑий или баÑÑеÑов планиÑованиÑ). + +ÐÐ¾Ñ ÑпиÑок блокиÑовок Ñ ÑооÑвеÑÑÑвÑÑÑими Ñипами поведениÑ: + +* spin mutex â вÑаÑаÑÑийÑÑ Ñежим â man:mutex[9] +* sleep mutex â блокиÑÑÑÑий Ñежим â man:mutex[9] +* pool mutex â блокиÑÑÑÑий Ñежим â man:mtx[pool] +* СемейÑÑво ÑÑнкÑий sleep â ÑпÑÑий Ñежим â man:sleep[9] pause tsleep msleep msleep_spin msleep_rw msleep_sx +* condvar â ÑпÑÑий Ñежим â man:condvar[9] +* rwlock â блокиÑÑÑÑий Ñежим â man:rwlock[9] +* sxlock â ÑпÑÑий Ñежим â man:sx[9] +* lockmgr â ÑпÑÑий Ñежим â man:lockmgr[9] +* ÑемаÑоÑÑ â ÑпÑÑий Ñежим â man:sema[9] + +СÑеди ÑÑÐ¸Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовок ÑолÑко мÑÑÑекÑÑ, sxlock, rwlock и lockmgr пÑедназнаÑÐµÐ½Ñ Ð´Ð»Ñ Ð¾Ð±ÑабоÑки ÑекÑÑÑии, но в наÑÑоÑÑее вÑÐµÐ¼Ñ ÑекÑÑÑÐ¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑживаеÑÑÑ ÑолÑко мÑÑÑекÑами и lockmgr. + +[[freebsd-scheduling]] +===== ÐаÑÑеÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ + +ÐаÑÑеÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑедназнаÑÐµÐ½Ñ Ð´Ð»Ñ ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð»Ð°Ð½Ð¸Ñованием поÑоков. Ðни в оÑновном ÑоÑÑоÑÑ Ð¸Ð· ÑÑÐµÑ ÑазлиÑнÑÑ Ð·Ð°Ð³Ð»ÑÑек: + +* кÑиÑиÑеÑкие ÑекÑии (и вÑÑеÑнение) +* sched_bind +* sched_pin + +Ðак пÑавило, Ð¸Ñ ÑледÑÐµÑ Ð¸ÑполÑзоваÑÑ ÑолÑко в опÑеделÑнном конÑекÑÑе, и даже еÑли они ÑаÑÑо могÑÑ Ð·Ð°Ð¼ÐµÐ½ÑÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовки, Ð¸Ñ ÑледÑÐµÑ Ð¸Ð·Ð±ÐµÐ³Ð°ÑÑ, поÑколÑÐºÑ Ð¾Ð½Ð¸ не позволÑÑÑ Ð´Ð¸Ð°Ð³Ð½Ð¾ÑÑиÑоваÑÑ Ð¿ÑоÑÑÑе поÑенÑиалÑнÑе пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¸Ð½ÑÑÑÑменÑов оÑладки блокиÑовок (напÑимеÑ, man:witness[4]). + +[[freebsd-critical]] +===== ÐÑиÑиÑеÑкие ÑекÑии + +Ð ÑдÑе FreeBSD бÑла Ñеализована вÑÑеÑнÑÑÑÐ°Ñ Ð¼Ð½Ð¾Ð³Ð¾Ð·Ð°Ð´Ð°ÑноÑÑÑ Ð² оÑновном Ð´Ð»Ñ ÑабоÑÑ Ñ Ð¿Ð¾Ñоками обÑабоÑки пÑеÑÑваний. ФакÑиÑеÑки, ÑÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ Ð²ÑÑокой задеÑжки пÑеÑÑваний, поÑоки Ñ Ð¿ÑиоÑиÑеÑом ÑÐ°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð²Ñемени могÑÑ Ð±ÑÑÑ Ð²ÑÑеÑÐ½ÐµÐ½Ñ Ð¿Ð¾Ñоками обÑабоÑки пÑеÑÑваний (Ñаким обÑазом, им не нÑжно ждаÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑованиÑ, как ÑÑо пÑедÑÑмоÑÑено в обÑÑном ÑлÑÑае). Ðднако вÑÑеÑнение Ñакже Ð²Ð²Ð¾Ð´Ð¸Ñ Ð½Ð¾Ð²Ñе ÑоÑки гонки, коÑоÑÑе Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ обÑабаÑÑваÑÑ. ЧР°ÑÑо Ð´Ð»Ñ Ð±Ð¾ÑÑÐ±Ñ Ñ Ð²ÑÑеÑнением пÑоÑе вÑего полноÑÑÑÑ Ð¾ÑклÑÑиÑÑ ÐµÐ³Ð¾. ÐÑиÑиÑеÑÐºÐ°Ñ ÑекÑÐ¸Ñ Ð¾Ð¿ÑеделÑÐµÑ ÑÑаÑÑок ко да (огÑаниÑеннÑй паÑой ÑÑнкÑий man:critical_enter[9] и man:critical_exit[9]), где гаÑанÑиÑÑеÑÑÑ Ð¾ÑÑÑÑÑÑвие вÑÑеÑÐ½ÐµÐ½Ð¸Ñ (пока заÑиÑÑннÑй код не бÑÐ´ÐµÑ Ð¿Ð¾Ð»Ð½Ð¾ÑÑÑÑ Ð²Ñполнен). ÐÑо ÑаÑÑо Ð¼Ð¾Ð¶ÐµÑ ÑÑÑекÑивно замениÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑовкÑ, но должно иÑполÑзоваÑÑÑÑ Ð¾ÑÑоÑожно, ÑÑÐ¾Ð±Ñ Ð½Ðµ поÑеÑÑÑÑ Ð²Ñе пÑеимÑÑеÑÑва, коÑоÑÑе даÑÑ Ð²ÑÑеÑнение. + +[[freebsd-schedpin]] +===== sched_pin/sched_unpin + +ÐÑе один ÑпоÑоб ÑабоÑÑ Ñ Ð²ÑÑеÑнением â ÑÑо инÑеÑÑÐµÐ¹Ñ `sched_pin()`. ÐÑли ÑÑаÑÑок кода заклÑÑен Ð¼ÐµÐ¶Ð´Ñ ÑÑнкÑиÑми `sched_pin()` и `sched_unpin()`, гаÑанÑиÑÑеÑÑÑ, ÑÑо ÑооÑвеÑÑÑвÑÑÑий поÑок, даже еÑли он Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²ÑÑеÑнен, вÑегда бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð½Ð° Ñом же CPU. ÐакÑепление оÑÐµÐ½Ñ ÑÑÑекÑивно в ÑаÑÑном ÑлÑÑае, когда нам Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ обÑаÑаÑÑÑÑ Ðº даннÑм, пÑивÑзаннÑм к опÑеделеннÑм CPU, и Ð¼Ñ Ð¿Ñедполагаем, ÑÑо дÑÑгие поÑоки не изменÑÑ ÑÑи даннÑе. ÐоÑледнее ÑÑловие д ÐµÐ»Ð°ÐµÑ ÐºÑиÑиÑеÑкÑÑ ÑекÑÐ¸Ñ Ð¸Ð·Ð±ÑÑоÑно ÑÑÑогим ÑÑловием Ð´Ð»Ñ Ð½Ð°Ñего кода. + +[[freebsd-schedbind]] +===== sched_bind/sched_unbind + +`sched_bind` â ÑÑо API, иÑполÑзÑемÑй Ð´Ð»Ñ Ð¿ÑивÑзки поÑока к опÑеделÑÐ½Ð½Ð¾Ð¼Ñ CPU на вÑÑ Ð²ÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð´Ð°, пока вÑзов ÑÑнкÑии `sched_unbind` не оÑÐ¼ÐµÐ½Ð¸Ñ ÑÑÑ Ð¿ÑивÑзкÑ. ÐÑа ÑÑнкÑÐ¸Ñ Ð¸Ð³ÑÐ°ÐµÑ ÐºÐ»ÑÑевÑÑ ÑÐ¾Ð»Ñ Ð² ÑиÑÑаÑиÑÑ , когда нелÑÐ·Ñ Ð´Ð¾Ð²ÐµÑÑÑÑ ÑекÑÑÐµÐ¼Ñ ÑоÑÑоÑÐ½Ð¸Ñ CPU (напÑимеÑ, на ÑамÑÑ ÑÐ°Ð½Ð½Ð¸Ñ ÑÑÐ°Ð¿Ð°Ñ Ð·Ð°Ð³ÑÑзки), Ñак как ÑÑебÑеÑÑÑ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ Ð¼Ð¸Ð³ÑаÑии поÑока на неакÑивнÑе CPU. ÐоÑколÑÐºÑ `sched_bind` и `sched_unbind` ÑабоÑаÑÑ Ñ Ð²Ð½ÑÑÑенними ÑÑÑÑкÑÑÑами планиÑовÑика, Ð¸Ñ Ð¸ÑполÑзован ие должно бÑÑÑ Ð·Ð°ÐºÐ»ÑÑено в Ð·Ð°Ñ Ð²Ð°Ñ/оÑвобождение `sched_lock`. + +[[freebsd-proc]] +==== СÑÑÑкÑÑÑа proc + +РазлиÑнÑе ÑÑовни ÑмÑлÑÑии иногда ÑÑебÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ Ð´Ð°Ð½Ð½ÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пÑоÑеÑÑа. Ðожно ÑпÑавлÑÑÑ Ð¾ÑделÑнÑми ÑÑÑÑкÑÑÑами (ÑпиÑком, деÑевом и Ñ.д.), ÑодеÑжаÑими ÑÑи даннÑе Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пÑоÑеÑÑа, но ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾ и поÑÑеблÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ памÑÑи. ЧÑÐ¾Ð±Ñ ÑеÑиÑÑ ÑÑÑ Ð¿ÑоблемÑ, ÑÑÑÑкÑÑÑа `proc` в FreeBSD ÑодеÑÐ¶Ð¸Ñ `p_emuldata` â ÑказаÑÐµÐ»Ñ Ñипа void на даннÑе, ÑпеÑиÑиÑнÑе Ð´Ð»Ñ ÑÑÐ¾Ð²Ð½Ñ ÑмÑлÑÑии. ÐÑа запиÑÑ `proc` заÑиÑена мÑÑÑекÑом proc. + +СÑÑÑкÑÑÑа `proc` в FreeBSD ÑодеÑÐ¶Ð¸Ñ ÑÐ»ÐµÐ¼ÐµÐ½Ñ `p_sysent`, коÑоÑÑй иденÑиÑиÑиÑÑеÑ, под какой ABI ÑабоÑÐ°ÐµÑ Ð´Ð°Ð½Ð½Ñй пÑоÑеÑÑ. ФакÑиÑеÑки, ÑÑо ÑказаÑÐµÐ»Ñ Ð½Ð° ÑпомÑнÑÑÑй вÑÑе `sysentvec`. Таким обÑазом, ÑÑÐ°Ð²Ð½Ð¸Ð²Ð°Ñ ÑÑÐ¾Ñ ÑказаÑÐµÐ»Ñ Ñ Ð°Ð´ÑеÑом, по коÑоÑÐ¾Ð¼Ñ Ñ ÑаниÑÑÑ ÑÑÑÑкÑÑÑа `sysentvec` Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ ABI, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑÑÑекÑивно опÑеделиÑÑ, пÑÐ¸Ð½Ð°Ð´Ð»ÐµÐ¶Ð¸Ñ Ð»Ð¸ пÑоÑеÑÑ Ð½Ð°ÑÐµÐ¼Ñ ÑмÑлÑÑÐ¸Ð¾Ð½Ð½Ð¾Ð¼Ñ ÑлоÑ. Ðод обÑÑно вÑглÑÐ´Ð¸Ñ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +if (__predict_true(p->p_sysent != &elf_Linux(R)_sysvec)) + return; +.... + +Ðак видиÑе, Ð¼Ñ ÑÑÑекÑивно иÑполÑзÑем модиÑикаÑÐ¾Ñ `__predict_true`, ÑÑÐ¾Ð±Ñ ÑвеÑÑи наиболее ÑаÑпÑоÑÑÑанÑннÑй ÑлÑÑай (пÑоÑеÑÑ FreeBSD) к пÑоÑÑой опеÑаÑии возвÑаÑа, ÑÐ¾Ñ ÑанÑÑ Ð²ÑÑокÑÑ Ð¿ÑоизводиÑелÑноÑÑÑ. ÐÑÐ¾Ñ ÐºÐ¾Ð´ ÑледÑÐµÑ Ð¿ÑеобÑазоваÑÑ Ð² макÑоÑ, поÑколÑÐºÑ Ð² наÑÑоÑÑее вÑÐµÐ¼Ñ Ð¾Ð½ не оÑÐµÐ½Ñ Ð³Ð¸Ð±ÐºÐ¸Ð¹, напÑимеÑ, Ð¼Ñ Ð½Ðµ поддеÑживаем ÑмÑлÑÑÐ¸Ñ Linux(R)64, а Ñакже пÑоÑеÑÑÑ Linux(R) в ÑоÑмаÑе A.OUT на аÑÑ Ð¸ÑекÑÑÑе i386. + +[[freebsd-vfs]] +==== VFS + +ÐодÑиÑÑема VFS в FreeBSD оÑÐµÐ½Ñ Ñложна, но Ñлой ÑмÑлÑÑии Linux(R) иÑполÑзÑÐµÑ Ð»Ð¸ÑÑ Ð½ÐµÐ±Ð¾Ð»ÑÑÑÑ ÐµÑ ÑаÑÑÑ ÑеÑез ÑÑÑко опÑеделÑннÑй API. Ðна Ð¼Ð¾Ð¶ÐµÑ ÑабоÑаÑÑ ÐºÐ°Ðº Ñ vnode, Ñак и Ñ ÑайловÑми деÑкÑипÑоÑами. Vnode пÑедÑÑавлÑÐµÑ Ñобой виÑÑÑалÑнÑй vnode, Ñо еÑÑÑ Ð¿ÑедÑÑавление Ñзла в VFS. ÐÑÑгое пÑедÑÑавление â ÑÑо ÑайловÑй деÑкÑипÑоÑ, коÑоÑÑй пÑедÑÑавлÑÐµÑ Ð¾ÑкÑÑÑÑй Ñайл Ñ ÑоÑки зÑÐµÐ½Ð¸Ñ Ð¿ÑоÑеÑÑа. ФайловÑй деÑкÑипÑÐ¾Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑедÑÑавлÑÑÑ ÑÐ¾ÐºÐµÑ Ð¸Ð»Ð¸ обÑÑнÑй Ñайл. ФайловÑй де ÑкÑипÑÐ¾Ñ ÑодеÑÐ¶Ð¸Ñ ÑказаÑÐµÐ»Ñ Ð½Ð° Ñвой vnode. Ðолее одного Ñайлового деÑкÑипÑоÑа могÑÑ ÑказÑваÑÑ Ð½Ð° один и ÑÐ¾Ñ Ð¶Ðµ vnode. + +[[freebsd-namei]] +===== namei + +ФÑнкÑÐ¸Ñ man:namei[9] ÑвлÑеÑÑÑ ÑенÑÑалÑной ÑоÑкой Ð²Ñ Ð¾Ð´Ð° Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка и пÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑÑей. Ðна пÑÐ¾Ñ Ð¾Ð´Ð¸Ñ Ð¿Ð¾ пÑÑи Ñаг за Ñагом Ð¾Ñ Ð½Ð°ÑалÑной до конеÑной ÑоÑки, иÑполÑзÑÑ ÑÑнкÑÐ¸Ñ Ð¿Ð¾Ð¸Ñка, коÑоÑÐ°Ñ ÑвлÑеÑÑÑ Ð²Ð½ÑÑÑенней Ð´Ð»Ñ VFS. СиÑÑемнÑй вÑзов man:namei[9] Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð±ÑабаÑÑваÑÑ ÑимволÑнÑе ÑÑÑлки, абÑолÑÑнÑе и оÑноÑиÑелÑнÑе пÑÑи. Ðогда пÑÑÑ Ð¸ÑеÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ man:namei[9], он заноÑиÑÑÑ Ð² кÑÑ Ð¸Ð¼Ñн. ÐÑо поведение можно оÑклÑÑиÑÑ. ÐÐ°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¸ÑполÑзÑеÑÑÑ Ð¿Ð¾Ð²ÑемеÑÑ Ð½Ð¾ в ÑдÑе, и ÐµÑ Ð¿ÑоизводиÑелÑноÑÑÑ ÐºÑайне важна. + +[[freebsd-vn]] +===== vn_fullpath + +ФÑнкÑÐ¸Ñ man:vn_fullpath[9] пÑедпÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð¼Ð°ÐºÑималÑнÑе ÑÑÐ¸Ð»Ð¸Ñ Ð´Ð»Ñ Ð¾Ð±Ñ Ð¾Ð´Ð° кÑÑа имÑн VFS и возвÑаÑÐ°ÐµÑ Ð¿ÑÑÑ Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ (заблокиÑованного) vnode. ÐÑÐ¾Ñ Ð¿ÑоÑеÑÑ Ð½ÐµÐ½Ð°Ð´Ñжен, но в болÑÑинÑÑве ÑипиÑнÑÑ ÑлÑÑаев ÑабоÑÐ°ÐµÑ ÐºÐ¾ÑÑекÑно. ÐенадÑжноÑÑÑ Ð¾Ð±ÑÑловлена Ñем, ÑÑо ÑÑнкÑÐ¸Ñ Ð¾Ð¿Ð¸ÑаеÑÑÑ Ð½Ð° кÑÑ VFS (она не Ð¾Ð±Ñ Ð¾Ð´Ð¸Ñ ÑÑÑÑкÑÑÑÑ Ð½Ð° ноÑиÑеле), не ÑабоÑÐ°ÐµÑ Ñ Ð¶ÑÑÑкими ÑÑÑлками и Ñ.д. ÐÐ°Ð½Ð½Ð°Ñ Ð¿ÑоÑедÑÑа иÑполÑзÑеÑÑÑ Ð² неÑколÑÐºÐ¸Ñ Ð¼ÐµÑÑÐ°Ñ Linuxulator. + +[[freebsd-vnode]] +===== ÐпеÑаÑии Ñ vnode + +* `fgetvp` - по заданнÑм поÑÐ¾ÐºÑ Ð¸ номеÑÑ Ñайлового деÑкÑипÑоÑа возвÑаÑÐ°ÐµÑ ÑвÑзаннÑй vnode +* man:vn_lock[9] - блокиÑÑÐµÑ vnode +* `vn_unlock` - ÑазблокиÑÑÐµÑ vnode +* man:VOP_READDIR[9] - ÑиÑÐ°ÐµÑ ÐºÐ°Ñалог, на коÑоÑÑй ÑÑÑлаеÑÑÑ vnode +* man:VOP_GETATTR[9] - полÑÑÐ°ÐµÑ Ð°ÑÑибÑÑÑ Ñайла или каÑалога, на коÑоÑÑй ÑÑÑлаеÑÑÑ vnode +* man:VOP_LOOKUP[9] - вÑполнÑÐµÑ Ð¿Ð¾Ð¸Ñк пÑÑи к Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ ÐºÐ°ÑÐ°Ð»Ð¾Ð³Ñ +* man:VOP_OPEN[9] - оÑкÑÑÐ²Ð°ÐµÑ Ñайл, на коÑоÑÑй ÑÑÑлаеÑÑÑ vnode +* man:VOP_CLOSE[9] - закÑÑÐ²Ð°ÐµÑ Ñайл, на коÑоÑÑй ÑÑÑлаеÑÑÑ vnode +* man:vput[9] - ÑменÑÑÐ°ÐµÑ ÑÑеÑÑик иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ vnode и ÑазблокиÑÑÐµÑ ÐµÐ³Ð¾ +* man:vrele[9] - ÑменÑÑÐ°ÐµÑ ÑÑеÑÑик иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ vnode +* man:vref[9] - ÑвелиÑÐ¸Ð²Ð°ÐµÑ ÑÑеÑÑик иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ vnode + +[[freebsd-file-handler]] +===== ÐпеÑаÑии обÑабоÑÑика Ñайлов (handler) + +* `fget` - Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ поÑока и номеÑа Ñайлового деÑкÑипÑоÑа возвÑаÑÐ°ÐµÑ ÑвÑзаннÑй обÑабоÑÑик Ñайла и Ð´ÐµÐ»Ð°ÐµÑ Ð½Ð° него ÑÑÑÐ»ÐºÑ +* `fdrop` - оÑÐ²Ð¾Ð±Ð¾Ð¶Ð´Ð°ÐµÑ ÑÑÑÐ»ÐºÑ Ð½Ð° обÑабоÑÑик Ñайлов +* `fhold` - ÑÑÑлаеÑÑÑ Ð½Ð° обÑабоÑÑик Ñайла + +[[md]] +== Слой ÑмÑлÑÑии Linux(R) - маÑинно-завиÑÐ¸Ð¼Ð°Ñ ÑаÑÑÑ + +Ð ÑÑом Ñазделе ÑаÑÑмаÑÑиваеÑÑÑ ÑеализаÑÐ¸Ñ ÑÐ»Ð¾Ñ ÑмÑлÑÑии Linux(R) в опеÑаÑионной ÑиÑÑеме FreeBSD. СнаÑала опиÑÑваеÑÑÑ Ð¼Ð°Ñинно-завиÑÐ¸Ð¼Ð°Ñ ÑаÑÑÑ, ÑаÑÑказÑваÑÑÐ°Ñ Ð¾ Ñом, как и где Ñеализовано взаимодейÑÑвие Ð¼ÐµÐ¶Ð´Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑким пÑоÑÑÑанÑÑвом и ÑдÑом. РаÑÑмаÑÑиваÑÑÑÑ ÑиÑÑемнÑе вÑзовÑ, ÑигналÑ, ptrace, ловÑÑки и иÑпÑавление ÑÑека. ÐÑа ÑаÑÑÑ Ð¿Ð¾ÑвÑÑена аÑÑ Ð¸ÑекÑÑÑе i386, но напиÑана в обÑем виде, поÑÑÐ¾Ð¼Ñ Ð´ÑÑгие аÑÑ Ð¸ÑекÑÑÑÑ Ð½Ðµ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑилÑно оÑлиÑаÑÑÑÑ . СледÑÑÑÐ°Ñ ÑаÑÑÑ â маÑинно-незавиÑÐ¸Ð¼Ð°Ñ ÑаÑÑÑ Linuxulator. ÐÑÐ¾Ñ Ñаздел Ð¾Ñ Ð²Ð°ÑÑÐ²Ð°ÐµÑ ÑолÑко i386 и обÑабоÑÐºÑ ELF. A.OUT ÑÑÑ Ð°Ñел и не поддеÑживаеÑÑÑ. + +[[syscall-handling]] +=== ÐбÑабоÑка ÑиÑÑемнÑÑ Ð²Ñзовов + +ÐбÑабоÑка ÑиÑÑемнÑÑ Ð²Ñзовов в оÑновном Ñеализована в Ñайле [.filename]#linux_sysvec.c#, коÑоÑÑй покÑÑÐ²Ð°ÐµÑ Ð±Ð¾Ð»ÑÑинÑÑво пÑоÑедÑÑ, ÑказаннÑÑ Ð² ÑÑÑÑкÑÑÑе `sysentvec`. Ðогда пÑоÑеÑÑ Linux(R), вÑполнÑÑÑийÑÑ Ð½Ð° FreeBSD, Ð´ÐµÐ»Ð°ÐµÑ ÑиÑÑемнÑй вÑзов, обÑÐ°Ñ Ð¿ÑоÑедÑÑа обÑабоÑки ÑиÑÑемнÑÑ Ð²Ñзовов вÑзÑÐ²Ð°ÐµÑ linux prepsyscall Ð´Ð»Ñ ABI Linux(R). + +[[linux-prepsyscall]] +==== Linux(R) prepsyscall + +Linux(R) пеÑÐµÐ´Ð°ÐµÑ Ð°ÑгÑменÑÑ ÑиÑÑемнÑÑ Ð²Ñзовов ÑеÑез ÑегиÑÑÑÑ (поÑÑÐ¾Ð¼Ñ Ð½Ð° i386 огÑаниÑено 6 паÑамеÑÑами), Ñогда как FreeBSD иÑполÑзÑÐµÑ ÑÑек. ÐодпÑогÑамма Linux(R) `prepsyscall` должна копиÑоваÑÑ Ð¿Ð°ÑамеÑÑÑ Ð¸Ð· ÑегиÑÑÑов в ÑÑек. ÐоÑÑдок ÑегиÑÑÑов ÑледÑÑÑий: `%ebx`, `%ecx`, `%edx`, `%esi`, `%edi`, `%ebp`. Ðднако ÑÑо веÑно ÑолÑко Ð´Ð»Ñ _болÑÑинÑÑва_ ÑиÑÑемнÑÑ Ð²Ñзовов. ÐекоÑоÑÑе (оÑобенно `clone`) иÑполÑзÑÑÑ Ð´ÑÑгой поÑÑдок, но ÑÑо, к ÑÑаÑÑÑÑ, легко иÑпÑавиÑÑ, добавив ÑикÑивнÑй паÑамеÑÑ Ð² пÑоÑоÑип `linux_clone`. + +[[syscall-writing]] +==== Ðак пиÑаÑÑ ÑиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ + +ÐаждÑй ÑиÑÑемнÑй вÑзов, ÑеализованнÑй в Linuxulator, должен имеÑÑ Ñвой пÑоÑоÑип Ñ ÑазлиÑнÑми Ñлагами в [.filename]#syscalls.master#. ФоÑÐ¼Ð°Ñ Ñайла ÑледÑÑÑий: + +[.programlisting] +.... +... + AUE_FORK STD { int linux_fork(void); } +... + AUE_CLOSE NOPROTO { int close(int fd); } +... +.... + +ÐеÑвÑй ÑÑÐ¾Ð»Ð±ÐµÑ Ð¿ÑедÑÑавлÑÐµÑ Ð½Ð¾Ð¼ÐµÑ ÑиÑÑемного вÑзова. ÐÑоÑой ÑÑÐ¾Ð»Ð±ÐµÑ Ð¿ÑедназнаÑен Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑжки аÑдиÑа. ТÑеÑий ÑÑÐ¾Ð»Ð±ÐµÑ Ð¾Ð±Ð¾Ð·Ð½Ð°ÑÐ°ÐµÑ Ñип ÑиÑÑемного вÑзова. Ðн Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ `STD`, `OBSOL`, `NOPROTO` или `UNIMPL`. `STD` â ÑÑо ÑÑандаÑÑнÑй ÑиÑÑемнÑй вÑзов Ñ Ð¿Ð¾Ð»Ð½Ñм пÑоÑоÑипом и ÑеализаÑией. `OBSOL` ознаÑÐ°ÐµÑ ÑÑÑаÑевÑий вÑзов и опÑеделÑÐµÑ ÑолÑко пÑоÑоÑип. `NOPROTO` ознаÑаеÑ, ÑÑо ÑиÑÑемнÑй вÑзов Ñеализован в дÑÑгом меÑÑе, поÑÑÐ¾Ð¼Ñ Ð½Ðµ ÑÑебÑÐµÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑеÑикÑа ABI и Ñ.д. ` UNIMPL` ознаÑаеÑ, ÑÑо ÑиÑÑемнÑй вÑзов бÑÐ´ÐµÑ Ð·Ð°Ð¼ÐµÐ½Ñн на `nosys` (ÑиÑÑемнÑй вÑзов, коÑоÑÑй пÑоÑÑо вÑÐ²Ð¾Ð´Ð¸Ñ ÑообÑение о Ñом, ÑÑо вÑзов не Ñеализован, и возвÑаÑÐ°ÐµÑ `ENOSYS`). + +Ðз Ñайла [.filename]#syscalls.master# ÑкÑÐ¸Ð¿Ñ Ð³ÐµÐ½ÐµÑиÑÑÐµÑ ÑÑи Ñайла: [.filename]#linux_syscall.h#, [.filename]#linux_proto.h# и [.filename]#linux_sysent.c#. Файл [.filename]#linux_syscall.h# ÑодеÑÐ¶Ð¸Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐ½ ÑиÑÑемнÑÑ Ð²Ñзовов и Ð¸Ñ ÑиÑловÑÑ Ð·Ð½Ð°Ñений, напÑимеÑ: + +[.programlisting] +.... +... +#define LINUX_SYS_linux_fork 2 +... +#define LINUX_SYS_close 6 +... +.... + +[.filename]#linux_proto.h# ÑодеÑÐ¶Ð¸Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÑÑÑÑкÑÑÑ Ð°ÑгÑменÑов Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ ÑиÑÑемного вÑзова, напÑимеÑ: + +[.programlisting] +.... +struct linux_fork_args { + register_t dummy; +}; +.... + +Ð, наконеÑ, [.filename]#linux_sysent.c# ÑодеÑÐ¶Ð¸Ñ ÑÑÑÑкÑÑÑÑ, опиÑÑваÑÑÑÑ ÑаблиÑÑ ÑиÑÑемнÑÑ Ð²Ñзовов, иÑполÑзÑемÑÑ Ð´Ð»Ñ ÑакÑиÑеÑкой диÑпеÑÑеÑизаÑии ÑиÑÑемного вÑзова, напÑимеÑ: + +[.programlisting] +.... +{ 0, (sy_call_t *)linux_fork, AUE_FORK, NULL, 0, 0 }, /* 2 = linux_fork */ +{ AS(close_args), (sy_call_t *)close, AUE_CLOSE, NULL, 0, 0 }, /* 6 = close */ +.... + +Ðак видно, `linux_fork` Ñеализован в Ñамом Linuxulator, поÑÑÐ¾Ð¼Ñ Ð¾Ð¿Ñеделение Ð¸Ð¼ÐµÐµÑ Ñип `STD` и не Ð¸Ð¼ÐµÐµÑ Ð°ÑгÑменÑов, ÑÑо демонÑÑÑиÑÑеÑÑÑ ÑÑÑÑкÑÑÑой-заглÑÑкой. С дÑÑгой ÑÑоÑонÑ, `close` â ÑÑо пÑоÑÑо пÑевдоним Ð´Ð»Ñ Ð½Ð°ÑÑоÑÑего FreeBSD man:close[2], поÑÑÐ¾Ð¼Ñ Ñ Ð½ÐµÐ³Ð¾ Ð½ÐµÑ ÑвÑзанной ÑÑÑÑкÑÑÑÑ Ð°ÑгÑменÑов Linux, и в ÑиÑÑемной ÑаблиÑе вÑзовов он не Ð¸Ð¼ÐµÐµÑ Ð¿ÑеÑикÑа linux, Ñак как вÑзÑÐ²Ð°ÐµÑ Ð½Ð°ÑÑоÑÑий man:close[2] в ÑдÑе. + +[[dummy-syscalls]] +==== ÐеÑеализованнÑе ÑиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ + +Слой ÑмÑлÑÑии Linux(R) не ÑвлÑеÑÑÑ Ð¿Ð¾Ð»Ð½Ñм, Ñак как некоÑоÑÑе ÑиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ ÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ Ð½ÐµÐ¿ÑавилÑно, а некоÑоÑÑе не ÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ Ð²Ð¾Ð²Ñе. Ð Ñлое ÑмÑлÑÑии иÑполÑзÑеÑÑÑ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼ Ð´Ð»Ñ Ð¿Ð¾Ð¼ÐµÑки неÑеализованнÑÑ ÑиÑÑемнÑÑ Ð²Ñзовов Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¼Ð°ÐºÑоÑа `DUMMY`. ÐÑи заглÑÑки Ð½Ð°Ñ Ð¾Ð´ÑÑÑÑ Ð² Ñайле [.filename]#linux_dummy.c# в ÑоÑме `DUMMY(syscall);`, коÑоÑÑе заÑем пÑеобÑазÑÑÑÑÑ Ð² ÑазлиÑнÑе вÑпомогаÑелÑнÑе ÑÐ°Ð¹Ð»Ñ ÑиÑÑемнÑÑ Ð²Ñзовов, а Ð¸Ñ ÑеализаÑÐ¸Ñ ÑводиÑÑÑ Ðº вÑÐ²Ð¾Ð´Ñ ÑообÑÐµÐ½Ð¸Ñ Ð¾ Ñ Ð¾Ð¼, ÑÑо даннÑй ÑиÑÑемнÑй вÑзов не Ñеализован. ÐÑоÑоÑип `UNIMPL` не иÑполÑзÑеÑÑÑ, поÑÐ¾Ð¼Ñ ÑÑо Ð¼Ñ Ñ Ð¾Ñим имеÑÑ Ð²Ð¾Ð·Ð¼Ð¾ жноÑÑÑ Ð¸Ð´ÐµÐ½ÑиÑиÑиÑоваÑÑ Ð¸Ð¼Ñ Ð²Ñзванного ÑиÑÑемного вÑзова, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð½Ð¸Ð¼Ð°ÑÑ, какие ÑиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ Ð±Ð¾Ð»ÐµÐµ Ð²Ð°Ð¶Ð½Ñ Ð´Ð»Ñ ÑеализаÑии. + +[[signal-handling]] +=== ÐбÑабоÑка Ñигналов + +ÐбÑабоÑка Ñигналов обÑÑно вÑполнÑеÑÑÑ Ð² ÑдÑе FreeBSD Ð´Ð»Ñ Ð²ÑÐµÑ Ð²Ð°ÑианÑов бинаÑной ÑовмеÑÑимоÑÑи Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð²Ñзова ÑÑовнÑ, завиÑÑÑего Ð¾Ñ ÑовмеÑÑимоÑÑи. Слой ÑовмеÑÑимоÑÑи Linux(R) опÑеделÑÐµÑ Ð´Ð»Ñ ÑÑой Ñели пÑоÑедÑÑÑ `linux_sendsig`. + +[[linux-sendsig]] +==== Linux(R) sendsig + +ÐÑа пÑоÑедÑÑа ÑнаÑала пÑовеÑÑеÑ, ÑÑÑановлен ли Ñигнал Ñ Ñлагом `SA_SIGINFO`, в Ñаком ÑлÑÑае она вÑзÑÐ²Ð°ÐµÑ Ð¿ÑоÑедÑÑÑ `linux_rt_sendsig` вмеÑÑо ÑекÑÑей. Ðалее она вÑделÑÐµÑ (или повÑоÑно иÑполÑзÑÐµÑ Ñже ÑÑÑеÑÑвÑÑÑий) конÑекÑÑ Ð¾Ð±ÑабоÑÑика Ñигнала, заÑем ÑоÑмиÑÑÐµÑ ÑпиÑок аÑгÑменÑов Ð´Ð»Ñ Ð¾Ð±ÑабоÑÑика Ñигнала. Ðна пÑеобÑазÑÐµÑ Ð½Ð¾Ð¼ÐµÑ Ñигнала на оÑнове ÑаблиÑÑ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñигналов, назнаÑÐ°ÐµÑ Ð¾Ð±ÑабоÑÑик, пÑеобÑазÑÐµÑ sigset. ÐаÑем она ÑÐ¾Ñ ÑанÑÐµÑ ÐºÐ¾Ð½ÑекÑÑ Ð´Ð»Ñ Ð¿ ÑоÑедÑÑÑ `sigreturn` (ÑазлиÑнÑе ÑегиÑÑÑÑ, пÑеобÑазованнÑй Ð½Ð¾Ð¼ÐµÑ trap и маÑÐºÑ Ñигналов). ÐаконеÑ, она копиÑÑÐµÑ ÐºÐ¾Ð½ÑеРºÑÑ Ñигнала в полÑзоваÑелÑÑкое пÑоÑÑÑанÑÑво и подгоÑÐ°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÐºÐ¾Ð½ÑекÑÑ Ð´Ð»Ñ ÑакÑиÑеÑкого вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±ÑабоÑÑика Ñигнала. + +[[linux-rt-sendsig]] +==== linux_rt_sendsig + +ÐÑа пÑоÑедÑÑа аналогиÑна `linux_sendsig`, ÑолÑко подгоÑовка конÑекÑÑа Ñигнала оÑлиÑаеÑÑÑ. Ðна добавлÑÐµÑ `siginfo`, `ucontext` и некоÑоÑÑе ÑаÑÑи POSIX(R). СÑÐ¾Ð¸Ñ ÑаÑÑмоÑÑеÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð¾Ð±ÑÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑÑÐ¸Ñ Ð´Ð²ÑÑ ÑÑнкÑий Ñ Ð²Ñгодой в виде менÑÑего дÑблиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ð´Ð° и, возможно, даже более бÑÑÑÑого вÑполнениÑ. + +[[linux-sigreturn]] +==== linux_sigreturn + +ÐÑÐ¾Ñ ÑиÑÑемнÑй вÑзов иÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð²Ð¾Ð·Ð²ÑаÑа из обÑабоÑÑика Ñигнала. Ðн вÑполнÑÐµÑ Ð½ÐµÐºÐ¾ÑоÑÑе пÑовеÑки безопаÑноÑÑи и воÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¸ÑÑ Ð¾Ð´Ð½Ñй конÑекÑÑ Ð¿ÑоÑеÑÑа. Также он ÑазблокиÑÑÐµÑ Ñигнал в маÑке Ñигналов пÑоÑеÑÑа. + +[[ptrace]] +=== Ptrace + +Ðногие пÑоизводнÑе UNIX(R) ÑеализÑÑÑ ÑиÑÑемнÑй вÑзов man:ptrace[2] Ð´Ð»Ñ Ð¾Ð±ÐµÑпеÑÐµÐ½Ð¸Ñ ÑазлиÑнÑÑ ÑÑнкÑий оÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¸ оÑладки. ÐÑÐ¾Ñ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼ позволÑÐµÑ ÑÑаÑÑиÑÑÑÑÐµÐ¼Ñ Ð¿ÑоÑеÑÑÑ Ð¿Ð¾Ð»ÑÑаÑÑ ÑазлиÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ ÑÑаÑÑиÑÑемом пÑоÑеÑÑе, ÑакÑÑ ÐºÐ°Ðº Ð´Ð°Ð¼Ð¿Ñ ÑегиÑÑÑов, лÑбÑÑ Ð¿Ð°Ð¼ÑÑÑ Ð¸Ð· адÑеÑного пÑоÑÑÑанÑÑва пÑоÑеÑÑа и Ñ.д., а Ñакже ÑÑаÑÑиÑоваÑÑ Ð¿ÑоÑеÑÑ, напÑимеÑ, поÑагово вÑполнÑÑÑ Ð¸Ð½ÑÑÑÑкÑии или Ð¼ÐµÐ¶Ð´Ñ ÑиÑÑемнÑми вÑзовами (ÑиÑколлами и ловÑÑками). man:ptrace [2] Ñакже позволÑÐµÑ ÑÑÑанавливаÑÑ ÑазлиÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð² ÑÑаÑÑиÑÑемом пÑоÑеÑÑе (ÑегиÑÑÑÑ Ð¸ Ñ.д.). man:ptrace[2] ÑÐ²Ð»Ñ ÐµÑÑÑ ÑÑандаÑÑом Ð´Ð»Ñ UNIX(R), ÑеализованнÑм в болÑÑинÑÑве UNIX(R)-ÑиÑÑем по вÑÐµÐ¼Ñ Ð¼Ð¸ÑÑ. + +ÐмÑлÑÑÐ¸Ñ Linux(R) в FreeBSD ÑеализÑÐµÑ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼ man:ptrace[2] в Ñайле [.filename]#linux_ptrace.c#. ФÑнкÑии Ð´Ð»Ñ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑегиÑÑÑов Ð¼ÐµÐ¶Ð´Ñ Linux(R) и FreeBSD и ÑакÑиÑеÑкий ÑиÑÑемнÑй вÑзов ÑмÑлÑÑии man:ptrace[2]. СиÑÑемнÑй вÑзов пÑедÑÑавлÑÐµÑ Ñобой длиннÑй блок switch, коÑоÑÑй ÑеализÑÐµÑ Ñвой аналог в FreeBSD Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ man:ptrace[2]. ÐÐ¾Ð¼Ð°Ð½Ð´Ñ man:ptrace[2] в оÑновном Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ Ð¼ÐµÐ¶Ð´Ñ Linux(R) и FreeBSD, поÑÑÐ¾Ð¼Ñ Ð¾Ð±ÑÑно ÑÑебÑеÑÑÑ Ð»Ð¸ÑÑ Ð½ÐµÐ±Ð¾Ð»ÑÑÐ°Ñ Ð¼Ð¾Ð´Ð¸ÑикаÑиÑ. ÐапÑимеÑ, `PT_GETREGS` в Linux(R) ÑабоÑÐ°ÐµÑ Ñ Ð½Ð µÐ¿Ð¾ÑÑедÑÑвеннÑми даннÑми, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº FreeBSD иÑполÑзÑÐµÑ ÑказаÑÐµÐ»Ñ Ð½Ð° даннÑе, поÑÑÐ¾Ð¼Ñ Ð¿Ð¾Ñле вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ (наÑиР²Ð½Ð¾Ð³Ð¾) ÑиÑÑемного вÑзова man:ptrace[2] Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ вÑполниÑÑ copyout Ð´Ð»Ñ ÑÐ¾Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑеманÑики Linux(R). + +РеализаÑÐ¸Ñ man:ptrace[2] в Linuxulator Ð¸Ð¼ÐµÐµÑ Ð¸Ð·Ð²ÐµÑÑнÑе недоÑÑаÑки. ÐаблÑдалиÑÑ Ð¿Ð°Ð½Ð¸ÐºÐ¸ пÑи иÑполÑзовании `strace` (коÑоÑÑй ÑвлÑеÑÑÑ Ð¿Ð¾ÑÑебиÑелем man:ptrace[2]) в ÑÑеде Linuxulator. Также `PT_SYSCALL` не Ñеализован. + +[[traps]] +=== ÐовÑÑки (trap) + +ÐÑÑкий Ñаз, когда пÑоÑеÑÑ Linux(R), вÑполнÑÑÑийÑÑ Ð² Ñлое ÑмÑлÑÑии, вÑзÑÐ²Ð°ÐµÑ Ð¿ÑеÑÑвание (trap), Ñамо пÑеÑÑвание обÑабаÑÑваеÑÑÑ Ð¿ÑозÑаÑно, за иÑклÑÑением пÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑеÑÑваниÑ. Linux(R) и FreeBSD ÑаÑÑ Ð¾Ð´ÑÑÑÑ Ð²Ð¾ мнениÑÑ Ð¾ÑноÑиÑелÑно Ñого, ÑÑо ÑвлÑеÑÑÑ Ð¿ÑеÑÑванием, поÑÑÐ¾Ð¼Ñ ÑÑÐ¾Ñ Ð²Ð¾Ð¿ÑÐ¾Ñ ÑеÑаеÑÑÑ Ð·Ð´ÐµÑÑ. Ðод на Ñамом деле оÑÐµÐ½Ñ ÐºÐ¾ÑоÑкий: + +[.programlisting] +.... +static int +translate_traps(int signal, int trap_code) +{ + + if (signal != SIGBUS) + return signal; + + switch (trap_code) { + + case T_PROTFLT: + case T_TSSFLT: + case T_DOUBLEFLT: + case T_PAGEFLT: + return SIGSEGV; + + default: + return signal; + } +} +.... + +[[stack-fixup]] +=== ÐÑпÑавление ÑÑека + +ÐинамиÑеÑкий ÑедакÑÐ¾Ñ ÑвÑзей RTLD Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ Ñак назÑваемÑе AUX-Ñеги на ÑÑеке во вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ `execve`, поÑÑÐ¾Ð¼Ñ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ вÑполниÑÑ Ð¸ÑпÑавление, ÑÑÐ¾Ð±Ñ ÑÑо обеÑпеÑиÑÑ. ÐонеÑно, ÐºÐ°Ð¶Ð´Ð°Ñ ÑиÑÑема RTLD оÑлиÑаеÑÑÑ, поÑÑÐ¾Ð¼Ñ ÑÑÐ¾Ð²ÐµÐ½Ñ ÑмÑлÑÑии должен пÑедоÑÑавлÑÑÑ ÑобÑÑвеннÑÑ Ð¿ÑоÑедÑÑÑ Ð¸ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑÑека. Linuxulator Ð´ÐµÐ»Ð°ÐµÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ ÑÑо. ФÑнкÑÐ¸Ñ `elf_linux_fixup` пÑоÑÑо копиÑÑÐµÑ AUX-Ñеги на ÑÑек и коÑÑекÑиÑÑÐµÑ ÑÑек полÑзоваÑелÑÑкого пÑоÑеÑÑа, ÑÑÐ¾Ð±Ñ Ð¾Ð½ ÑказÑвал ÑÑаР·Ñ поÑле ÑÑÐ¸Ñ Ñегов. Таким обÑазом, RTLD ÑабоÑÐ°ÐµÑ ÑмнÑм ÑпоÑобом. + +[[aout-support]] +=== ÐоддеÑжка A.OUT + +ÐмÑлÑÑионнÑй Ñлой Linux(R) на i386 Ñакже поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð±Ð¸Ð½Ð°ÑнÑе ÑÐ°Ð¹Ð»Ñ Linux(R) в ÑоÑмаÑе A.OUT. ÐоÑÑи вÑÑ, ÑÑо опиÑано в пÑедÑдÑÑÐ¸Ñ ÑÐ°Ð·Ð´ÐµÐ»Ð°Ñ , должно бÑÑÑ Ñеализовано Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑжки A.OUT (кÑоме пеÑевода ловÑÑек и оÑпÑавки Ñигналов). ÐоддеÑжка бинаÑнÑÑ Ñайлов A.OUT болÑÑе не поддеÑживаеÑÑÑ, в ÑаÑÑноÑÑи, ÑмÑлÑÑÐ¸Ñ 2.6 Ñ Ð½Ð¸Ð¼Ð¸ не ÑабоÑаеÑ, но ÑÑо не вÑзÑÐ²Ð°ÐµÑ Ð½Ð¸ÐºÐ°ÐºÐ¸Ñ Ð¿Ñоблем, Ñак как linux-base в поÑÑÐ°Ñ , веÑоÑÑно, вообÑе не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð±Ð¸Ð½Ð°ÑнÑе ÑÐ°Ð¹Ð»Ñ A.OUT. ÐÑа поддеÑÐ ¶ÐºÐ°, ÑкоÑее вÑего, бÑÐ´ÐµÑ Ñдалена в бÑдÑÑем. ÐолÑÑÐ°Ñ ÑаÑÑÑ ÐºÐ¾Ð´Ð°, Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾Ð³Ð¾ Ð´Ð»Ñ Ð·Ð°Ð³ÑÑзки бинаÑнÑÑ Ñайлов Linux( R) A.OUT, Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð² Ñайле [.filename]#imgact_linux.c#. + +[[mi]] +== Слой ÑмÑлÑÑии Linux(R) - маÑино-незавиÑÐ¸Ð¼Ð°Ñ ÑаÑÑÑ + +Ð ÑÑом Ñазделе ÑаÑÑмаÑÑиваеÑÑÑ Ð¼Ð°Ñинно-незавиÑÐ¸Ð¼Ð°Ñ ÑаÑÑÑ Linuxulator. Ðн Ð¾Ñ Ð²Ð°ÑÑÐ²Ð°ÐµÑ Ð¸Ð½ÑÑаÑÑÑÑкÑÑÑÑ ÑмÑлÑÑии, Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼ÑÑ Ð´Ð»Ñ ÑмÑлÑÑии Linux(R) 2.6, ÑеализаÑÐ¸Ñ thread local storage (TLS) (на i386) и ÑÑÑÑекÑÑ. ÐаÑем Ð¼Ñ ÐºÑаÑко обÑÑждаем некоÑоÑÑе ÑиÑÑемнÑе вÑзовÑ. + +[[nptl-desc]] +=== ÐпиÑание NPTL + +Ðдним из оÑновнÑÑ Ð½Ð°Ð¿Ñавлений пÑогÑеÑÑа в ÑазÑабоÑке Linux(R) 2.6 ÑÑала поддеÑжка поÑоков. Ðо веÑÑии 2.6 поддеÑжка поÑоков в Linux(R) ÑеализовÑвалаÑÑ Ð² библиоÑеке linuxthreads. ÐÑа библиоÑека пÑедÑÑавлÑла Ñобой ÑаÑÑиÑнÑÑ ÑеализаÑÐ¸Ñ Ð¿Ð¾Ñоков POSIX(R). ÐоÑоки ÑоздавалиÑÑ ÐºÐ°Ðº оÑделÑнÑе пÑоÑеÑÑÑ Ñ Ð¸ÑполÑзованием ÑиÑÑемного вÑзова `clone`, ÑÑо позволÑло им ÑазделÑÑÑ Ð°Ð´ÑеÑное пÑоÑÑÑанÑÑво (и дÑÑгие ÑеÑÑÑÑÑ). ÐÑновнÑми недоÑÑаÑками Ñакого Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð° бÑли ÑазнÑе P ID Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ поÑока, некоÑÑекÑÐ½Ð°Ñ Ð¾Ð±ÑабоÑка Ñигналов (Ñ ÑоÑки зÑÐµÐ½Ð¸Ñ pthreads) и Ñ.д. ÐÑоме Ñого, пÑоизводиÑелÑнР¾ÑÑÑ Ð¾ÑÑавлÑла желаÑÑ Ð»ÑÑÑего (иÑполÑзование Ñигналов `SIGUSR` Ð´Ð»Ñ ÑÐ¸Ð½Ñ ÑонизаÑии поÑоков, поÑÑебление ÑеÑÑÑÑов ÑдÑа и Ñ.п.), поÑÑÐ¾Ð¼Ñ Ð´Ð»Ñ ÑеÑÐµÐ½Ð¸Ñ ÑÑÐ¸Ñ Ð¿Ñоблем бÑла ÑазÑабоÑана Ð½Ð¾Ð²Ð°Ñ ÑиÑÑема поÑоков под названием NPTL. + +ÐиблиоÑека NPTL бÑла ÑоÑÑедоÑоÑена на двÑÑ Ð²ÐµÑÐ°Ñ , но поÑвилаÑÑ ÑÑеÑÑÑ, поÑÑÐ¾Ð¼Ñ ÐµÑ Ð¾Ð±ÑÑно ÑÑиÑаÑÑ ÑаÑÑÑÑ NPTL. ÐÑими двÑÐ¼Ñ Ð²ÐµÑами бÑли вÑÑÑаивание поÑоков в ÑÑÑÑкÑÑÑÑ Ð¿ÑоÑеÑÑа и ÑÑÑÑекÑ. ÐополниÑелÑной ÑÑеÑÑей веÑÑÑ ÑÑал TLS, коÑоÑÑй не ÑÑебÑеÑÑÑ Ð½Ð°Ð¿ÑÑмÑÑ NPTL, но вÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑÐºÐ°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñека NPTL завиÑÐ¸Ñ Ð¾Ñ Ð½ÐµÐ³Ð¾. ÐÑи ÑлÑÑÑÐµÐ½Ð¸Ñ Ð¿Ñивели к знаÑиÑелÑÐ½Ð¾Ð¼Ñ ÑоÑÑÑ Ð¿ÑоизводиÑелÑноÑÑи и ÑооÑвеÑÑÑÐ²Ð¸Ñ ÑÑандаÑÑам. РнаÑÑоÑÑее вÑÐµÐ¼Ñ NPTL ÑвлÑеÑÑÑ ÑÑанд аÑÑной библиоÑекой поÑоков в ÑиÑÑÐµÐ¼Ð°Ñ Linux(R). + +РеализаÑÐ¸Ñ Linuxulator в FreeBSD Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð¸Ñ Ðº NPTL в ÑÑÑÑ Ð¾ÑновнÑÑ Ð½Ð°Ð¿ÑавлениÑÑ : TLS, ÑÑÑÑÐµÐºÑ Ð¸ изменение PID, ÑÑо пÑедназнаÑено Ð´Ð»Ñ ÑмÑлÑÑии поÑоков Linux(R). Ð ÑледÑÑÑÐ¸Ñ ÑÐ°Ð·Ð´ÐµÐ»Ð°Ñ Ð¾Ð¿Ð¸ÑÑваеÑÑÑ ÐºÐ°Ð¶Ð´Ð¾Ðµ из ÑÑÐ¸Ñ Ð½Ð°Ð¿Ñавлений. + +[[linux26-emu]] +=== ÐнÑÑаÑÑÑÑкÑÑÑа ÑмÑлÑÑии Linux(R) 2.6 + +ÐÑи ÑÐ°Ð·Ð´ÐµÐ»Ñ Ð¿Ð¾ÑвÑÑÐµÐ½Ñ ÑомÑ, как ÑпÑавлÑÑÑÑÑ Ð¿Ð¾Ñоки Linux(R) и как Ð¼Ñ Ð¼Ð¾Ð´ÐµÐ»Ð¸ÑÑем ÑÑо в FreeBSD. + +[[linux26-runtime]] +==== ÐпÑеделение ÑмÑлÑÑии 2.6 во вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ + +Слой ÑмÑлÑÑии Linux(R) в FreeBSD поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑкÑÑ Ð½Ð°ÑÑÑÐ¾Ð¹ÐºÑ ÑмÑлиÑÑемой веÑÑии. ÐÑо вÑполнÑеÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ man:sysctl[8], а именно `compat.linux.osrelease`. УÑÑановка ÑÑого man:sysctl[8] влиÑÐµÑ Ð½Ð° поведение ÑÐ»Ð¾Ñ ÑмÑлÑÑии во вÑÐµÐ¼Ñ Ð²ÑполнениÑ. ÐÑи ÑÑÑановке знаÑÐµÐ½Ð¸Ñ 2.6.x ÑÑÑанавливаеÑÑÑ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ `linux_use_linux26`, а пÑи ÑÑÑановке дÑÑгого знаÑÐµÐ½Ð¸Ñ Ð¾Ð½Ð° оÑÑаÑÑÑÑ ÑбÑоÑенной. ÐÑа пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ (а Ñакже аналогиÑнÑе пеÑеменнÑе Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ клеÑки) опÑеделÑеÑ, иÑполÑзÑеÑÑÑ Ð»Ð¸ в коде инÑÑаÑÑÑÑкÑÑÑа 2.6 (в оÑновном, пÑеобÑазование PID). ÐаÑÑÑойка веÑÑии пÑименÑеÑÑÑ Ð³Ð»Ð¾Ð±Ð°Ð»Ñно Ð´Ð»Ñ Ð²Ñей Ñ Ð¸ÑÑÐµÐ¼Ñ Ð¸ влиÑÐµÑ Ð½Ð° вÑе пÑоÑеÑÑÑ Linux(R). Ðе ÑледÑÐµÑ Ð¸Ð·Ð¼ÐµÐ½ÑÑÑ man:sysctl[8] во вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð»Ñбого бинаÑного Ñайла Linux(R), Ñак как ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑивеÑÑи к пÑоблемам. + +[[linux-proc-thread]] +==== ÐденÑиÑикаÑоÑÑ Ð¿ÑоÑеÑÑов и поÑоков Linux(R) + +СеманÑика поÑоков в Linux(R) немного запÑÑÐ°Ð½Ð½Ð°Ñ Ð¸ иÑполÑзÑÐµÑ ÑовеÑÑенно дÑÑгÑÑ ÑеÑÐ¼Ð¸Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ Ð¿Ð¾ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ñ FreeBSD. ÐÑоÑеÑÑ Ð² Linux(R) ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· `struct task`, вклÑÑаÑÑей два Ð¿Ð¾Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑов â PID и TGID. PID â ÑÑо _не_ иденÑиÑикаÑÐ¾Ñ Ð¿ÑоÑеÑÑа, а иденÑиÑикаÑÐ¾Ñ Ð¿Ð¾Ñока. TGID иденÑиÑиÑиÑÑÐµÑ Ð³ÑÑÐ¿Ð¿Ñ Ð¿Ð¾Ñоков, дÑÑгими Ñловами, пÑоÑеÑÑ. ÐÐ»Ñ Ð¾Ð´Ð½Ð¾Ð¿Ð¾ÑоÑного пÑоÑеÑÑа PID Ñавен TGID. + +ÐоÑок в NPTL â ÑÑо обÑÑнÑй пÑоÑеÑÑ, Ñ ÐºÐ¾ÑоÑого TGID не Ñавен PID и еÑÑÑ Ð³ÑÑпповой лидеÑ, оÑлиÑнÑй Ð¾Ñ Ð½ÐµÐ³Ð¾ Ñамого (и, конеÑно, обÑÐ°Ñ Ð²Ð¸ÑÑÑалÑÐ½Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ Ð¸ Ñ.д.). ÐÑе оÑÑалÑное пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ñак же, как и Ñ Ð¾Ð±ÑÑнÑм пÑоÑеÑÑом. ÐÐµÑ ÑÐ°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾Ð±Ñего ÑоÑÑоÑÐ½Ð¸Ñ Ð½Ð° внеÑнÑÑ ÑÑÑÑкÑÑÑÑ, как в FreeBSD. ÐÑо ÑÐ¾Ð·Ð´Ð°ÐµÑ Ð½ÐµÐºÐ¾ÑоÑое дÑблиÑование инÑоÑмаÑии и возможнÑÑ Ð½ÐµÑоглаÑованноÑÑÑ Ð´Ð°Ð½Ð½ÑÑ . ЯдÑо Linux(R), Ð¿Ð¾Ñ Ð¾Ð¶Ðµ, иÑполÑзÑÐµÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ задаÑе -> гÑÑппе в Ð¾Ð´Ð½Ð¸Ñ Ð¼ÐµÑÑÐ°Ñ Ð¸ ин ÑоÑмаÑÐ¸Ñ Ð¾ задаÑе в дÑÑÐ³Ð¸Ñ , ÑÑо не оÑÐµÐ½Ñ Ð¿Ð¾ÑледоваÑелÑно и вÑглÑÐ´Ð¸Ñ Ð½ÐµÐ±ÐµÐ·Ð¾Ð¿Ð°Ñно Ñ ÑоÑки зÑÐµÐ½Ð¸Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½ÑÑ Ð¾ÑÐ ¸Ð±Ð¾Ðº. + +ÐаждÑй поÑок NPTL ÑоздаеÑÑÑ Ð²Ñзовом ÑиÑÑемного вÑзова `clone` Ñ Ð¾Ð¿ÑеделеннÑм набоÑом Ñлагов (подÑобнее в ÑледÑÑÑем подÑазделе). NPTL ÑеализÑÐµÑ ÑÑÑогÑÑ Ð¼Ð¾Ð´ÐµÐ»Ñ Ð¿Ð¾Ñоков 1:1. + +Ð FreeBSD Ð¼Ñ ÑмÑлиÑÑем поÑоки NPTL Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¾Ð±ÑÑнÑÑ Ð¿ÑоÑеÑÑов FreeBSD, коÑоÑÑе ÑазделÑÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¿Ð°Ð¼ÑÑÑ Ð¸ Ñ.д., а гимнаÑÑика Ñ PID пÑоÑÑо имиÑиÑÑеÑÑÑ Ð² ÑпеÑиÑиÑеÑкой Ð´Ð»Ñ ÑмÑлÑÑии ÑÑÑÑкÑÑÑе, пÑикÑеплÑнной к пÑоÑеÑÑÑ. СÑÑÑкÑÑÑа, пÑикÑеплÑÐ½Ð½Ð°Ñ Ðº пÑоÑеÑÑÑ, вÑглÑÐ´Ð¸Ñ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +struct linux_emuldata { + pid_t pid; + + int *child_set_tid; /* in clone(): Child.s TID to set on clone */ + int *child_clear_tid;/* in clone(): Child.s TID to clear on exit */ + + struct linux_emuldata_shared *shared; + + int pdeath_signal; /* parent death signal */ + + LIST_ENTRY(linux_emuldata) threads; /* list of linux threads */ +}; +.... + +PID иÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии пÑоÑеÑÑа FreeBSD, к коÑоÑÐ¾Ð¼Ñ Ð¿ÑиÑоединена ÑÑа ÑÑÑÑкÑÑÑа. `child_se_tid` и `child_clear_tid` иÑполÑзÑÑÑÑÑ Ð´Ð»Ñ ÐºÐ¾Ð¿Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð°Ð´ÑеÑа TID пÑи завеÑÑении и Ñоздании пÑоÑеÑÑа. УказаÑÐµÐ»Ñ `shared` ÑказÑÐ²Ð°ÐµÑ Ð½Ð° ÑÑÑÑкÑÑÑÑ, ÑазделÑемÑÑ Ð¼ÐµÐ¶Ð´Ñ Ð¿Ð¾Ñоками. ÐеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ `pdeath_signal` опÑеделÑÐµÑ Ñигнал завеÑÑÐµÐ½Ð¸Ñ ÑодиÑелÑÑкого пÑоÑеÑÑа, а ÑказаÑÐµÐ»Ñ `threads` иÑполÑзÑеÑÑÑ Ð´Ð»Ñ ÑвÑзÑÐ²Ð°Ð½Ð¸Ñ ÑÑой ÑÑÑÑкÑÑÑÑ Ñо ÑпиÑком поÑоков. СÑÑÑкÑÑÑа `linux_emuldata_shared` вÑглÑÐ ´Ð¸Ñ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +struct linux_emuldata_shared { + + int refs; + + pid_t group_pid; + + LIST_HEAD(, linux_emuldata) threads; /* head of list of linux threads */ +}; +.... + +`refs` â ÑÑо ÑÑÑÑÑик ÑÑÑлок, иÑполÑзÑемÑй Ð´Ð»Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñа, когда можно оÑвободиÑÑ ÑÑÑÑкÑÑÑÑ, ÑÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ ÑÑеÑек памÑÑи. `group_pid` ÑлÑÐ¶Ð¸Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии PID (= TGID) вÑего пÑоÑеÑÑа (= гÑÑÐ¿Ð¿Ñ Ð¿Ð¾Ñоков). УказаÑÐµÐ»Ñ `threads` ÑвлÑеÑÑÑ Ð³Ð¾Ð»Ð¾Ð²Ð¾Ð¹ ÑпиÑка поÑоков в пÑоÑеÑÑе. + +СÑÑÑкÑÑÑÑ `linux_emuldata` можно полÑÑиÑÑ Ð¸Ð· пÑоÑеÑÑа Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ `em_find`. ÐÑоÑоÑип ÑÑнкÑии вÑглÑÐ´Ð¸Ñ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +struct linux_emuldata *em_find(struct proc *, int locked); +.... + +ÐдеÑÑ `proc` â ÑÑо пÑоÑеÑÑ, из коÑоÑого Ð¼Ñ Ñ Ð¾Ñим полÑÑиÑÑ ÑÑÑÑкÑÑÑÑ `emuldata`, а паÑамеÑÑ `locked` опÑеделÑеÑ, нÑжно ли блокиÑоваÑÑ. ÐопÑÑÑимÑе знаÑÐµÐ½Ð¸Ñ â `EMUL_DOLOCK` и `EMUL_DOUNLOCK`. ÐодÑобнее о блокиÑовке позже. + +[[pid-mangling]] +==== ÐÑеобÑазование PID + +ÐоÑколÑÐºÑ Ð¼ÐµÐ¶Ð´Ñ FreeBSD и Linux(R) ÑÑÑеÑÑвÑÑÑ ÑазлиÑÐ¸Ñ Ð² пÑедÑÑавлении иденÑиÑикаÑоÑа пÑоÑеÑÑа (PID) и иденÑиÑикаÑоÑа поÑока (TID), нам Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ пÑеобÑазовÑваÑÑ ÑÑи понÑÑиÑ. ÐÑо доÑÑигаеÑÑÑ Ð·Ð° ÑÑÑÑ Ð¼Ð¾Ð´Ð¸ÑикаÑии PID. ÐÑо ознаÑаеÑ, ÑÑо Ð¼Ñ Ð¸Ð·Ð¼ÐµÐ½Ñем пÑедÑÑавление о PID (=TGID) и TID (=PID) Ð¼ÐµÐ¶Ð´Ñ ÑдÑом и полÑзоваÑелÑÑким пÑоÑÑÑанÑÑвом. ÐÑновное пÑавило заклÑÑаеÑÑÑ Ð² ÑледÑÑÑем: в ÑдÑе (в Linuxulator) `PID = PID`, а `TGID = shared -> group_pid`; Ð´Ð»Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑкого пÑоÑÑÑанÑÑва Ð¼Ñ Ð¿ ÑедÑÑавлÑем `PID = shared -> group_pid` и `TID = proc -> p_pid`. Член `PID` в ÑÑÑÑкÑÑÑе `linux_emuldata` ÑвлÑеÑÑÑ FreeBSD PID. + +ÐÑÑеÑказанное в оÑновном влиÑÐµÑ Ð½Ð° ÑиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ getpid, getppid, gettid. Ð ÑлÑÑаÑÑ , где Ð¼Ñ Ð¸ÑполÑзÑем PID/TGID ÑооÑвеÑÑÑвенно. ÐÑи копиÑовании TID в `child_clear_tid` и `child_set_tid` Ð¼Ñ ÐºÐ¾Ð¿Ð¸ÑÑем FreeBSD PID. + +[[clone-syscall]] +==== СиÑÑемнÑй вÑзов clone + +`clone` â ÑÑо ÑиÑÑемнÑй вÑзов, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÐºÐ¾ÑоÑого ÑоздаÑÑÑÑ Ð¿Ð¾Ñоки в Linux(R). ÐÑоÑоÑип ÑиÑÑемного вÑзова вÑглÑÐ´Ð¸Ñ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +int linux_clone(l_int flags, void *stack, void *parent_tidptr, int dummy, +void * child_tidptr); +.... + +ÐаÑамеÑÑ `flags` ÑказÑÐ²Ð°ÐµÑ ÑиÑÑÐµÐ¼Ð½Ð¾Ð¼Ñ Ð²ÑзовÑ, как именно пÑоÑеÑÑÑ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÐºÐ»Ð¾Ð½Ð¸ÑованÑ. Ðак опиÑано вÑÑе, Linux(R) Ð¼Ð¾Ð¶ÐµÑ ÑоздаваÑÑ Ð¿ÑоÑеÑÑÑ, ÑазделÑÑÑие ÑазлиÑнÑе ÑеÑÑÑÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо, напÑимеÑ, два пÑоÑеÑÑа могÑÑ ÑазделÑÑÑ ÑайловÑе деÑкÑипÑоÑÑ, но не виÑÑÑалÑнÑÑ Ð¿Ð°Ð¼ÑÑÑ Ð¸ Ñ.д. ÐоÑледний Ð±Ð°Ð¹Ñ Ð¿Ð°ÑамеÑÑа `flags` ÑвлÑеÑÑÑ Ñигналом завеÑÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð²Ð½Ð¾Ð²Ñ Ñозданного пÑоÑеÑÑа. ÐаÑамеÑÑ `stack`, еÑли он не `NULL`, ÑказÑваеÑ, где Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ ÑÑек поÑока, а еÑли он `NULL`, пÑедполагаеÑÑÑ ÐºÐ¾Ð¿Ð¸Ñование пÑи запиÑи ÑÑека вÑзÑваÑÑего пÑоÑеÑÑа (Ñ.е. делаÑÑ Ñо же, ÑÑо Ð´ÐµÐ»Ð°ÐµÑ Ð¾Ð±ÑÑÐ ½Ð°Ñ ÑÑнкÑÐ¸Ñ man:fork[2]). ÐаÑамеÑÑ `parent_tidptr` иÑполÑзÑеÑÑÑ ÐºÐ°Ðº адÑÐµÑ Ð´Ð»Ñ ÐºÐ¾Ð¿Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ PID пÑоÑеÑÑа (Ñ.е. иденÑиÑикаÑоÑа поÑока) поÑле Ñого, как пÑоÑеÑÑ Ð´Ð¾ÑÑаÑоÑно иниÑиализиÑован, но еÑÑ Ð½Ðµ гоÑов к вÑполнениÑ. ÐаÑамеÑÑ `dummy` пÑиÑÑÑÑÑвÑÐµÑ Ð¸Ð·-за оÑÐµÐ½Ñ ÑÑÑанного ÑоглаÑÐµÐ½Ð¸Ñ Ð¾ вÑÐ·Ð¾Ð²Ð°Ñ ÑÑого ÑиÑÑемного вÑзова на i386. Ðн иÑполÑзÑÐµÑ ÑегиÑÑÑÑ Ð½Ð°Ð¿ÑÑмÑÑ Ð¸ не позволÑÐµÑ ÐºÐ¾Ð¼Ð¿Ð¸Ð»ÑÑоÑÑ Ð´ÐµÐ»Ð°ÑÑ ÑÑо, ÑÑо пÑÐ¸Ð²Ð¾Ð´Ð¸Ñ Ðº Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑикÑивного ÑиÑÑемногР¾ вÑзова. ÐаÑамеÑÑ `child_tidptr` иÑполÑзÑеÑÑÑ ÐºÐ°Ðº адÑÐµÑ Ð´Ð»Ñ ÐºÐ¾Ð¿Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ PID поÑле завеÑÑÐµÐ½Ð¸Ñ Ð²ÐµÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑоÑеÑÑа и п Ñи его завеÑÑении. + +СиÑÑемнÑй вÑзов пÑÐ¾Ð´Ð¾Ð»Ð¶Ð°ÐµÑ Ð²Ñполнение, ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°Ñ ÑооÑвеÑÑÑвÑÑÑие Ñлаги в завиÑимоÑÑи Ð¾Ñ Ð¿ÐµÑеданнÑÑ Ð°ÑгÑменÑов. ÐапÑимеÑ, `CLONE_VM` пÑеобÑазÑеÑÑÑ Ð² RFMEM (обÑее адÑеÑное пÑоÑÑÑанÑÑво) и Ñ.д. ÐдинÑÑÐ²ÐµÐ½Ð½Ð°Ñ ÑонкоÑÑÑ Ð·Ð´ÐµÑÑ â ÑÑо `CLONE_FS` и `CLONE_FILES`, поÑколÑÐºÑ FreeBSD не позволÑÐµÑ ÑÑÑанавливаÑÑ Ð¸Ñ Ð¾ÑделÑно, поÑÑÐ¾Ð¼Ñ Ð¼Ñ ÑмÑлиÑÑем ÑÑо, не ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°Ñ RFFDG (копиÑование ÑаблиÑÑ ÑайловÑÑ Ð´ÐµÑкÑипÑоÑов и дÑÑгой инÑоÑмаÑии о Ñайловой ÑиÑÑеме), еÑли задан Ð»Ñ Ð±Ð¾Ð¹ из ÑÑÐ¸Ñ Ñлагов. ÐÑо не вÑзÑÐ²Ð°ÐµÑ Ð¿Ñоблем, Ñак как ÑÑи Ñлаги вÑегда ÑÑÑанавливаÑÑÑÑ Ð²Ð¼ÐµÑÑе. ÐоÑле ÑÑÑановк и Ñлагов пÑоÑеÑÑ ÑоздаÑÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð²Ð½ÑÑÑенней пÑоÑедÑÑÑ `fork1`, пÑи ÑÑом пÑоÑеÑÑ Ð½Ð°ÑÑÑаиваеÑÑÑ Ñак, ÑÑÐ¾Ð±Ñ Ð½Ðµ помеÑаÑÑÑÑ Ð² оÑеÑÐµÐ´Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ (Ñ.е. не ÑÑановиÑÑÑÑ Ð¸ÑполнÑемÑм). ÐоÑле завеÑÑÐµÐ½Ð¸Ñ Ð²ÐµÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¼Ñ, пÑи Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи, изменÑем ÑодиÑÐµÐ»Ñ Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ пÑоÑеÑÑа, ÑÑÐ¾Ð±Ñ ÑмÑлиÑоваÑÑ ÑеманÑÐ¸ÐºÑ `CLONE_PARENT`. СледÑÑÑий Ñаг â Ñоздание даннÑÑ ÑмÑлÑÑии. ÐоÑоки в Linux(R) не оÑпÑавлÑÑÑ ÑÐ¸Ð³Ð½Ð°Ð»Ñ Ñвоим ÑодиÑелÑм, поÑÑÐ¾Ð¼Ñ Ð¼Ñ ÑÑÑанавливаем Ñигнал завеÑÑ ÐµÐ½Ð¸Ñ Ð² 0, ÑÑÐ¾Ð±Ñ Ð¾ÑклÑÑиÑÑ ÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ. ÐаÑем вÑполнÑеÑÑÑ Ð½Ð°ÑÑÑойка `child_set_tid` и `child_clear_tid`, ÑÑо акÑивиÑÑÐµÑ Ñ Ð¾Ð¾ÑвеÑÑÑвÑÑÑÑÑ ÑÑнкÑиоÐ! ½Ð°Ð»ÑноÑÑÑ Ð´Ð°Ð»ÐµÐµ в коде. Ðа ÑÑом ÑÑапе Ð¼Ñ ÐºÐ¾Ð¿Ð¸ÑÑем PID по адÑеÑÑ, ÑÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð¼Ñ Ð² `parent_tidptr`. УÑÑановка ÑÑека пÑоÑеÑÑа вÑполнÑеÑÑÑ Ð¿ÑоÑÑой пеÑезапиÑÑÑ ÑегиÑÑÑа `%esp` (`%rsp` на amd64) в кадÑе поÑока. Ðалее наÑÑÑаиваеÑÑÑ TLS Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ пÑоÑеÑÑа. ÐоÑле ÑÑого Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑмÑлиÑована ÑеманÑика man:vfork[2], и, наконеÑ, новÑй пÑоÑеÑÑ Ð¿Ð¾Ð¼ÐµÑаеÑÑÑ Ð² оÑеÑÐµÐ´Ñ Ð²ÑполнениÑ, а его PID возвÑаÑаеÑÑÑ ÑодиÑелÑÑÐºÐ¾Ð¼Ñ Ð¿ÑоÑеÑÑÑ ÑеÑез возвÑаÑаемое знаÑение `clone`. + +СиÑÑемнÑй вÑзов `clone` ÑпоÑобен и ÑакÑиÑеÑки иÑполÑзÑеÑÑÑ Ð´Ð»Ñ ÑмÑлÑÑии клаÑÑиÑеÑÐºÐ¸Ñ ÑиÑÑемнÑÑ Ð²Ñзовов man:fork[2] и man:vfork[2]. Ðолее новÑе веÑÑии glibc в ÑлÑÑае ÑдÑа 2.6 иÑполÑзÑÑÑ `clone` Ð´Ð»Ñ ÑеализаÑии ÑиÑÑемнÑÑ Ð²Ñзовов man:fork[2] и man:vfork[2]. + +[[locking]] +==== ÐлокиÑовка + +ÐлокиÑовка Ñеализована на ÑÑовне подÑиÑÑем, поÑколÑÐºÑ Ð½Ðµ ожидаеÑÑÑ Ð²ÑÑокой конкÑÑенÑии за ÑÑи ÑеÑÑÑÑÑ. СÑÑеÑÑвÑÐµÑ Ð´Ð²Ðµ блокиÑовки: `emul_lock`, иÑполÑзÑÐµÐ¼Ð°Ñ Ð´Ð»Ñ Ð·Ð°ÑиÑÑ Ð¼Ð°Ð½Ð¸Ð¿ÑлÑÑий Ñ `linux_emuldata`, и `emul_shared_lock`, иÑполÑзÑÐµÐ¼Ð°Ñ Ð´Ð»Ñ Ð¼Ð°Ð½Ð¸Ð¿ÑлÑÑий Ñ `linux_emuldata_shared`. `emul_lock` пÑедÑÑавлÑÐµÑ Ñобой неÑпÑÑий блокиÑÑÑÑий мÑÑÑекÑ, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº `emul_shared_lock` â ÑÑо ÑпÑÑий блокиÑÑÑÑий `sx_lock`. ÐлагодаÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовке на ÑÑовне подÑиÑÑем Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ обÑединÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе блоки Ñовки, поÑÑÐ¾Ð¼Ñ em_find пÑÐµÐ´Ð»Ð°Ð³Ð°ÐµÑ Ð´Ð¾ÑÑÑп без блокиÑовки. + +[[tls]] +=== TLS + +ÐÑÐ¾Ñ Ñаздел поÑвÑÑÑн TLS, Ñакже извеÑÑÐ½Ð¾Ð¼Ñ ÐºÐ°Ðº локалÑное Ñ ÑанилиÑе поÑока. + +[[trheading-intro]] +==== Ðведение в многопоÑоÑноÑÑÑ + +РкомпÑÑÑеÑнÑÑ Ð½Ð°ÑÐºÐ°Ñ Ð¿Ð¾Ñоки (threads) â ÑÑо ÑÑÑноÑÑи внÑÑÑи пÑоÑеÑÑа, коÑоÑÑе могÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑоваÑÑÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо дÑÑг Ð¾Ñ Ð´ÑÑга. ÐоÑоки в пÑоÑеÑÑе ÑазделÑÑÑ Ð¾Ð±Ñие даннÑе пÑоÑеÑÑа (напÑимеÑ, ÑайловÑе деÑкÑипÑоÑÑ), но Ñакже имеÑÑ Ñвой ÑобÑÑвеннÑй ÑÑек Ð´Ð»Ñ ÑÐ²Ð¾Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ . Ðногда Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑÑ Ð² даннÑÑ , ÑпеÑиÑиÑнÑÑ Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑеÑного поÑока, но доÑÑÑпнÑÑ Ð½Ð° ÑÑовне пÑоÑеÑÑа. ÐапÑимеÑ, Ð¸Ð¼Ñ Ð²ÑполнÑемого поÑока или ÑÑо-Ñо подобное. ТÑадиÑионР½Ñй API Ð´Ð»Ñ ÑабоÑÑ Ñ Ð¿Ð¾Ñоками в UNIX® â pthreads â пÑедоÑÑавлÑÐµÑ ÑпоÑоб ÑделаÑÑ ÑÑо ÑеÑез ÑÑнкÑии `man:pthread_key_create[3]`, `man :pthread_setspecific[3]` и `man:pthread_getspecific[3]`, где поÑок Ð¼Ð¾Ð¶ÐµÑ ÑоздаÑÑ ÐºÐ»ÑÑ Ðº локалÑнÑм даннÑм поÑока и иÑполÑзоваÑÑ `man:pthread_getspecific[3]` или `man:pthread_getspecific[3]` Ð´Ð»Ñ ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑÑими даннÑми. Ðегко замеÑиÑÑ, ÑÑо ÑÑо не ÑамÑй ÑдобнÑй ÑпоÑоб. ÐоÑÑÐ¾Ð¼Ñ ÑазлиÑнÑе ÑазÑабоÑÑики компилÑÑоÑов C/C++ пÑедложили более ÑдобнÑй меÑод. Ðни ввели новое клÑÑевое Ñлово `thread`, коÑоÑое ÑказÑваеÑ, ÑÑо пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ ÑвлÑеÑÑÑ ÑпеÑиÑиÑной Ð´Ð»Ñ Ð¿Ð¾Ñока. Также бÑл ÑазÑабоÑан новÑй меÑод дР¾ÑÑÑпа к Ñаким пеÑеменнÑм (по кÑайней меÑе, на аÑÑ Ð¸ÑекÑÑÑе i386). ÐеÑод pthreads обÑÑно ÑеализÑеÑÑÑ Ð² полÑзоваÑелÑÑ ÐºÐ¾Ð¼ пÑоÑÑÑанÑÑве в виде ! пÑоÑÑой ÑаблиÑÑ Ð¿Ð¾Ð¸Ñка. ÐÑоизводиÑелÑноÑÑÑ Ñакого ÑеÑÐµÐ½Ð¸Ñ Ð½Ðµ оÑÐµÐ½Ñ Ð²ÑÑока. ÐовÑй меÑод иÑполÑзÑÐµÑ (на i386) ÑегменÑнÑе ÑегиÑÑÑÑ Ð´Ð»Ñ Ð°Ð´ÑеÑаÑии облаÑÑи, где Ñ ÑаниÑÑÑ TLS (Thread-Local Storage), Ñак ÑÑо ÑакÑиÑеÑкий доÑÑÑп к пеÑеменной поÑока ÑводиÑÑÑ Ðº Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑегменÑного ÑегиÑÑÑа к адÑеÑÑ, Ñаким обÑазом обÑаÑаÑÑÑ ÑеÑез него. СегменÑнÑе ÑегиÑÑÑÑ, обÑÑно `%gs` и `%fs`, дейÑÑвÑÑÑ ÐºÐ°Ðº ÑелекÑоÑÑ ÑегменÑов. ÐаждÑй поÑок Ð¸Ð¼ÐµÐµÑ ÑÐ²Ð¾Ñ ÑобÑÑвеннÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ, где Ñ ÑанÑÑÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑе даннÑе поÑока, и ÑÐµÐ³Ð¼ÐµÐ½Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ загÑÑжаÑÑÑÑ Ð¿Ñи каждом пеÑеклÑÑении конÑекÑÑа. ÐÑÐ¾Ñ Ð¼ÐµÑ Ð¾Ð´ оÑÐµÐ½Ñ Ð±ÑÑÑÑÑй и иÑполÑзÑеÑÑÑ Ð¿ÑакÑиÑеÑки повÑемеÑÑно в миÑе UNIX® на аÑÑ Ð¸ÑекÑÑÑе i386. Ð FreeBSD, и Linux® ÑеализÑÑÑ ÑÑÐ¾Ñ Ð¿Ð¾Ð´Ñ Ð¾Ð´, и он даÑÑ Ð¾ÑÐµÐ½Ñ Ñ Ð¾ÑоÑие ÑезÑлÑÑаÑÑ. ÐдинÑÑвеннÑй недоÑÑаÑок â Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑÑ Ð¿ÐµÑезагÑÑжаÑÑ ÑÐµÐ³Ð¼ÐµÐ½Ñ Ð¿Ñи каждом пеÑеклÑÑении конÑекÑÑа, ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð¼ÐµÐ´Ð»ÑÑÑ Ð¿ÐµÑеклÑÑениÑ. FreeBSD пÑÑаеÑÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð¸Ð·Ð¸ÑоваÑÑ ÑÑи накладнÑе ÑаÑÑ Ð¾Ð´Ñ, иÑполÑзÑÑ ÑолÑко 1 деÑкÑипÑÐ¾Ñ ÑегменÑа, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº Linux® иÑполÑзÑÐµÑ 3. ÐнÑеÑеÑно, ÑÑо поÑÑи ниÑÑо не иÑполÑзÑÐµÑ Ð±Ð¾Ð»ÑÑе 1 деÑкÑипÑоÑа (ÑолÑко Wine, кажеÑÑÑ, иÑполÑзÑÐµÑ 2), поÑÑÐ¾Ð¼Ñ Linux® плаÑÐ¸Ñ ÑÑÑ Ð½ÐµÐ¾Ð±ÑзаÑе лÑнÑÑ ÑÐµÐ½Ñ Ð¿Ñи пеÑеклÑÑÐ! µÐ½Ð¸Ð¸ Ð! ºÐ¾Ð½ÑекÑÑов. + +[[i386-segs]] +==== СегменÑÑ Ð½Ð° i386 + +ÐÑÑ Ð¸ÑекÑÑÑа i386 ÑеализÑÐµÑ Ñак назÑваемÑе ÑегменÑÑ. Ð¡ÐµÐ³Ð¼ÐµÐ½Ñ â ÑÑо опиÑание облаÑÑи памÑÑи. Ðн вклÑÑÐ°ÐµÑ Ð±Ð°Ð·Ð¾Ð²Ñй адÑÐµÑ (наÑало) облаÑÑи памÑÑи, ÐµÑ ÐºÐ¾Ð½ÐµÑ (гÑаниÑÑ), Ñип, заÑиÑÑ Ð¸ Ñ.д. ÐоÑÑÑп к памÑÑи, опиÑÑваемой ÑегменÑом, Ð¼Ð¾Ð¶ÐµÑ Ð¾ÑÑÑеÑÑвлÑÑÑÑÑ Ñ Ð¸ÑполÑзованием ÑегиÑÑÑов ÑелекÑоÑов ÑегменÑов (`%cs`, `%ds`, `%ss`, `%es`, `%fs`, `%gs`). ÐапÑимеÑ, пÑедположим, ÑÑо Ñ Ð½Ð°Ñ ÐµÑÑÑ ÑÐµÐ³Ð¼ÐµÐ½Ñ Ñ Ð±Ð°Ð·Ð¾Ð²Ñм адÑеÑом 0x1234 и длиной, а Ñакже ÑледÑÑÑий код: + +[.programlisting] +.... +mov %edx,%gs:0x10 +.... + +ÐÑо загÑÑÐ·Ð¸Ñ ÑодеÑжимое ÑегиÑÑÑа `%edx` в ÑÑÐµÐ¹ÐºÑ Ð¿Ð°Ð¼ÑÑи по адÑеÑÑ 0x1244. ÐекоÑоÑÑе ÑегменÑнÑе ÑегиÑÑÑÑ Ð¸Ð¼ÐµÑÑ ÑпеÑиалÑное назнаÑение, напÑимеÑ, `%cs` иÑполÑзÑеÑÑÑ Ð´Ð»Ñ ÑегменÑа кода, а `%ss` â Ð´Ð»Ñ ÑегменÑа ÑÑека, но `%fs` и `%gs` обÑÑно не иÑполÑзÑÑÑÑÑ. СегменÑÑ Ñ ÑанÑÑÑÑ Ð»Ð¸Ð±Ð¾ в глобалÑной ÑаблиÑе GDT, либо в локалÑной ÑаблиÑе LDT. ÐоÑÑÑп к LDT оÑÑÑеÑÑвлÑеÑÑÑ ÑеÑез запиÑÑ Ð² GDT. LDT Ð¼Ð¾Ð¶ÐµÑ Ñ ÑаниÑÑ Ð±Ð¾Ð»ÑÑе Ñипов ÑегменÑов. LDT Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾ÑделÑной Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пÑÐ¾Ñ ÐµÑÑа. Ðбе ÑаблиÑÑ Ð¾Ð¿ÑеделÑÑÑ Ð´Ð¾ 8191 запиÑей. + +[[linux-i386]] +==== РеализаÑÐ¸Ñ Ð½Ð° Linux(R) i386 + +СÑÑеÑÑвÑÐµÑ Ð´Ð²Ð° оÑновнÑÑ ÑпоÑоба наÑÑÑойки TLS в Linux(R). Ðн Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½Ð°ÑÑÑоен пÑи клониÑовании пÑоÑеÑÑа Ñ Ð¸ÑполÑзованием ÑиÑÑемного вÑзова `clone` или Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð²Ñзова `set_thread_area`. Ðогда пÑоÑеÑÑ Ð¿ÐµÑÐµÐ´Ð°ÐµÑ Ñлаг `CLONE_SETTLS` в `clone`, ÑдÑо ожидаеÑ, ÑÑо памÑÑÑ, на коÑоÑÑÑ ÑказÑÐ²Ð°ÐµÑ ÑегиÑÑÑ `%esi`, бÑÐ´ÐµÑ ÑодеÑжаÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑкое пÑедÑÑавление ÑегменÑа в Linux(R), коÑоÑое пÑеобÑазÑеÑÑÑ Ð² маÑинное пÑедÑÑавление ÑегменÑа и загÑÑжаеÑÑÑ Ð² ÑÐ»Ð¾Ñ GDT. Ð¡Ð»Ð¾Ñ GDT Ð¼Ð¾Ð¶ÐµÑ Ð ±ÑÑÑ Ñказан номеÑом или можно иÑполÑзоваÑÑ -1, ÑÑо ознаÑаеÑ, ÑÑо ÑиÑÑема Ñама должна вÑбÑаÑÑ Ð¿ÐµÑвÑй ÑвободнÑй ÑлоÑ. Ðа пÑакÑике подавлÑÑÑее болÑÑинÑÑво пÑогÑамм иÑполÑзÑÑÑ ÑолÑко Ð¾Ð´Ð½Ñ Ð·Ð°Ð¿Ð¸ÑÑ TLS и не забоÑÑÑÑÑ Ð¾ номеÑе запиÑи. ÐÑ Ð¸ÑполÑзÑем ÑÑо в ÑмÑлÑÑии и ÑакÑиÑеÑки завиÑим Ð¾Ñ ÑÑого. + +[[tls-emu]] +==== ÐмÑлÑÑÐ¸Ñ Linux(R) TLS + +[[tls-i386]] +===== i386 + +ÐагÑÑзка TLS Ð´Ð»Ñ ÑекÑÑего поÑока пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð¿ÑÑем вÑзова `set_thread_area`, Ñогда как загÑÑзка TLS Ð´Ð»Ñ Ð²ÑоÑого пÑоÑеÑÑа в `clone` вÑполнÑеÑÑÑ Ð² оÑделÑном блоке в `clone`. ÐÑи две ÑÑнкÑии оÑÐµÐ½Ñ Ð¿Ð¾Ñ Ð¾Ð¶Ð¸. ÐдинÑÑвенное ÑазлиÑие заклÑÑаеÑÑÑ Ð² ÑакÑиÑеÑкой загÑÑзке ÑегменÑа GDT, коÑоÑÐ°Ñ Ð¿ÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð¿Ñи ÑледÑÑÑем пеÑеклÑÑении конÑекÑÑа Ð´Ð»Ñ Ð²Ð½Ð¾Ð²Ñ Ñозданного пÑоÑеÑÑа, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº `set_thread_area` должен загÑÑзиÑÑ ÐµÐ³Ð¾ напÑÑмÑÑ. Ðод в оÑновном Ð´ÐµÐ»Ð°ÐµÑ ÑледÑÑÑее. Ðн копР¸ÑÑÐµÑ Ð´ÐµÑкÑипÑÐ¾Ñ ÑегменÑа в ÑоÑмаÑе Linux(R) из полÑзоваÑелÑÑкого пÑоÑÑÑанÑÑва. Ðод пÑовеÑÑÐµÑ Ð½Ð¾Ð¼ÐµÑ Ð´ÐµÑкÑипÑÐ¾Ñ Ð°, но поÑколÑÐºÑ Ð¾Ð½ ÑазлиÑаеÑÑÑ Ð¼ÐµÐ¶Ð´Ñ FreeBSD и Linux(R), Ð¼Ñ Ð½ÐµÐ¼Ð½Ð¾Ð³Ð¾ имиÑиÑÑем его. ÐÑ Ð¿Ð¾Ð´Ð´ÐµÑживаем ÑолÑко индекÑÑ 6, 3 и -1. ЧиÑло 6 â ÑÑо оÑигиналÑнÑй Ð½Ð¾Ð¼ÐµÑ Linux(R), 3 â оÑигиналÑнÑй Ð½Ð¾Ð¼ÐµÑ FreeBSD, а -1 ознаÑÐ°ÐµÑ Ð°Ð²Ñо-вÑбоÑ. ÐаÑем Ð¼Ñ ÑÑÑанавливаем Ð½Ð¾Ð¼ÐµÑ Ð´ÐµÑкÑипÑоÑа на конÑÑанÑÑ 3 и копиÑÑем его обÑаÑно в полÑзоваÑелÑÑкое пÑоÑÑÑанÑÑво. ÐÑ Ð¿Ð¾Ð»Ð°Ð³Ð°ÐµÐ¼ÑÑ Ð½Ð° Ñо, ÑÑо пÑоÑеÑÑ Ð² полÑзоваÑелÑÑком пÑоÑÑÑанÑÑве иÑполÑзÑÐµÑ Ð½Ð¾Ð¼ÐµÑ Ð¸Ð· деÑкÑипÑоÑа, но ÑÑо ÑабоÑÐ°ÐµÑ Ð² болÑÑ Ð¸Ð½ÑÑве ÑлÑÑаев (никогда не вÑÑÑеÑалоÑÑ ÑиÑÑаÑии, когда ÑÑо не ÑÑабаÑÑвало), Ñак как пÑоÑеÑÑ Ð² полÑзоваÑелÑÑÐ ºÐ¾Ð¼ пÑоÑÑÑанÑÑве обÑÑно ! пеÑÐµÐ´Ð°ÐµÑ 1. ÐаÑем Ð¼Ñ Ð¿ÑеобÑазÑем деÑкÑипÑÐ¾Ñ Ð¸Ð· ÑоÑмаÑа Linux(R) в маÑинно-завиÑимÑÑ ÑоÑÐ¼Ñ (Ñ.е. незавиÑимÑÑ Ð¾Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑемÑ) и копиÑÑем его в деÑкÑипÑÐ¾Ñ ÑегменÑа, опÑеделеннÑй FreeBSD. ÐаконеÑ, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ загÑÑзиÑÑ ÐµÐ³Ð¾. ÐÑ Ð½Ð°Ð·Ð½Ð°Ñаем деÑкÑипÑÐ¾Ñ PCB поÑока (блок ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑоÑеÑÑом) и загÑÑжаем ÑÐµÐ³Ð¼ÐµÐ½Ñ `%gs` Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ `load_gs`. ÐÑа загÑÑзка должна вÑполнÑÑÑÑÑ Ð² кÑиÑиÑеÑкой ÑекÑии, ÑÑÐ¾Ð±Ñ Ð½Ð¸ÑÑо не могло Ð½Ð°Ñ Ð¿ÑеÑваÑÑ. СлÑÑай `CLONE_SETTLS` ÑабоÑÐ°ÐµÑ ÑоÑно Ñак же, ÑолÑко загÑÑзка Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ `load_gs` не вÑполнÑеÑÑÑ. СегменÑ, иÑполÑзÑемÑй Ð´Ð»Ñ ÑÑого (ÑÐµÐ³Ð¼ÐµÐ½Ñ Ð½Ð¾Ð¼ÐµÑ 3), ÑазР´ÐµÐ»ÑеÑÑÑ Ð¼ÐµÐ¶Ð´Ñ Ð¿ÑоÑеÑÑами FreeBSD и Linux(R), поÑÑÐ¾Ð¼Ñ Ñлой ÑмÑлÑÑии Linux(R) не добавлÑÐµÑ Ð½Ð°ÐºÐ»Ð°Ð´Ð½ÑÑ ÑаÑÑ Ð¾Ð´Ð¾Ð² по ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ñ Ð¾Ð±ÑÑнÑм FreeBSD. + +[[tls-amd64]] +===== amd64 + +РеализаÑÐ¸Ñ amd64 аналогиÑна ÑеализаÑии i386, но изнаÑалÑно не иÑполÑзовалÑÑ 32-биÑнÑй деÑкÑипÑÐ¾Ñ ÑегменÑа Ð´Ð»Ñ ÑÑой Ñели (поÑÑÐ¾Ð¼Ñ Ð´Ð°Ð¶Ðµ наÑивнÑе полÑзоваÑели 32-биÑного TLS не ÑабоÑали), поÑÑÐ¾Ð¼Ñ Ð½Ð°Ð¼ пÑиÑлоÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ñакой ÑÐµÐ³Ð¼ÐµÐ½Ñ Ð¸ ÑеализоваÑÑ ÐµÐ³Ð¾ загÑÑÐ·ÐºÑ Ð¿Ñи каждом пеÑеклÑÑении конÑекÑÑа (когда ÑÑÑановлен Ñлаг, ÑигнализиÑÑÑÑий о иÑполÑзовании 32-биÑного Ñежима). ÐÑоме ÑÑого, загÑÑзка TLS ÑоÑно ÑÐ°ÐºÐ°Ñ Ð¶Ðµ, ÑолÑко номеÑа ÑегменÑов оÑлиÑаÑÑÑÑ, а ÑоÑÐ¼Ð°Ñ Ð´ÐµÑкÑипÑоÑа и загÑÑзка немного ÑазлиÑаÑÑÑÑ. + +[[futexes]] +=== ФÑÑÑекÑÑ + +[[sync-intro]] +==== Ðведение в ÑÐ¸Ð½Ñ ÑонизаÑÐ¸Ñ + +ÐоÑокам ÑÑебÑеÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÐ°Ñ ÑÐ¸Ð½Ñ ÑонизаÑиÑ, и POSIX(R) пÑедоÑÑавлÑÐµÑ Ð½ÐµÑколÑко ÐµÑ Ð²Ð¸Ð´Ð¾Ð²: мÑÑÑекÑÑ Ð´Ð»Ñ Ð²Ð·Ð°Ð¸Ð¼Ð½Ð¾Ð³Ð¾ иÑклÑÑениÑ, блокиÑовки ÑÑениÑ-запиÑи Ð´Ð»Ñ Ð²Ð·Ð°Ð¸Ð¼Ð½Ð¾Ð³Ð¾ иÑклÑÑÐµÐ½Ð¸Ñ Ñ Ð¿Ñеобладанием опеÑаÑий ÑÑÐµÐ½Ð¸Ñ Ð½Ð°Ð´ запиÑÑми и ÑÑловнÑе пеÑеменнÑе Ð´Ð»Ñ ÑигнализаÑии об изменении ÑоÑÑоÑниÑ. ÐнÑеÑеÑно оÑмеÑиÑÑ, ÑÑо в API поÑоков POSIX(R) оÑÑÑÑÑÑвÑÐµÑ Ð¿Ð¾Ð´Ð´ÐµÑжка ÑемаÑоÑов. РеализаÑии ÑÑÐ¸Ñ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼Ð¾Ð² ÑÐ¸Ð½Ñ ÑонизаÑии ÑилÑно завиÑÑÑ Ð¾Ñ Ñипа поддеÑжки поÑÐ ¾ÐºÐ¾Ð², коÑоÑÐ°Ñ Ñ Ð½Ð°Ñ ÐµÑÑÑ. Ð ÑиÑÑой модели 1:M (полÑзоваÑелÑÑкое пÑоÑÑÑанÑÑво) ÑеализаÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²Ñполнена Ð ¸ÑклÑÑиÑелÑно в полÑзоваÑелÑÑком пÑоÑÑÑанÑÑве и, ÑледоваÑелÑно, бÑÑÑ Ð¾ÑÐµÐ½Ñ Ð±ÑÑÑÑой (ÑÑловнÑе пеÑеменнÑе, веÑоÑÑно, бÑдÑÑ ÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ Ñ Ð¸ÑполÑзованием Ñигналов, Ñ.е. не бÑÑÑÑо) и пÑоÑÑой. Рмодели 1:1 ÑиÑÑаÑÐ¸Ñ Ñакже доволÑно ÑÑна â поÑоки Ð´Ð¾Ð»Ð¶Ð½Ñ ÑÐ¸Ð½Ñ ÑонизиÑоваÑÑÑÑ Ñ Ð¸ÑполÑзованием ÑÑедÑÑв ÑдÑа (ÑÑо оÑÐµÐ½Ñ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾, поÑколÑÐºÑ ÑÑебÑеÑÑÑ Ð²Ñполнение ÑиÑÑемного вÑзова). СмеÑаннÑй ÑÑенаÑий M:N пÑоÑÑо комбиниÑÑÐµÑ Ð¿ÐµÑвÑй и вÑоÑой Ð¿Ð¾Ð´Ñ Ð¾Ð´Ñ Ð¸Ð»Ð¸ п олагаеÑÑÑ Ð¸ÑклÑÑиÑелÑно на ÑдÑо. Ð¡Ð¸Ð½Ñ ÑонизаÑÐ¸Ñ Ð¿Ð¾Ñоков ÑвлÑеÑÑÑ Ð²Ð°Ð¶Ð½Ð¾Ð¹ ÑаÑÑÑÑ Ð¿ÑогÑаммиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ñ Ð¸ÑполÑзо ванием поÑоков, и ÐµÑ Ð¿ÑоÐ! ¸Ð·Ð²Ð¾Ð´Ð¸ÑелÑноÑÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð·Ð½Ð°ÑиÑелÑно влиÑÑÑ Ð½Ð° иÑоговÑÑ Ð¿ÑогÑаммÑ. Ðедавние ÑеÑÑÑ Ð² опеÑаÑионной ÑиÑÑеме FreeBSD показали, ÑÑо ÑлÑÑÑÐµÐ½Ð½Ð°Ñ ÑеализаÑÐ¸Ñ `sx_lock` дала 40% пÑиÑоÑÑа ÑкоÑоÑÑи в _ZFS_ (где акÑивно иÑполÑзÑÑÑÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовки sx), ÑÑо внÑÑÑенние Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼Ñ ÑдÑа, но ÑÑо наглÑдно демонÑÑÑиÑÑеÑ, наÑколÑко важна пÑоизводиÑелÑноÑÑÑ Ð¿ÑимиÑивов ÑÐ¸Ð½Ñ ÑонизаÑии. + +ÐногопоÑоÑнÑе пÑогÑÐ°Ð¼Ð¼Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð½Ð°Ð¿Ð¸ÑÐ°Ð½Ñ Ñ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»Ñной конкÑÑенÑией за блокиÑовки. РпÑоÑивном ÑлÑÑае, вмеÑÑо вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾Ð¹ ÑабоÑÑ Ð¿Ð¾Ñок пÑоÑÑо Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ Ð±Ð»Ð¾ÐºÐ¸ÑовкÑ. Ð ÑезÑлÑÑаÑе, наиболее Ñ Ð¾ÑоÑо напиÑаннÑе многопоÑоÑнÑе пÑогÑÐ°Ð¼Ð¼Ñ Ð´ÐµÐ¼Ð¾Ð½ÑÑÑиÑÑÑÑ Ð½Ð¸Ð·ÐºÑÑ ÐºÐ¾Ð½ÐºÑÑенÑÐ¸Ñ Ð·Ð° блокиÑовки. + +[[futex-intro]] +==== Ðведение в ÑÑÑÑекÑÑ + +Linux(R) ÑеализÑÐµÑ 1:1 поÑоковÑÑ Ð¼Ð¾Ð´ÐµÐ»Ñ, Ñо еÑÑÑ Ð¸ÑполÑзÑÐµÑ Ð¿ÑимиÑÐ¸Ð²Ñ ÑÐ¸Ð½Ñ ÑонизаÑии в ÑдÑе. Ðак ÑпоминалоÑÑ Ñанее, Ñ Ð¾ÑоÑо напиÑаннÑе многопоÑоÑнÑе пÑогÑÐ°Ð¼Ð¼Ñ Ð¸Ð¼ÐµÑÑ Ð½Ð¸Ð·ÐºÑÑ ÐºÐ¾Ð½ÐºÑÑенÑÐ¸Ñ Ð·Ð° блокиÑовки. Таким обÑазом, ÑипиÑÐ½Ð°Ñ Ð¿Ð¾ÑледоваÑелÑноÑÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð²ÑполнÑÑÑÑÑ ÐºÐ°Ðº два аÑомаÑнÑÑ ÑвелиÑениÑ/ÑменÑÑÐµÐ½Ð¸Ñ ÑÑÑÑÑика ÑÑÑлок мÑÑÑекÑа, ÑÑо оÑÐµÐ½Ñ Ð±ÑÑÑÑо, как показано в ÑледÑÑÑем пÑимеÑе: + +[.programlisting] +.... +pthread_mutex_lock(&mutex); +... +pthread_mutex_unlock(&mutex); +.... + +1:1 threading вÑнÑÐ¶Ð´Ð°ÐµÑ Ð½Ð°Ñ Ð²ÑполнÑÑÑ Ð´Ð²Ð° ÑиÑÑемнÑÑ Ð²Ñзова Ð´Ð»Ñ ÑÑÐ¸Ñ Ð²Ñзовов мÑÑÑекÑа, ÑÑо оÑÐµÐ½Ñ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾. + +РеÑение, Ñеализованное в Linux(R) 2.6, назÑваеÑÑÑ ÑÑÑÑекÑÑ. ФÑÑÑекÑÑ Ð²ÑполнÑÑÑ Ð¿ÑовеÑÐºÑ Ð½Ð° конкÑÑенÑÐ¸Ñ Ð² полÑзоваÑелÑÑком пÑоÑÑÑанÑÑве и вÑзÑваÑÑ Ð¿ÑимиÑÐ¸Ð²Ñ ÑдÑа ÑолÑко в ÑлÑÑае конкÑÑенÑии. Таким обÑазом, ÑипиÑнÑй ÑлÑÑай Ð¾Ð±Ñ Ð¾Ð´Ð¸ÑÑÑ Ð±ÐµÐ· вмеÑаÑелÑÑÑва ÑдÑа. ÐÑо обеÑпеÑÐ¸Ð²Ð°ÐµÑ Ð´Ð¾ÑÑаÑоÑно бÑÑÑÑÑÑ Ð¸ гибкÑÑ ÑеализаÑÐ¸Ñ Ð¿ÑимиÑивов ÑÐ¸Ð½Ñ ÑонизаÑии. + +[[futex-api]] +==== API ÑÑÑÑекÑов + +СиÑÑемнÑй вÑзов futex вÑглÑÐ´Ð¸Ñ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +int futex(void *uaddr, int op, int val, struct timespec *timeout, void *uaddr2, int val3); +.... + +Ð ÑÑом пÑимеÑе `uaddr` â ÑÑо адÑÐµÑ Ð¼ÑÑÑекÑа в полÑзоваÑелÑÑком пÑоÑÑÑанÑÑве, `op` â опеÑаÑиÑ, коÑоÑÑÑ Ð¼Ñ ÑобиÑаемÑÑ Ð²ÑполниÑÑ, а оÑÑалÑнÑе паÑамеÑÑÑ Ð¸Ð¼ÐµÑÑ Ð·Ð½Ð°Ñение, завиÑÑÑее Ð¾Ñ ÐºÐ¾Ð½ÐºÑеÑной опеÑаÑии. + +ФÑÑÑекÑÑ ÑеализÑÑÑ ÑледÑÑÑие опеÑаÑии: + +* `FUTEX_WAIT` +* `FUTEX_WAKE` +* `FUTEX_FD` +* `FUTEX_REQUEUE` +* `FUTEX_CMP_REQUEUE` +* `FUTEX_WAKE_OP` + +[[futex-wait]] +===== FUTEX_WAIT + +ÐÑа опеÑаÑÐ¸Ñ Ð¿ÑовеÑÑеÑ, ÑÑо по адÑеÑÑ `uaddr` запиÑано знаÑение `val`. ÐÑли неÑ, возвÑаÑаеÑÑÑ `EWOULDBLOCK`, в пÑоÑивном ÑлÑÑае поÑок ÑÑавиÑÑÑ Ð² оÑеÑÐµÐ´Ñ Ð½Ð° ÑÑÑÑÐµÐºÑ Ð¸ пÑиоÑÑанавливаеÑÑÑ. ÐÑли аÑгÑÐ¼ÐµÐ½Ñ `timeout` не Ñавен нÑлÑ, он Ð·Ð°Ð´Ð°ÐµÑ Ð¼Ð°ÐºÑималÑное вÑÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ, в пÑоÑивном ÑлÑÑае ожидание беÑконеÑно. + +[[futex-wake]] +===== FUTEX_WAKE + +ÐÑа опеÑаÑÐ¸Ñ Ð·Ð°Ñ Ð²Ð°ÑÑÐ²Ð°ÐµÑ ÑÑÑÑÐµÐºÑ Ð¿Ð¾ адÑеÑÑ `uaddr` и пÑобÑÐ¶Ð´Ð°ÐµÑ Ð¿ÐµÑвÑе `val` ÑÑÑÑекÑов, ожидаÑÑÐ¸Ñ Ð² оÑеÑеди на ÑÑом ÑÑÑÑекÑе. + +[[futex-fd]] +===== FUTEX_FD + +ÐÑа опеÑаÑÐ¸Ñ ÑвÑзÑÐ²Ð°ÐµÑ ÑайловÑй деÑкÑипÑÐ¾Ñ Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ñм ÑÑÑÑекÑом. + +[[futex-requeue]] +===== FUTEX_REQUEUE + +ÐÑа опеÑаÑÐ¸Ñ Ð±ÐµÑÐµÑ `val` поÑоков, ожидаÑÑÐ¸Ñ Ð½Ð° ÑÑÑÑекÑе по адÑеÑÑ `uaddr`, пÑобÑÐ¶Ð´Ð°ÐµÑ Ð¸Ñ Ð¸ беÑÐµÑ ÑледÑÑÑие `val2` поÑоков, пеÑемеÑÐ°Ñ Ð¸Ñ Ð² оÑеÑÐµÐ´Ñ ÑÑÑÑекÑа по адÑеÑÑ `uaddr2`. + +[[futex-cmp-requeue]] +===== FUTEX_CMP_REQUEUE + +ÐÑа опеÑаÑÐ¸Ñ Ð´ÐµÐ»Ð°ÐµÑ Ñо же Ñамое, ÑÑо и `FUTEX_REQUEUE`, но ÑнаÑала пÑовеÑÑеÑ, ÑÑо `val3` Ñавно `val`. + +[[futex-wake-op]] +===== FUTEX_WAKE_OP + +ÐÑа опеÑаÑÐ¸Ñ Ð²ÑполнÑÐµÑ Ð°ÑомаÑнÑÑ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð½Ð°Ð´ `val3` (коÑоÑÐ°Ñ ÑодеÑÐ¶Ð¸Ñ Ð·Ð°ÐºÐ¾Ð´Ð¸Ñованное дÑÑгое знаÑение) и `uaddr`. ÐаÑем она пÑобÑÐ¶Ð´Ð°ÐµÑ `val` поÑоков на ÑÑÑÑекÑе по адÑеÑÑ `uaddr`, и еÑли аÑомаÑÐ½Ð°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð²ÐµÑнÑла положиÑелÑное ÑиÑло, пÑобÑÐ¶Ð´Ð°ÐµÑ `val2` поÑоков на ÑÑÑÑекÑе по адÑеÑÑ `uaddr2`. + +ÐпеÑаÑии, ÑеализованнÑе в `FUTEX_WAKE_OP`: + +* `FUTEX_OP_SET` +* `FUTEX_OP_ADD` +* `FUTEX_OP_OR` +* `FUTEX_OP_AND` +* `FUTEX_OP_XOR` + +[NOTE] +==== +РпÑоÑоÑипе ÑиÑÑемного вÑзова futex оÑÑÑÑÑÑвÑÐµÑ Ð¿Ð°ÑамеÑÑ `val2`. ÐнаÑение `val2` беÑÑÑÑÑ Ð¸Ð· паÑамеÑÑа `struct timespec *timeout` Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑий `FUTEX_REQUEUE`, `FUTEX_CMP_REQUEUE` и `FUTEX_WAKE_OP`. +==== + +[[futex-emu]] +==== ÐмÑлÑÑÐ¸Ñ ÑÑÑÑекÑов в FreeBSD + +ÐмÑлÑÑÐ¸Ñ futex в FreeBSD взÑÑа из NetBSD и дополниÑелÑно ÑаÑÑиÑена нами. Ðна ÑазмеÑена в ÑÐ°Ð¹Ð»Ð°Ñ `linux_futex.c` и [.filename]#linux_futex.h#. СÑÑÑкÑÑÑа `futex` вÑглÑÐ´Ð¸Ñ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +struct futex { + void *f_uaddr; + int f_refcount; + + LIST_ENTRY(futex) f_list; + + TAILQ_HEAD(lf_waiting_paroc, waiting_proc) f_waiting_proc; +}; +.... + +Ð ÑÑÑÑкÑÑÑа `waiting_proc` вÑглÑÐ´Ð¸Ñ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +struct waiting_proc { + + struct thread *wp_t; + + struct futex *wp_new_futex; + + TAILQ_ENTRY(waiting_proc) wp_list; +}; +.... + +[[futex-get]] +===== futex_get / futex_put + +ФÑÑÑÐµÐºÑ Ð¿Ð¾Ð»ÑÑаеÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÑнкÑии `futex_get`, коÑоÑÐ°Ñ Ð²ÑполнÑÐµÑ Ð¿Ð¾Ð¸Ñк в линейном ÑпиÑке ÑÑÑÑекÑов и возвÑаÑÐ°ÐµÑ Ð½Ð°Ð¹Ð´ÐµÐ½Ð½Ñй или ÑÐ¾Ð·Ð´Ð°ÐµÑ Ð½Ð¾Ð²Ñй. ÐÑи оÑвобождении ÑÑÑÑекÑа поÑле иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²ÑзÑваеÑÑÑ ÑÑнкÑÐ¸Ñ `futex_put`, коÑоÑÐ°Ñ ÑменÑÑÐ°ÐµÑ ÑÑеÑÑик ÑÑÑлок ÑÑÑÑекÑа, и еÑли ÑÑеÑÑик доÑÑÐ¸Ð³Ð°ÐµÑ Ð½ÑлÑ, ÑÑÑÑÐµÐºÑ Ð¾ÑвобождаеÑÑÑ. + +[[futex-sleep]] +===== futex_sleep + +Ðогда ÑÑÑÑÐµÐºÑ ÑÑÐ°Ð²Ð¸Ñ Ð¿Ð¾Ñок в оÑеÑÐµÐ´Ñ Ð½Ð° ожидание, он ÑÐ¾Ð·Ð´Ð°ÐµÑ ÑÑÑÑкÑÑÑÑ `working_proc` и помеÑÐ°ÐµÑ ÑÑÑ ÑÑÑÑкÑÑÑÑ Ð² ÑпиÑок внÑÑÑи ÑÑÑÑкÑÑÑÑ futex, поÑле Ñего пÑоÑÑо вÑполнÑÐµÑ man:tsleep[9] Ð´Ð»Ñ Ð¿ÑиоÑÑановки поÑока. Ðжидание Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ð³ÑаниÑено по вÑемени. ÐоÑле возвÑаÑа из man:tsleep[9] (поÑок бÑл ÑазбÑжен или иÑÑекло вÑÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ) ÑÑÑÑкÑÑÑа `working_proc` ÑдалÑеÑÑÑ Ð¸Ð· ÑпиÑка и ÑниÑÑожаеÑÑÑ. ÐÑе ÑÑо вÑполнÑеÑÑÑ Ð² ÑÑнкÑии `futex_sleep`. ÐÑли Ð¼Ñ Ð±Ñли ÑазбÑÐ¶ÐµÐ½Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ `futex_wake`, Ñ Ð½Ð°Ñ ÑÑÑановлен `wp_new_futex`, поÑÑÐ¾Ð¼Ñ Ð¼Ñ Ð¾Ð¶Ð¸Ð´Ð°ÐµÐ¼ на нем. Таким обÑазом, ÑакÑиÑеÑкое пеÑемеÑение вÑÐ¿Ð¾Ð»Ð½Ñ ÐµÑÑÑ Ð² ÑÑой ÑÑнкÑии. + +[[futex-wake-2]] +===== futex_wake + +ÐÑобÑждение поÑока, ожидаÑÑего на ÑÑÑÑекÑе, вÑполнÑеÑÑÑ Ð² ÑÑнкÑии `futex_wake`. СнаÑала в ÑÑой ÑÑнкÑии Ð¼Ñ Ð¸Ð¼Ð¸ÑиÑÑем ÑÑÑанное поведение Linux(R), где пÑобÑждаÑÑÑÑ N поÑоков Ð´Ð»Ñ Ð²ÑÐµÑ Ð¾Ð¿ÐµÑаÑий, за иÑклÑÑением Ñого, ÑÑо опеÑаÑии REQUEUE вÑполнÑÑÑÑÑ Ð½Ð° N+1 поÑÐ¾ÐºÐ°Ñ . Ðднако обÑÑно ÑÑо не Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°ÑениÑ, Ñак как Ð¼Ñ Ð¿ÑобÑждаем вÑе поÑоки. Ðалее в ÑÑнкÑии в Ñикле Ð¼Ñ Ð¿ÑобÑждаем n поÑоков, поÑле Ñего пÑовеÑÑем, еÑÑÑ Ð»Ð¸ новÑй ÑÑÑÑÐµÐºÑ Ð´Ð»Ñ Ð¿ÐµÑеÑÑановки. ÐÑли еÑÑÑ, Ð¼Ñ Ð¿ÐµÑеÑÑавлÑем до n2 поÑоков на новÑй futex. ÐÑо взаимодейÑÑвÑÐµÑ Ñ `futex_sleep`. + +[[futex-wake-op-2]] +===== futex_wake_op + +ÐпеÑаÑÐ¸Ñ `FUTEX_WAKE_OP` доволÑно Ñложна. СнаÑала Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем два ÑÑÑÑекÑа по адÑеÑам `uaddr` и `uaddr2`, заÑем вÑполнÑем аÑомаÑнÑÑ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ñ Ð¸ÑполÑзованием `val3` и `uaddr2`. ÐоÑле ÑÑого пÑобÑждаÑÑÑÑ `val` ожидаÑÑÐ¸Ñ Ð½Ð° пеÑвом ÑÑÑÑекÑе, и еÑли ÑÑловие аÑомаÑной опеÑаÑии вÑполнÑеÑÑÑ, Ð¼Ñ Ð¿ÑобÑждаем `val2` (Ñ.е. `timeout`) ожидаÑÑÐ¸Ñ Ð½Ð° вÑоÑом ÑÑÑÑекÑе. + +[[futex-atomic-op]] +===== ÐÑомаÑÐ½Ð°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð½Ð° ÑÑÑÑекÑе + +ÐÑомаÑÐ½Ð°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð¿ÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð´Ð²Ð° паÑамеÑÑа `encoded_op` и `uaddr`. ÐакодиÑÐ¾Ð²Ð°Ð½Ð½Ð°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð²ÐºÐ»ÑÑÐ°ÐµÑ ÑÐ°Ð¼Ñ Ð¾Ð¿ÐµÑаÑиÑ, ÑÑавниваемое знаÑение, аÑгÑÐ¼ÐµÐ½Ñ Ð¾Ð¿ÐµÑаÑии и аÑгÑÐ¼ÐµÐ½Ñ ÑÑавнениÑ. ÐÑевдокод опеÑаÑии вÑглÑÐ´Ð¸Ñ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +oldval = *uaddr2 +*uaddr2 = oldval OP oparg +.... + +Ð ÑÑо вÑполнÑеÑÑÑ Ð°ÑомаÑно. СнаÑала пÑоиÑÑ Ð¾Ð´Ð¸Ñ ÐºÐ¾Ð¿Ð¸Ñование ÑиÑла по адÑеÑÑ `uaddr`, а заÑем вÑполнÑеÑÑÑ Ð¾Ð¿ÐµÑаÑиÑ. Ðод обÑабаÑÑÐ²Ð°ÐµÑ Ð¾Ñибки ÑÑÑаниÑ, и еÑли оÑибки не пÑоиÑÑ Ð¾Ð´Ð¸Ñ, `oldval` ÑÑавниваеÑÑÑ Ñ Ð°ÑгÑменÑом `cmparg` Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÐºÐ¾Ð¼Ð¿Ð°ÑаÑоÑа cmp. + +[[futex-locking]] +===== ÐлокиÑовка ÑÑÑÑекÑа + +РеализаÑÐ¸Ñ ÑÑÑÑекÑов иÑполÑзÑÐµÑ Ð´Ð²Ð° ÑпиÑка блокиÑовок Ð´Ð»Ñ Ð·Ð°ÑиÑÑ `sx_lock` и глобалÑнÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовок (либо Giant, либо дÑÑгой `sx_lock`). ÐÐ°Ð¶Ð´Ð°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð²ÑполнÑеÑÑÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñованной Ð¾Ñ Ð½Ð°Ñала до Ñамого конÑа. + +[[syscall-impl]] +=== РеализаÑÐ¸Ñ ÑазлиÑнÑÑ ÑиÑÑемнÑÑ Ð²Ñзовов + +Ð ÑÑом Ñазделе Ñ Ð¾Ð¿Ð¸ÑÑ Ð½ÐµÑколÑко менее знаÑимÑÑ ÑиÑÑемнÑÑ Ð²Ñзовов, коÑоÑÑе ÑÑÐ¾Ð¸Ñ ÑпомÑнÑÑÑ, поÑÐ¾Ð¼Ñ ÑÑо Ð¸Ñ ÑеализаÑÐ¸Ñ Ð½ÐµÐ¾Ñевидна или ÑÑи вÑÐ·Ð¾Ð²Ñ Ð¿ÑедÑÑавлÑÑÑ Ð¸Ð½ÑеÑÐµÑ Ñ Ð´ÑÑгой ÑоÑки зÑениÑ. + +[[syscall-at]] +==== *ÑемейÑÑво ÑиÑÑемнÑÑ Ð²Ñзовов at + +Ðо вÑÐµÐ¼Ñ ÑазÑабоÑки ÑдÑа Linux(R) 2.6.16 бÑли Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ñ *at-ÑиÑÑемнÑе вÑзовÑ. ÐÑи ÑиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ (напÑимеÑ, `openat`) ÑабоÑаÑÑ ÑоÑно Ñак же, как Ð¸Ñ Ð°Ð½Ð°Ð»Ð¾Ð³Ð¸ без at, за иÑклÑÑением паÑамеÑÑа `dirfd`. ÐÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð¾Ð¿ÑеделÑÐµÑ Ð¼ÐµÑÑоположение Ñайла, над коÑоÑÑм вÑполнÑеÑÑÑ ÑиÑÑемнÑй вÑзов. ÐÑли паÑамеÑÑ `filename` ÑвлÑеÑÑÑ Ð°Ð±ÑолÑÑнÑм, `dirfd` игноÑиÑÑеÑÑÑ, но еÑли пÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ Ð¾ÑноÑиÑелÑнÑй, `dirfd` вÑÑÑÐ¿Ð°ÐµÑ Ð² игÑÑ. ÐаÑамеÑÑ `dirfd` пÑедÑÑавлÑÐµÑ Ñобой каÑалог, оÑноÑиÑÐ µÐ»Ñно коÑоÑого пÑовеÑÑеÑÑÑ Ð¾ÑноÑиÑелÑнÑй пÑÑÑ. ÐаÑамеÑÑ `dirfd` ÑвлÑеÑÑÑ ÑайловÑм деÑкÑипÑоÑом некоÑоÑого ÐºÐ°Ñ Ð°Ð»Ð¾Ð³Ð° или `AT_FDCWD`. ÐапÑимеÑ, ÑиÑÑемнÑй вÑзов `openat` Ð¼Ð¾Ð¶ÐµÑ Ð²ÑглÑдеÑÑ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +file descriptor 123 = /tmp/foo/, current working directory = /tmp/ + +openat(123, /tmp/bah\, flags, mode) /* opens /tmp/bah */ +openat(123, bah\, flags, mode) /* opens /tmp/foo/bah */ +openat(AT_FDWCWD, bah\, flags, mode) /* opens /tmp/bah */ +openat(stdio, bah\, flags, mode) /* returns error because stdio is not a directory */ +.... + +ÐÑа инÑÑаÑÑÑÑкÑÑÑа Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð° Ð´Ð»Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°Ð½Ð¸Ñ ÑоÑÑоÑний гонки пÑи оÑкÑÑÑии Ñайлов вне ÑабоÑего каÑалога. ÐÑедÑÑавÑÑе, ÑÑо пÑоÑеÑÑ ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· двÑÑ Ð¿Ð¾Ñоков, поÑока A и поÑока B. ÐоÑок A вÑполнÑÐµÑ `open(./tmp/foo/bah., flags, mode)`, и пеÑед возвÑаÑом ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð½ вÑÑеÑнÑеÑÑÑ, и наÑÐ¸Ð½Ð°ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð¿Ð¾Ñок B. ÐоÑок B не ÑÑиÑÑÐ²Ð°ÐµÑ Ð¿Ð¾ÑÑебноÑÑи поÑока A и пеÑеименовÑÐ²Ð°ÐµÑ Ð¸Ð»Ð¸ ÑдалÑÐµÑ [.filename]#/tmp/foo/#. ÐÐ¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ ÑоÑÑоÑние гонки. ЧÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ ÑÑого, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ оÑкÑÑÑ Ñ [.filename]#/tmp/foo# и иÑполÑзоваÑÑ ÐµÐ³Ð¾ как `dirfd` Ð´Ð»Ñ ÑиÑÑемного вÑзова `openat`. ÐÑо Ñакже позволÑÐµÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ñеали зоваÑÑ ÑабоÑие каÑалоги Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ поÑока. + +СемейÑÑво *at ÑиÑÑемнÑÑ Ð²Ñзовов Linux(R) вклÑÑаеÑ: `linux_openat`, `linux_mkdirat`, `linux_mknodat`, `linux_fchownat`, `linux_futimesat`, `linux_fstatat64`, `linux_unlinkat`, `linux_renameat`, `linux_linkat`, `linux_symlinkat`, `linux_readlinkat`, `linux_fchmodat` и `linux_faccessat`. ÐÑе они ÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ Ñ Ð¸ÑполÑзованием модиÑиÑиÑованной ÑÑнкÑии man:namei[9] и пÑоÑÑого ÑÐ»Ð¾Ñ Ð¾Ð±ÑÑÑки. + +[[implementation]] +===== РеализаÑÐ¸Ñ + +РеализаÑÐ¸Ñ Ð²Ñполнена пÑÑем Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑÑнкÑии man:namei[9] (опиÑанной вÑÑе) Ð´Ð»Ñ Ð¿Ñиема дополниÑелÑного паÑамеÑÑа `dirfd` в ÑÑÑÑкÑÑÑе `nameidata`, коÑоÑÑй ÑказÑÐ²Ð°ÐµÑ Ð½Ð°ÑалÑнÑÑ ÑоÑÐºÑ Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пÑÑи вмеÑÑо иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑекÑÑей ÑабоÑей диÑекÑоÑии каждÑй Ñаз. ÐÑеобÑазование `dirfd` из номеÑа Ñайлового деÑкÑипÑоÑа в vnode вÑполнÑеÑÑÑ Ð² наÑивнÑÑ *at-ÑиÑÑемнÑÑ Ð²ÑÐ·Ð¾Ð²Ð°Ñ . Ðогда `dirfd` Ñавен `AT_FDCWD`, запиÑÑ `dvp` в ÑÑÑÑкÑÑÑе `nameidata` Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°Ñение `NULL`, но еÑли `dirfd` пÑедÑÑ Ð°Ð²Ð»ÑÐµÑ Ð´ÑÑгой номеÑ, Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем Ñайл по ÑÑÐ¾Ð¼Ñ Ð´ÐµÑкÑипÑоÑÑ, пÑовеÑÑем его валидноÑÑÑ Ð¸, еÑли к Ð½ÐµÐ¼Ñ Ð¿ÑикÑеплРµÐ½ vnode, полÑÑаем ÑÑÐ¾Ñ vnode. ÐаÑем пÑовеÑÑем, ÑвлÑеÑÑÑ Ð»Ð¸ ÑÑÐ¾Ñ vnode диÑекÑоÑией. Ð Ñамой ÑÑнкÑии man:namei[9] Ð¼Ñ Ð¿ÑоÑÑо заменÑем vnode `dvp` на пеÑеменнÑÑ `dp` в ÑÑнкÑии man:namei[9], коÑоÑÐ°Ñ Ð¾Ð¿ÑеделÑÐµÑ Ð½Ð°ÑалÑнÑÑ ÑоÑкÑ. ФÑнкÑÐ¸Ñ man:namei[9] иÑполÑзÑеÑÑÑ Ð½Ðµ напÑÑмÑÑ, а ÑеÑез ÑепоÑÐºÑ ÑазлиÑнÑÑ ÑÑнкÑий на ÑазнÑÑ ÑÑовнÑÑ . ÐапÑимеÑ, `openat` ÑабоÑÐ°ÐµÑ ÑледÑÑÑим обÑазом: + +[.programlisting] +.... +openat() --> kern_openat() --> vn_open() -> namei() +.... + +Ðо ÑÑой пÑиÑине `kern_open` и `vn_open` Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ñ Ð´Ð»Ñ Ð²ÐºÐ»ÑÑÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑного паÑамеÑÑа `dirfd`. Слой ÑовмеÑÑимоÑÑи Ð´Ð»Ñ Ð½Ð¸Ñ Ð½Ðµ ÑоздаÑÑÑÑ, Ñак как полÑзоваÑелей ÑÑÐ¸Ñ ÑÑнкÑий немного и Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ легко адапÑиÑоваÑÑ. ÐÐ°Ð½Ð½Ð°Ñ Ð¾Ð±ÑÐ°Ñ ÑеализаÑÐ¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÐµÑ FreeBSD ÑеализоваÑÑ Ñвои ÑобÑÑвеннÑе *at-ÑиÑÑемнÑе вÑзовÑ. ÐÑо обÑÑждаеÑÑÑ Ð² наÑÑоÑÑее вÑемÑ. + +[[ioctl]] +==== Ioctl + +ÐнÑеÑÑÐµÐ¹Ñ ioctl доволÑно Ñ ÑÑпок из-за Ñвоей обобÑÑнноÑÑи. ÐÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ ÑÑиÑÑваÑÑ, ÑÑо ÑÑÑÑойÑÑва в Linux(R) и FreeBSD ÑазлиÑаÑÑÑÑ, поÑÑÐ¾Ð¼Ñ ÑÑебÑеÑÑÑ Ð¾ÑÐ¾Ð±Ð°Ñ Ð¾ÑÑоÑожноÑÑÑ Ð´Ð»Ñ ÐºÐ¾ÑÑекÑной ÑабоÑÑ ÑмÑлÑÑии ioctl. ÐбÑабоÑка ioctl Ñеализована в Ñайле [.filename]#linux_ioctl.c#, где опÑеделена ÑÑнкÑÐ¸Ñ `linux_ioctl`. ÐÑа ÑÑнкÑÐ¸Ñ Ð¿ÑоÑÑо пеÑебиÑÐ°ÐµÑ Ð½Ð°Ð±Ð¾ÑÑ Ð¾Ð±ÑабоÑÑиков ioctl, ÑÑÐ¾Ð±Ñ Ð½Ð°Ð¹Ñи обÑабоÑÑик, ÑеализÑÑÑий даннÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ. СиÑÑемнÑй вÑзов ioctl Ð¸Ð¼ÐµÐµÑ ÑÑи паÑамеÑÑа: ÑайловÑй деÑк ÑипÑоÑ, ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¸ аÑгÑменÑ. Ðоманда пÑедÑÑавлÑÐµÑ Ñобой 16-биÑное ÑиÑло, коÑоÑое ÑеоÑеÑиÑеÑки делиÑÑÑ Ð½Ð° ÑÑаÑÑ Ð¸Ðµ 8 биÑ, опÑеделÑÑÑие клаÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ ioctl, и младÑие 8 биÑ, коÑоÑÑе ÑвлÑÑÑÑÑ ÐºÐ¾Ð½ÐºÑеÑной командой в данном набоÑе. ÐмÑлÑÑÐ¸Ñ Ð¸ÑполÑзÑÐµÑ ÑÑо Ñазделение. Ð ÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ Ð¾Ð±ÑабоÑÑики Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ набоÑа, Ñакие как `sound_handler` или `disk_handler`. ÐаждÑй обÑабоÑÑик Ð¸Ð¼ÐµÐµÑ Ð¾Ð¿ÑеделÑннÑе макÑималÑнÑÑ Ð¸ минималÑнÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ, коÑоÑÑе иÑполÑзÑÑÑÑÑ Ð´Ð»Ñ Ð²ÑбоÑа нÑжного обÑабоÑÑика. СÑÑеÑÑвÑÑÑ Ð½ÐµÐ±Ð¾Ð»ÑÑие пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñ ÑÑим Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð¾Ð¼, поÑколÑÐºÑ Linux(R) не вÑегда поÑледоваÑе лÑно иÑполÑзÑÐµÑ Ñазделение на набоÑÑ, поÑÑÐ¾Ð¼Ñ Ð¸Ð½Ð¾Ð³Ð´Ð° ioctls Ð´Ð»Ñ Ð´ÑÑгого набоÑа оказÑваÑÑÑÑ Ð²Ð½ÑÑÑи набоÑа, к ÐºÐ¾Ñ Ð¾ÑÐ¾Ð¼Ñ Ð¾Ð½Ð¸ не Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿ÑиÐ! ½Ð°Ð´Ð»ÐµÐ¶Ð°ÑÑ (напÑимеÑ, SCSI generic ioctls внÑÑÑи набоÑа cdrom и Ñ.д.). РнаÑÑоÑÑее вÑÐµÐ¼Ñ FreeBSD ÑеализÑÐµÑ Ð½Ðµ Ñак много ioctls Linux(R) (по ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ñ NetBSD, напÑимеÑ), но планиÑÑеÑÑÑ Ð¿ÐµÑенеÑÑи Ð¸Ñ Ð¸Ð· NetBSD. ТенденÑÐ¸Ñ Ñакова, ÑÑо ioctls Linux(R) иÑполÑзÑÑÑÑÑ Ð´Ð°Ð¶Ðµ в ÑоднÑÑ Ð´ÑайвеÑÐ°Ñ FreeBSD Ð´Ð»Ñ ÑпÑоÑÐµÐ½Ð¸Ñ Ð¿Ð¾ÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ñиложений. + +[[debugging]] +==== ÐÑладка + +ÐаждÑй ÑиÑÑемнÑй вÑзов должен поддеÑживаÑÑ Ð¾ÑладкÑ. ÐÐ»Ñ ÑÑой Ñели Ð¼Ñ Ð²Ð²Ð¾Ð´Ð¸Ð¼ неболÑÑÑÑ Ð¸Ð½ÑÑаÑÑÑÑкÑÑÑÑ. У Ð½Ð°Ñ ÐµÑÑÑ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼ `ldebug`, коÑоÑÑй опÑеделÑеÑ, нÑжно ли оÑлаживаÑÑ Ð´Ð°Ð½Ð½Ñй ÑиÑÑемнÑй вÑзов (наÑÑÑаиваеÑÑÑ ÑеÑез `sysctl`). ÐÐ»Ñ Ð²Ñвода ÑообÑений иÑполÑзÑÑÑÑÑ Ð¼Ð°ÐºÑоÑÑ `LMSG` и `ARGS`. Ðни пÑименÑÑÑÑÑ Ð´Ð»Ñ ÑоÑмаÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑÑок вÑвода Ñ ÑелÑÑ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐµÐ´Ð¸Ð½Ð¾Ð¾Ð±ÑазнÑÑ Ð¾ÑладоÑнÑÑ ÑообÑений. + +[[conclusion]] +== ÐаклÑÑение + +[[results]] +=== РезÑлÑÑаÑÑ + +Ðо ÑоÑÑоÑÐ½Ð¸Ñ Ð½Ð° апÑÐµÐ»Ñ 2007 года ÑÑÐ¾Ð²ÐµÐ½Ñ ÑмÑлÑÑии Linux(R) ÑпоÑобен доÑÑаÑоÑно Ñ Ð¾ÑоÑо ÑмÑлиÑоваÑÑ ÑдÑо Linux(R) 2.6.16. ÐÑÑавÑиеÑÑ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ ÐºÐ°ÑаÑÑÑÑ ÑÑÑÑекÑов, незавеÑÑÑнного ÑемейÑÑва ÑиÑÑемнÑÑ Ð²Ñзовов *at, пÑоблемаÑиÑной доÑÑавки Ñигналов, оÑÑÑÑÑÑÐ²Ð¸Ñ `epoll` и `inotify`, а Ñакже, веÑоÑÑно, некоÑоÑÑÑ Ð¾Ñибок, коÑоÑÑе Ð¼Ñ ÐµÑÑ Ð½Ðµ обнаÑÑжили. ÐеÑмоÑÑÑ Ð½Ð° ÑÑо, Ð¼Ñ ÑпоÑÐ¾Ð±Ð½Ñ Ð·Ð°Ð¿ÑÑкаÑÑ Ð¿ÑакÑиÑеÑки вÑе пÑогÑÐ°Ð¼Ð¼Ñ Linux(R), вклÑÑÑннÑе в ÐоллекÑÐ¸Ñ Ð¿Ð¾ÑÑов FreeBSD, Ñ Fedora Core 4 Ð ½Ð° ÑдÑе 2.6.16, а Ñакже еÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе пÑедваÑиÑелÑнÑе ÑообÑÐµÐ½Ð¸Ñ Ð¾Ð± ÑÑпеÑной ÑабоÑе Ñ Fedora Core 6 на ÑдÑе 2.6.16. ÐедавР½Ð¾ бÑл добавлен linux_base Fedora Core 6, ÑÑо позволило пÑовеÑÑи дополниÑелÑнÑе ÑеÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑÐ¾Ð²Ð½Ñ ÑмÑлÑÑии и дало нам болÑÑе подÑказок, кÑда ÑледÑÐµÑ Ð½Ð°Ð¿ÑавиÑÑ ÑÑÐ¸Ð»Ð¸Ñ Ð´Ð»Ñ ÑеализаÑии недоÑÑаÑÑÐ¸Ñ ÑÑнкÑий. + +ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ запÑÑкаÑÑ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ попÑлÑÑнÑе пÑиложениÑ, Ñакие как package:www/linux-firefox[], package:net-im/skype[], и некоÑоÑÑе игÑÑ Ð¸Ð· ÐоллекÑии поÑÑов. ÐекоÑоÑÑе пÑогÑÐ°Ð¼Ð¼Ñ Ð´ÐµÐ¼Ð¾Ð½ÑÑÑиÑÑÑÑ Ð½ÐµÐºÐ¾ÑÑекÑное поведение пÑи ÑмÑлÑÑии 2.6, но ÑÑо в наÑÑоÑÑее вÑÐµÐ¼Ñ Ð¸ÑÑледÑеÑÑÑ, и, надеемÑÑ, ÑкоÑо бÑÐ´ÐµÑ Ð¸ÑпÑавлено. ÐдинÑÑвенное кÑÑпное пÑиложение, коÑоÑое, как извеÑÑно, не ÑабоÑаеÑ, â ÑÑо Linux(R) Java(TM) Development Kit, и ÑÑо ÑвÑзано Ñ ÑÑебованием ÑÑнкÑии `epoll`, коÑоÑÐ°Ñ Ð½Ðµ Ð¸Ð¼ÐµÐµÑ Ð¿ÑÑмогР¾ оÑноÑÐµÐ½Ð¸Ñ Ðº ÑдÑÑ Linux(R) 2.6. + +ÐÑ Ð½Ð°Ð´ÐµÐµÐ¼ÑÑ Ð²ÐºÐ»ÑÑиÑÑ ÑмÑлÑÑÐ¸Ñ 2.6.16 по ÑмолÑÐ°Ð½Ð¸Ñ ÑеÑез некоÑоÑое вÑÐµÐ¼Ñ Ð¿Ð¾Ñле вÑÑ Ð¾Ð´Ð° FreeBSD 7.0, по кÑайней меÑе, ÑÑÐ¾Ð±Ñ Ð¾ÑкÑÑÑÑ ÑаÑÑи ÑмÑлÑÑии 2.6 Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ ÑиÑокого ÑеÑÑиÑованиÑ. Ðак ÑолÑко ÑÑо бÑÐ´ÐµÑ Ñделано, Ð¼Ñ Ñможем пеÑейÑи на Fedora Core 6 linux_base, ÑÑо ÑвлÑеÑÑÑ ÐºÐ¾Ð½ÐµÑной ÑелÑÑ. + +[[future-work]] +=== ÐÑдÑÑие ÑабоÑÑ + +ÐÑдÑÑÐ°Ñ ÑабоÑа должна бÑÑÑ ÑоÑÑедоÑоÑена на иÑпÑавлении оÑÑавÑÐ¸Ñ ÑÑ Ð¿Ñоблем Ñ ÑÑÑÑекÑами, ÑеализаÑии оÑÑавÑÐ¸Ñ ÑÑ ÑиÑÑемнÑÑ Ð²Ñзовов ÑемейÑÑва *at, иÑпÑавлении доÑÑавки Ñигналов и, возможно, ÑеализаÑии Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼Ð¾Ð² `epoll` и `inotify`. + +ÐÑ Ð½Ð°Ð´ÐµÐµÐ¼ÑÑ Ð²ÑкоÑе добиÑÑÑÑ Ð±ÐµÐ·ÑпÑеÑной ÑабоÑÑ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ важнÑÑ Ð¿ÑогÑамм, ÑÑÐ¾Ð±Ñ Ð¼Ð¾Ð¶Ð½Ð¾ бÑло по ÑмолÑÐ°Ð½Ð¸Ñ Ð¿ÐµÑеклÑÑиÑÑÑÑ Ð½Ð° ÑмÑлÑÑÐ¸Ñ 2.6 и ÑделаÑÑ Fedora Core 6 базовой веÑÑией linux_base, поÑколÑÐºÑ Ð¸ÑполÑзÑÐµÐ¼Ð°Ñ Ð² наÑÑоÑÑее вÑÐµÐ¼Ñ Fedora Core 4 болÑÑе не поддеÑживаеÑÑÑ. + +ÐÑÑÐ³Ð°Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð°Ñ ÑÐµÐ»Ñ â поделиÑÑÑÑ Ð½Ð°Ñим кодом Ñ NetBSD и DragonflyBSD. NetBSD Ð¸Ð¼ÐµÐµÑ Ð½ÐµÐºÐ¾ÑоÑÑÑ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶ÐºÑ ÑмÑлÑÑии 2.6, но она далека Ð¾Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð¸ не бÑла должнÑм обÑазом пÑоÑеÑÑиÑована. DragonflyBSD вÑÑазила некоÑоÑÑÑ Ð·Ð°Ð¸Ð½ÑеÑеÑованноÑÑÑ Ð² пеÑеноÑе ÑлÑÑÑений веÑÑии 2.6. + +Ð Ñелом, по меÑе ÑазвиÑÐ¸Ñ Linux(R) Ð¼Ñ Ñ Ð¾Ñели Ð±Ñ Ð¸Ð´Ñи в Ð½Ð¾Ð³Ñ Ñ Ð¸Ñ ÑазÑабоÑкой, ÑеализÑÑ Ð½Ð¾Ð²Ñе ÑиÑÑемнÑе вÑзовÑ. РпеÑвÑÑ Ð¾ÑеÑÐµÐ´Ñ Ð½Ð° Ñм пÑÐ¸Ñ Ð¾Ð´Ð¸Ñ `splice`. ÐекоÑоÑÑе Ñже ÑеализованнÑе ÑиÑÑемнÑе вÑÐ·Ð¾Ð²Ñ Ñакже неопÑималÑнÑ, напÑÐ¸Ð¼ÐµÑ `mremap` и дÑÑгие. Также можно внеÑÑи некоÑоÑÑе ÑлÑÑÑÐµÐ½Ð¸Ñ Ð¿ÑоизводиÑелÑноÑÑи, Ñакие как более деÑалÑÐ½Ð°Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовка и дÑÑгие. + +[[team]] +=== Ðоманда + +Я ÑоÑÑÑдниÑал в ÑÑом пÑоекÑе Ñ (в алÑавиÑном поÑÑдке): + +* `{jhb}` +* `{kib}` +* Emmanuel Dreyfus +* Scot Hetzel +* `{jkim}` +* `{netchild}` *** 4433 LINES SKIPPED ***