€•<Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒEnglish”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ/process/4.Coding”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Simplified)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/zh_CN/process/4.Coding”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/zh_TW/process/4.Coding”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/it_IT/process/4.Coding”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/ja_JP/process/4.Coding”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/ko_KR/process/4.Coding”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒSpanish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒwarning”“”)”}”(hX?Si tiene alguna duda sobre la exactitud del contenido de esta traducción, la única referencia válida es la documentación oficial en inglés. Además, por defecto, los enlaces a documentos redirigen a la documentación en inglés, incluso si existe una versión traducida. Consulte el índice para más información.”h]”hŒ paragraph”“”)”}”(hX?Si tiene alguna duda sobre la exactitud del contenido de esta traducción, la única referencia válida es la documentación oficial en inglés. Además, por defecto, los enlaces a documentos redirigen a la documentación en inglés, incluso si existe una versión traducida. Consulte el índice para más información.”h]”hX?Si tiene alguna duda sobre la exactitud del contenido de esta traducción, la única referencia válida es la documentación oficial en inglés. Además, por defecto, los enlaces a documentos redirigen a la documentación en inglés, incluso si existe una versión traducida. Consulte el índice para más información.”…””}”(hh©hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸŒ2Documentation/translations/sp_SP/disclaimer-sp.rst”h Khh£ubah}”(h]”h ]”h"]”h$]”h&]”uh1h¡hhhžhhŸh·h NubhŒ field_list”“”)”}”(hhh]”(hŒfield”“”)”}”(hhh]”(hŒ field_name”“”)”}”(hŒOriginal”h]”hŒOriginal”…””}”(hhÊhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÈhhÅhŸŒQ/var/lib/git/docbuild/linux/Documentation/translations/sp_SP/process/4.Coding.rst”h KubhŒ field_body”“”)”}”(hŒ"Documentation/process/4.Coding.rst”h]”h¨)”}”(hhÝh]”hŒ"Documentation/process/4.Coding.rst”…””}”(hhßhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh KhhÛubah}”(h]”h ]”h"]”h$]”h&]”uh1hÙhhÅubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÃhŸhØh KhhÀhžhubhÄ)”}”(hhh]”(hÉ)”}”(hŒ Translator”h]”hŒ Translator”…””}”(hhûhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÈhhøhŸhØh KubhÚ)”}”(hŒVCarlos Bilbao and Avadhut Naik ”h]”h¨)”}”(hŒUCarlos Bilbao and Avadhut Naik ”h]”(hŒCarlos Bilbao <”…””}”(hj hžhhŸNh NubhŒ reference”“”)”}”(hŒcarlos.bilbao.osdev@gmail.com”h]”hŒcarlos.bilbao.osdev@gmail.com”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œ$mailto:carlos.bilbao.osdev@gmail.com”uh1jhj ubhŒ> and Avadhut Naik <”…””}”(hj hžhhŸNh Nubj)”}”(hŒavadhut.naik@amd.com”h]”hŒavadhut.naik@amd.com”…””}”(hj+hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:avadhut.naik@amd.com”uh1jhj ubhŒ>”…””}”(hj hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Khj ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÙhhøubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÃhŸhØh KhhÀhžhubeh}”(h]”h ]”h"]”h$]”h&]”uh1h¾hhhžhhŸhØh KubhŒtarget”“”)”}”(hŒ.. _sp_development_coding:”h]”h}”(h]”h ]”h"]”h$]”h&]”Œrefid”Œsp-development-coding”uh1jWh KhhhžhhŸhØubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒConseguir el código correcto”h]”hŒConseguir el código correcto”…””}”(hjlhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhjghžhhŸhØh K ubh¨)”}”(hXSi bien hay mucho que decir a favor de un proceso de diseño sólido y orientado a la comunidad, la prueba de cualquier proyecto de desarrollo del kernel está en el código resultante. Es el código lo que será examinado por otros desarrolladores y lo que será incluido (o no) en el árbol principal. Por lo tanto, es la calidad de este código lo que determinará el éxito final del proyecto.”h]”hXSi bien hay mucho que decir a favor de un proceso de diseño sólido y orientado a la comunidad, la prueba de cualquier proyecto de desarrollo del kernel está en el código resultante. Es el código lo que será examinado por otros desarrolladores y lo que será incluido (o no) en el árbol principal. Por lo tanto, es la calidad de este código lo que determinará el éxito final del proyecto.”…””}”(hjzhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K hjghžhubh¨)”}”(hXEsta sección examinará el proceso de programación. Comenzaremos observando algunas de las maneras en que los desarrolladores del kernel pueden cometer errores. Luego, el enfoque se dirigirá hacia hacer las cosas bien y las herramientas que pueden ayudar en dicha búsqueda.”h]”hXEsta sección examinará el proceso de programación. Comenzaremos observando algunas de las maneras en que los desarrolladores del kernel pueden cometer errores. Luego, el enfoque se dirigirá hacia hacer las cosas bien y las herramientas que pueden ayudar en dicha búsqueda.”…””}”(hjˆhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Khjghžhubjf)”}”(hhh]”(jk)”}”(hŒ Problemas”h]”hŒ Problemas”…””}”(hj™hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhj–hžhhŸhØh Kubjf)”}”(hhh]”(jk)”}”(hŒEstilo de programación”h]”hŒEstilo de programación”…””}”(hjªhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhj§hžhhŸhØh Kubh¨)”}”(hX El kernel ha tenido durante mucho tiempo un estilo de programación estándar, descrito en la documentación del kernel en `Documentation/process/coding-style.rst`. Durante gran parte de ese tiempo, las políticas descritas en ese archivo se tomaban como, en el mejor de los casos, orientativas. Como resultado, hay una cantidad considerable de código en el kernel que no cumple con las pautas de estilo de programación. La presencia de ese código lleva a dos peligros independientes para los desarrolladores del kernel.”h]”(hŒ{El kernel ha tenido durante mucho tiempo un estilo de programación estándar, descrito en la documentación del kernel en ”…””}”(hj¸hžhhŸNh NubhŒtitle_reference”“”)”}”(hŒ(`Documentation/process/coding-style.rst`”h]”hŒ&Documentation/process/coding-style.rst”…””}”(hjÂhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÀhj¸ubhXh. Durante gran parte de ese tiempo, las políticas descritas en ese archivo se tomaban como, en el mejor de los casos, orientativas. Como resultado, hay una cantidad considerable de código en el kernel que no cumple con las pautas de estilo de programación. La presencia de ese código lleva a dos peligros independientes para los desarrolladores del kernel.”…””}”(hj¸hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Khj§hžhubh¨)”}”(hXEl primero de estos es creer que los estándares de programación del kernel no importan y no se aplican. La realidad es que agregar nuevo código al kernel es muy difícil si ese código no está escrito de acuerdo con el estándar; muchos desarrolladores solicitarán que el código sea reformateado antes de revisarlo. Una base de código tan grande como el kernel requiere cierta uniformidad para que los desarrolladores puedan comprender rápidamente cualquier parte de él. Así que ya no hay lugar para el código con formato extraño.”h]”hXEl primero de estos es creer que los estándares de programación del kernel no importan y no se aplican. La realidad es que agregar nuevo código al kernel es muy difícil si ese código no está escrito de acuerdo con el estándar; muchos desarrolladores solicitarán que el código sea reformateado antes de revisarlo. Una base de código tan grande como el kernel requiere cierta uniformidad para que los desarrolladores puedan comprender rápidamente cualquier parte de él. Así que ya no hay lugar para el código con formato extraño.”…””}”(hjÚhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K&hj§hžhubh¨)”}”(hXnOcasionalmente, el estilo de programación del kernel entrará en conflicto con el estilo obligatorio de un empleador. En tales casos, el estilo del kernel tendrá que prevalecer antes de que el código pueda ser fusionado. Incluir código en el kernel significa renunciar a cierto grado de control de varias maneras, incluida la forma en que se formatea el código.”h]”hXnOcasionalmente, el estilo de programación del kernel entrará en conflicto con el estilo obligatorio de un empleador. En tales casos, el estilo del kernel tendrá que prevalecer antes de que el código pueda ser fusionado. Incluir código en el kernel significa renunciar a cierto grado de control de varias maneras, incluida la forma en que se formatea el código.”…””}”(hjèhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K/hj§hžhubh¨)”}”(hXÍLa otra trampa es asumir que el código que ya está en el kernel necesita urgentemente correcciones de estilo de programación. Los desarrolladores pueden comenzar a generar parches de reformateo como una forma de familiarizarse con el proceso o como una forma de incluir su nombre en los registros de cambios del kernel, o ambos. Pero las correcciones puramente de estilo de programación son vistas como ruido por la comunidad de desarrollo; tienden a recibir una recepción adversa. Por lo tanto, este tipo de parche es mejor evitarlo. Es natural corregir el estilo de una parte del código mientras se trabaja en él por otras razones, pero los cambios de estilo de programación no deben hacerse por sí mismos.”h]”hXÍLa otra trampa es asumir que el código que ya está en el kernel necesita urgentemente correcciones de estilo de programación. Los desarrolladores pueden comenzar a generar parches de reformateo como una forma de familiarizarse con el proceso o como una forma de incluir su nombre en los registros de cambios del kernel, o ambos. Pero las correcciones puramente de estilo de programación son vistas como ruido por la comunidad de desarrollo; tienden a recibir una recepción adversa. Por lo tanto, este tipo de parche es mejor evitarlo. Es natural corregir el estilo de una parte del código mientras se trabaja en él por otras razones, pero los cambios de estilo de programación no deben hacerse por sí mismos.”…””}”(hjöhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K5hj§hžhubh¨)”}”(hX"El documento de estilo de programación tampoco debe leerse como una ley absoluta que nunca puede transgredirse. Si hay una buena razón para ir en contra del estilo (una línea que se vuelve mucho menos legible si se divide para ajustarse al límite de 80 columnas, por ejemplo), perfecto.”h]”hX"El documento de estilo de programación tampoco debe leerse como una ley absoluta que nunca puede transgredirse. Si hay una buena razón para ir en contra del estilo (una línea que se vuelve mucho menos legible si se divide para ajustarse al límite de 80 columnas, por ejemplo), perfecto.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K@hj§hžhubh¨)”}”(hXñTenga en cuenta que también puedes usar la herramienta `clang-format` para ayudarle con estas reglas, para reformatear rápidamente partes de su código automáticamente y para revisar archivos completos a fin de detectar errores de estilo de programación, errores tipográficos y posibles mejoras. También es útil para ordenar `#includes`, alinear variables/macros, reformatear texto y otras tareas similares. Consulte el archivo `Documentation/dev-tools/clang-format.rst` para más detalles.”h]”(hŒ8Tenga en cuenta que también puedes usar la herramienta ”…””}”(hjhžhhŸNh NubjÁ)”}”(hŒ`clang-format`”h]”hŒ clang-format”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÀhjubhX para ayudarle con estas reglas, para reformatear rápidamente partes de su código automáticamente y para revisar archivos completos a fin de detectar errores de estilo de programación, errores tipográficos y posibles mejoras. También es útil para ordenar ”…””}”(hjhžhhŸNh NubjÁ)”}”(hŒ `#includes`”h]”hŒ #includes”…””}”(hj,hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÀhjubhŒ\, alinear variables/macros, reformatear texto y otras tareas similares. Consulte el archivo ”…””}”(hjhžhhŸNh NubjÁ)”}”(hŒ*`Documentation/dev-tools/clang-format.rst`”h]”hŒ(Documentation/dev-tools/clang-format.rst”…””}”(hj>hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÀhjubhŒ para más detalles.”…””}”(hjhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh KEhj§hžhubh¨)”}”(hXAlgunas configuraciones básicas del editor, como la indentación y los finales de línea, se configurarán automáticamente si utilizas un editor compatible con EditorConfig. Consulte el sitio web oficial de EditorConfig para obtener más información: https://editorconfig.org/”h]”(hŒþAlgunas configuraciones básicas del editor, como la indentación y los finales de línea, se configurarán automáticamente si utilizas un editor compatible con EditorConfig. Consulte el sitio web oficial de EditorConfig para obtener más información: ”…””}”(hjVhžhhŸNh Nubj)”}”(hŒhttps://editorconfig.org/”h]”hŒhttps://editorconfig.org/”…””}”(hj^hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”j`uh1jhjVubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh KMhj§hžhubeh}”(h]”Œestilo-de-programacion”ah ]”h"]”Œestilo de programación”ah$]”h&]”uh1jehj–hžhhŸhØh Kubjf)”}”(hhh]”(jk)”}”(hŒCapas de abstracción”h]”hŒCapas de abstracción”…””}”(hj~hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhj{hžhhŸhØh KSubh¨)”}”(hX#Los profesores de ciencias de la computación enseñan a los estudiantes a hacer un uso extensivo de capas de abstracción en nombre de la flexibilidad y el ocultamiento de la información. Sin duda, el kernel hace un uso extensivo de la abstracción; ningún proyecto que involucre varios millones de líneas de código podría sobrevivir de otra manera. Pero la experiencia ha demostrado que una abstracción excesiva o prematura puede ser tan perjudicial como la optimización prematura. La abstracción debe usarse en la medida necesaria y ya.”h]”hX#Los profesores de ciencias de la computación enseñan a los estudiantes a hacer un uso extensivo de capas de abstracción en nombre de la flexibilidad y el ocultamiento de la información. Sin duda, el kernel hace un uso extensivo de la abstracción; ningún proyecto que involucre varios millones de líneas de código podría sobrevivir de otra manera. Pero la experiencia ha demostrado que una abstracción excesiva o prematura puede ser tan perjudicial como la optimización prematura. La abstracción debe usarse en la medida necesaria y ya.”…””}”(hjŒhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh KUhj{hžhubh¨)”}”(hXÑA un nivel simple, considere una función que tiene un argumento que siempre se pasa como cero por todos los que la invocan. Uno podría mantener ese argumento por si alguien eventualmente necesita usar la flexibilidad adicional que proporciona. Sin embargo, para entonces, es probable que el código que implementa este argumento adicional se haya roto de alguna manera sutil que nunca se notó, porque nunca se ha utilizado. O, cuando surge la necesidad de flexibilidad adicional, no lo hace de una manera que coincida con la expectativa temprana del programador. Los desarrolladores del kernel rutinariamente enviarán parches para eliminar argumentos no utilizados; en general, no deberían añadirse en primer lugar.”h]”hXÑA un nivel simple, considere una función que tiene un argumento que siempre se pasa como cero por todos los que la invocan. Uno podría mantener ese argumento por si alguien eventualmente necesita usar la flexibilidad adicional que proporciona. Sin embargo, para entonces, es probable que el código que implementa este argumento adicional se haya roto de alguna manera sutil que nunca se notó, porque nunca se ha utilizado. O, cuando surge la necesidad de flexibilidad adicional, no lo hace de una manera que coincida con la expectativa temprana del programador. Los desarrolladores del kernel rutinariamente enviarán parches para eliminar argumentos no utilizados; en general, no deberían añadirse en primer lugar.”…””}”(hjšhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K^hj{hžhubh¨)”}”(hX;Las capas de abstracción que ocultan el acceso al hardware, a menudo para permitir que la mayor parte de un controlador se utilice con varios sistemas operativos, son especialmente mal vistas. Dichas capas oscurecen el código y pueden imponer una penalización en el rendimiento; no pertenecen al kernel de Linux.”h]”hX;Las capas de abstracción que ocultan el acceso al hardware, a menudo para permitir que la mayor parte de un controlador se utilice con varios sistemas operativos, son especialmente mal vistas. Dichas capas oscurecen el código y pueden imponer una penalización en el rendimiento; no pertenecen al kernel de Linux.”…””}”(hj¨hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Kihj{hžhubh¨)”}”(hXJPor otro lado, si se encuentra copiando cantidades significativas de código de otro subsistema del kernel, es hora de preguntar si, de hecho, tendría sentido extraer parte de ese código en una biblioteca separada o implementar esa funcionalidad a un nivel superior. No tiene sentido replicar el mismo código en todo el kernel.”h]”hXJPor otro lado, si se encuentra copiando cantidades significativas de código de otro subsistema del kernel, es hora de preguntar si, de hecho, tendría sentido extraer parte de ese código en una biblioteca separada o implementar esa funcionalidad a un nivel superior. No tiene sentido replicar el mismo código en todo el kernel.”…””}”(hj¶hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Kohj{hžhubeh}”(h]”Œcapas-de-abstraccion”ah ]”h"]”Œcapas de abstracción”ah$]”h&]”uh1jehj–hžhhŸhØh KSubjf)”}”(hhh]”(jk)”}”(hŒ,Uso de #ifdef y del preprocesador en general”h]”hŒ,Uso de #ifdef y del preprocesador en general”…””}”(hjÏhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhjÌhžhhŸhØh Kvubh¨)”}”(hXïEl preprocesador de C tiene una tentación poderosa para algunos programadores de C, quienes lo ven como una forma de programar eficientemente una gran cantidad de flexibilidad en un archivo fuente. Pero el preprocesador no es C, y el uso intensivo de él da como resultado un código mucho más difícil de leer para otros y más difícil de verificar por el compilador para su corrección. El uso intensivo del preprocesador es asi siempre un signo de un código que necesita algo de limpieza.”h]”hXïEl preprocesador de C tiene una tentación poderosa para algunos programadores de C, quienes lo ven como una forma de programar eficientemente una gran cantidad de flexibilidad en un archivo fuente. Pero el preprocesador no es C, y el uso intensivo de él da como resultado un código mucho más difícil de leer para otros y más difícil de verificar por el compilador para su corrección. El uso intensivo del preprocesador es asi siempre un signo de un código que necesita algo de limpieza.”…””}”(hjÝhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh KxhjÌhžhubh¨)”}”(hX[La compilación condicional con `#ifdef` es, de hecho, una característica poderosa, y se usa dentro del kernel. Pero hay poco deseo de ver código que sté salpicado liberalmente con bloques `#ifdef`. Como regla general, el uso de `#ifdef` debe limitarse a los archivos de encabezado siempre que sea posible. El código condicionalmente compilado puede confinarse a funciones que, si el código no va a estar presente, simplemente se convierten en vacías. El compilador luego optimizará silenciosamente la llamada a la función vacía. El resultado es un código mucho más limpio y fácil de seguir.”h]”(hŒ La compilación condicional con ”…””}”(hjëhžhhŸNh NubjÁ)”}”(hŒ`#ifdef`”h]”hŒ#ifdef”…””}”(hjóhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÀhjëubhŒ˜ es, de hecho, una característica poderosa, y se usa dentro del kernel. Pero hay poco deseo de ver código que sté salpicado liberalmente con bloques ”…””}”(hjëhžhhŸNh NubjÁ)”}”(hŒ`#ifdef`”h]”hŒ#ifdef”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÀhjëubhŒ . Como regla general, el uso de ”…””}”(hjëhžhhŸNh NubjÁ)”}”(hŒ`#ifdef`”h]”hŒ#ifdef”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÀhjëubhXk debe limitarse a los archivos de encabezado siempre que sea posible. El código condicionalmente compilado puede confinarse a funciones que, si el código no va a estar presente, simplemente se convierten en vacías. El compilador luego optimizará silenciosamente la llamada a la función vacía. El resultado es un código mucho más limpio y fácil de seguir.”…””}”(hjëhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K€hjÌhžhubh¨)”}”(hXùLas macros del preprocesador de C presentan varios peligros, incluida la posible evaluación múltiple de expresiones con efectos secundarios y la falta de seguridad de tipos. Si te sientes tentado a definir una macro, considera crear una función en línea en su lugar. El código resultante será el mismo, pero las funciones en línea son más fáciles de leer, no evalúan sus argumentos varias veces y permiten que el compilador realice comprobaciones de tipo en los argumentos y el valor de retorno.”h]”hXùLas macros del preprocesador de C presentan varios peligros, incluida la posible evaluación múltiple de expresiones con efectos secundarios y la falta de seguridad de tipos. Si te sientes tentado a definir una macro, considera crear una función en línea en su lugar. El código resultante será el mismo, pero las funciones en línea son más fáciles de leer, no evalúan sus argumentos varias veces y permiten que el compilador realice comprobaciones de tipo en los argumentos y el valor de retorno.”…””}”(hj/hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh KŠhjÌhžhubeh}”(h]”Œ+uso-de-ifdef-y-del-preprocesador-en-general”ah ]”h"]”Œ,uso de #ifdef y del preprocesador en general”ah$]”h&]”uh1jehj–hžhhŸhØh Kvubjf)”}”(hhh]”(jk)”}”(hŒFunciones en línea”h]”hŒFunciones en línea”…””}”(hjHhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhjEhžhhŸhØh K“ubh¨)”}”(hXLas funciones en línea presentan su propio peligro, sin embargo. Los programadores pueden enamorarse de la eficiencia percibida al evitar una llamada a función y llenar un archivo fuente con funciones en línea. Esas funciones, sin embargo, pueden en realidad reducir el rendimiento. Dado que su código se replica en cada sitio de llamada, terminan hinchando el tamaño del kernel compilado. Eso, a su vez, crea presión en las cachés de memoria del procesador, lo que puede ralentizar la ejecución de manera drástica Las funciones en línea, como regla, deben ser bastante pequeñas y relativamente raras. El costo de una llamada a función, después de todo, no es tan alto; la creación de un gran número de funciones en línea es un ejemplo clásico de optimización prematura.”h]”hXLas funciones en línea presentan su propio peligro, sin embargo. Los programadores pueden enamorarse de la eficiencia percibida al evitar una llamada a función y llenar un archivo fuente con funciones en línea. Esas funciones, sin embargo, pueden en realidad reducir el rendimiento. Dado que su código se replica en cada sitio de llamada, terminan hinchando el tamaño del kernel compilado. Eso, a su vez, crea presión en las cachés de memoria del procesador, lo que puede ralentizar la ejecución de manera drástica Las funciones en línea, como regla, deben ser bastante pequeñas y relativamente raras. El costo de una llamada a función, después de todo, no es tan alto; la creación de un gran número de funciones en línea es un ejemplo clásico de optimización prematura.”…””}”(hjVhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K•hjEhžhubh¨)”}”(hXrEn general, los programadores del kernel ignoran los efectos de caché bajo su propio riesgo. El clásico intercambio de tiempo/espacio que se enseña en las clases de estructuras de datos iniciales a menudo no se aplica al hardware contemporáneo. El espacio *es* tiempo, en el sentido de que un programa más grande se ejecutará más lentamente que uno más compacto.”h]”(hXEn general, los programadores del kernel ignoran los efectos de caché bajo su propio riesgo. El clásico intercambio de tiempo/espacio que se enseña en las clases de estructuras de datos iniciales a menudo no se aplica al hardware contemporáneo. El espacio ”…””}”(hjdhžhhŸNh NubhŒemphasis”“”)”}”(hŒ*es*”h]”hŒes”…””}”(hjnhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jlhjdubhŒj tiempo, en el sentido de que un programa más grande se ejecutará más lentamente que uno más compacto.”…””}”(hjdhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K¡hjEhžhubh¨)”}”(hXLos compiladores más recientes toman un papel cada vez más activo al decidir si una función dada debe realmente ser en línea o no. Por lo tanto, la colocación liberal de palabras clave "inline" puede no solo ser excesiva; también podría ser irrelevante.”h]”hXLos compiladores más recientes toman un papel cada vez más activo al decidir si una función dada debe realmente ser en línea o no. Por lo tanto, la colocación liberal de palabras clave “inline†puede no solo ser excesiva; también podría ser irrelevante.”…””}”(hj†hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K§hjEhžhubeh}”(h]”Œfunciones-en-linea”ah ]”h"]”Œfunciones en línea”ah$]”h&]”uh1jehj–hžhhŸhØh K“ubjf)”}”(hhh]”(jk)”}”(hŒBloqueo”h]”hŒBloqueo”…””}”(hjŸhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhjœhžhhŸhØh K­ubh¨)”}”(hXøEn mayo de 2006, la pila de red "Devicescape" fue, con gran fanfarria, lanzada bajo la licencia GPL y puesta a disposición para su inclusión en el kernel principal. Esta donación fue una noticia bienvenida; el soporte para redes inalámbricas en Linux se consideraba, en el mejor de los casos, deficiente, y la pila de Devicescape ofrecía la promesa de solucionar esa situación. Sin embargo, este código no fue incluido en el kernel principal hasta junio de 2007 (versión 2.6.22). ¿Qué sucedió?”h]”hXüEn mayo de 2006, la pila de red “Devicescape†fue, con gran fanfarria, lanzada bajo la licencia GPL y puesta a disposición para su inclusión en el kernel principal. Esta donación fue una noticia bienvenida; el soporte para redes inalámbricas en Linux se consideraba, en el mejor de los casos, deficiente, y la pila de Devicescape ofrecía la promesa de solucionar esa situación. Sin embargo, este código no fue incluido en el kernel principal hasta junio de 2007 (versión 2.6.22). ¿Qué sucedió?”…””}”(hj­hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K¯hjœhžhubh¨)”}”(hXTEste código mostró varios signos de haber sido desarrollado a puertas cerradas en una empresa. Pero un problema importante en particular fue que no estaba diseñado para funcionar en sistemas multiprocesador. Antes de que esta pila de red (ahora llamada mac80211) pudiera fusionarse, se tuvo que implementar un esquema de bloqueo en ella.”h]”hXTEste código mostró varios signos de haber sido desarrollado a puertas cerradas en una empresa. Pero un problema importante en particular fue que no estaba diseñado para funcionar en sistemas multiprocesador. Antes de que esta pila de red (ahora llamada mac80211) pudiera fusionarse, se tuvo que implementar un esquema de bloqueo en ella.”…””}”(hj»hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K·hjœhžhubh¨)”}”(hXHubo un tiempo en que se podía desarrollar código para el kernel de Linux sin pensar en los problemas de concurrencia que presentan los sistemas multiprocesador. Ahora, sin embargo, este documento se está escribiendo en una computadora portátil con dos núcleos. Incluso en sistemas de un solo procesador, el trabajo que se está realizando para mejorar la capacidad de respuesta aumentará el nivel de concurrencia dentro del kernel. Los días en que se podía escribir código para el kernel sin pensar en el bloqueo han quedado atrás.”h]”hXHubo un tiempo en que se podía desarrollar código para el kernel de Linux sin pensar en los problemas de concurrencia que presentan los sistemas multiprocesador. Ahora, sin embargo, este documento se está escribiendo en una computadora portátil con dos núcleos. Incluso en sistemas de un solo procesador, el trabajo que se está realizando para mejorar la capacidad de respuesta aumentará el nivel de concurrencia dentro del kernel. Los días en que se podía escribir código para el kernel sin pensar en el bloqueo han quedado atrás.”…””}”(hjÉhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh K½hjœhžhubh¨)”}”(hX‚Cualquier recurso (estructuras de datos, registros de hardware, etc.) que pueda ser accedido concurrentemente por más de un hilo debe estar protegido por un bloqueo. El nuevo código debe escribirse teniendo en cuenta este requisito; implementar el bloqueo después de que el código ya ha sido desarrollado es una tarea mucho más difícil. Los desarrolladores del kernel deben tomarse el tiempo para comprender bien los primitivos de bloqueo disponibles para elegir la herramienta adecuada para el trabajo. El código que muestre una falta de atención a la concurrencia tendrá un camino difícil para ser incluido en el kernel principal.”h]”hX‚Cualquier recurso (estructuras de datos, registros de hardware, etc.) que pueda ser accedido concurrentemente por más de un hilo debe estar protegido por un bloqueo. El nuevo código debe escribirse teniendo en cuenta este requisito; implementar el bloqueo después de que el código ya ha sido desarrollado es una tarea mucho más difícil. Los desarrolladores del kernel deben tomarse el tiempo para comprender bien los primitivos de bloqueo disponibles para elegir la herramienta adecuada para el trabajo. El código que muestre una falta de atención a la concurrencia tendrá un camino difícil para ser incluido en el kernel principal.”…””}”(hj×hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh KÆhjœhžhubeh}”(h]”Œbloqueo”ah ]”h"]”Œbloqueo”ah$]”h&]”uh1jehj–hžhhŸhØh K­ubjf)”}”(hhh]”(jk)”}”(hŒ Regresiones”h]”hŒ Regresiones”…””}”(hjðhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhjíhžhhŸhØh KÑubh¨)”}”(hXóUn último peligro que vale la pena mencionar es el siguiente: puede ser tentador realizar un cambio (que puede traer grandes mejoras) que cause un problema para los usuarios existentes. Este tipo de cambio se llama una "regresión", y las regresiones se han vuelto muy mal recibidas en el kernel principal. Con pocas excepciones, los cambios que causan regresiones serán revertidos si la regresión no se puede solucionar de manera oportuna. Es mucho mejor evitar la regresión desde el principio.”h]”hX÷Un último peligro que vale la pena mencionar es el siguiente: puede ser tentador realizar un cambio (que puede traer grandes mejoras) que cause un problema para los usuarios existentes. Este tipo de cambio se llama una “regresiónâ€, y las regresiones se han vuelto muy mal recibidas en el kernel principal. Con pocas excepciones, los cambios que causan regresiones serán revertidos si la regresión no se puede solucionar de manera oportuna. Es mucho mejor evitar la regresión desde el principio.”…””}”(hjþhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh KÓhjíhžhubh¨)”}”(hXDA menudo se argumenta que una regresión puede justificarse si hace que las cosas funcionen para más personas de las que crea problemas. ¿Por qué no hacer un cambio si trae nueva funcionalidad a diez sistemas por cada uno que rompe? La mejor respuesta a esta pregunta fue expresada por Linus en julio de 2007 (traducido):”h]”hXDA menudo se argumenta que una regresión puede justificarse si hace que las cosas funcionen para más personas de las que crea problemas. ¿Por qué no hacer un cambio si trae nueva funcionalidad a diez sistemas por cada uno que rompe? La mejor respuesta a esta pregunta fue expresada por Linus en julio de 2007 (traducido):”…””}”(hj hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh KÛhjíhžhubhŒ literal_block”“”)”}”(hŒÉEntonces, no arreglamos errores introduciendo nuevos problemas. Eso lleva a la locura, y nadie sabe si realmente se avanza. ¿Es dos pasos adelante, uno atrás, o un paso adelante y dos atrás?”h]”hŒÉEntonces, no arreglamos errores introduciendo nuevos problemas. Eso lleva a la locura, y nadie sabe si realmente se avanza. ¿Es dos pasos adelante, uno atrás, o un paso adelante y dos atrás?”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1jhŸhØh Kãhjíhžhubh¨)”}”(hŒ#(https://lwn.net/Articles/243460/).”h]”(hŒ(”…””}”(hj,hžhhŸNh Nubj)”}”(hŒ https://lwn.net/Articles/243460/”h]”hŒ https://lwn.net/Articles/243460/”…””}”(hj4hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”j6uh1jhj,ubhŒ).”…””}”(hj,hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Kçhjíhžhubh¨)”}”(hX6Un tipo de regresión especialmente mal recibido es cualquier tipo de cambio en la ABI del espacio de usuario. Una vez que se ha exportado una interfaz al espacio de usuario, debe ser soportada indefinidamente. Este hecho hace que la creación de interfaces para el espacio de usuario sea particularmente desafiante: dado que no pueden cambiarse de manera incompatible, deben hacerse bien desde el principio. Por esta razón, siempre se requiere una gran cantidad de reflexión, documentación clara y una amplia revisión para las interfaces del espacio de usuario.”h]”hX6Un tipo de regresión especialmente mal recibido es cualquier tipo de cambio en la ABI del espacio de usuario. Una vez que se ha exportado una interfaz al espacio de usuario, debe ser soportada indefinidamente. Este hecho hace que la creación de interfaces para el espacio de usuario sea particularmente desafiante: dado que no pueden cambiarse de manera incompatible, deben hacerse bien desde el principio. Por esta razón, siempre se requiere una gran cantidad de reflexión, documentación clara y una amplia revisión para las interfaces del espacio de usuario.”…””}”(hjMhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Kéhjíhžhubeh}”(h]”Œ regresiones”ah ]”h"]”Œ regresiones”ah$]”h&]”uh1jehj–hžhhŸhØh KÑubjf)”}”(hhh]”(jk)”}”(hŒ(Herramientas de verificación de código”h]”hŒ(Herramientas de verificación de código”…””}”(hjfhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhjchžhhŸhØh Kóubh¨)”}”(hXPor ahora, al menos, escribir código libre de errores sigue siendo un ideal que pocos de nosotros podemos alcanzar. Sin embargo, lo que podemos esperar hacer es detectar y corregir tantos de esos errores como sea posible antes de que nuestro código se integre en el kernel principal. Con ese fin, los desarrolladores del kernel han reunido una impresionante variedad de herramientas que pueden detectar una amplia variedad de problemas oscuros de manera automatizada. Cualquier problema detectado por el ordenador es un problema que no afectará a un usuario más adelante, por lo que es lógico que las herramientas automatizadas se utilicen siempre que sea posible.”h]”hXPor ahora, al menos, escribir código libre de errores sigue siendo un ideal que pocos de nosotros podemos alcanzar. Sin embargo, lo que podemos esperar hacer es detectar y corregir tantos de esos errores como sea posible antes de que nuestro código se integre en el kernel principal. Con ese fin, los desarrolladores del kernel han reunido una impresionante variedad de herramientas que pueden detectar una amplia variedad de problemas oscuros de manera automatizada. Cualquier problema detectado por el ordenador es un problema que no afectará a un usuario más adelante, por lo que es lógico que las herramientas automatizadas se utilicen siempre que sea posible.”…””}”(hjthžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Kõhjchžhubh¨)”}”(hX-El primer paso es simplemente prestar atención a las advertencias producidas por el compilador. Las versiones contemporáneas de gcc pueden detectar (y advertir sobre) una gran cantidad de errores potenciales. Con bastante frecuencia, estas advertencias apuntan a problemas reales. El código enviado para revisión no debería, por regla general, producir ninguna advertencia del compilador. Al silenciar las advertencias, tenga cuidado de comprender la causa real e intente evitar "correcciones" que hagan desaparecer la advertencia sin abordar su causa.”h]”hX1El primer paso es simplemente prestar atención a las advertencias producidas por el compilador. Las versiones contemporáneas de gcc pueden detectar (y advertir sobre) una gran cantidad de errores potenciales. Con bastante frecuencia, estas advertencias apuntan a problemas reales. El código enviado para revisión no debería, por regla general, producir ninguna advertencia del compilador. Al silenciar las advertencias, tenga cuidado de comprender la causa real e intente evitar “correcciones†que hagan desaparecer la advertencia sin abordar su causa.”…””}”(hj‚hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Kÿhjchžhubh¨)”}”(hŒ³Tenga en cuenta que no todas las advertencias del compilador están habilitadas de forma predeterminada. Compile el kernel con "make KCFLAGS=-W" para obtener el conjunto completo.”h]”hŒ·Tenga en cuenta que no todas las advertencias del compilador están habilitadas de forma predeterminada. Compile el kernel con “make KCFLAGS=-W†para obtener el conjunto completo.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Mhjchžhubh¨)”}”(hX,El kernel proporciona varias opciones de configuración que activan funciones de depuración; la mayoría de estas se encuentran en el submenú "kernel hacking". Varias de estas opciones deben estar activadas para cualquier kernel utilizado para desarrollo o pruebas. En particular, debería activar:”h]”hX0El kernel proporciona varias opciones de configuración que activan funciones de depuración; la mayoría de estas se encuentran en el submenú “kernel hackingâ€. Varias de estas opciones deben estar activadas para cualquier kernel utilizado para desarrollo o pruebas. En particular, debería activar:”…””}”(hjžhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M hjchžhubhŒ block_quote”“”)”}”(hX)- FRAME_WARN para obtener advertencias sobre marcos de pila más grandes que una cantidad determinada. La salida generada puede ser extensa, pero no es necesario preocuparse por las advertencias de otras partes del kernel. - DEBUG_OBJECTS agregará código para rastrear la vida útil de varios objetos creados por el kernel y advertir cuando se realicen cosas fuera de orden. Si está agregando un subsistema que crea (y exporta) objetos complejos propios, considere agregar soporte para la infraestructura de depuración de objetos. - DEBUG_SLAB puede encontrar una variedad de errores en la asignación y uso de memoria; debe usarse en la mayoría de los kernels de desarrollo. - DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP y DEBUG_MUTEXES encontrarán una serie de errores comunes de bloqueo. ”h]”hŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒÝFRAME_WARN para obtener advertencias sobre marcos de pila más grandes que una cantidad determinada. La salida generada puede ser extensa, pero no es necesario preocuparse por las advertencias de otras partes del kernel. ”h]”h¨)”}”(hŒÜFRAME_WARN para obtener advertencias sobre marcos de pila más grandes que una cantidad determinada. La salida generada puede ser extensa, pero no es necesario preocuparse por las advertencias de otras partes del kernel.”h]”hŒÜFRAME_WARN para obtener advertencias sobre marcos de pila más grandes que una cantidad determinada. La salida generada puede ser extensa, pero no es necesario preocuparse por las advertencias de otras partes del kernel.”…””}”(hj½hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Mhj¹ubah}”(h]”h ]”h"]”h$]”h&]”uh1j·hj´ubj¸)”}”(hX6DEBUG_OBJECTS agregará código para rastrear la vida útil de varios objetos creados por el kernel y advertir cuando se realicen cosas fuera de orden. Si está agregando un subsistema que crea (y exporta) objetos complejos propios, considere agregar soporte para la infraestructura de depuración de objetos. ”h]”h¨)”}”(hX5DEBUG_OBJECTS agregará código para rastrear la vida útil de varios objetos creados por el kernel y advertir cuando se realicen cosas fuera de orden. Si está agregando un subsistema que crea (y exporta) objetos complejos propios, considere agregar soporte para la infraestructura de depuración de objetos.”h]”hX5DEBUG_OBJECTS agregará código para rastrear la vida útil de varios objetos creados por el kernel y advertir cuando se realicen cosas fuera de orden. Si está agregando un subsistema que crea (y exporta) objetos complejos propios, considere agregar soporte para la infraestructura de depuración de objetos.”…””}”(hjÕhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh MhjÑubah}”(h]”h ]”h"]”h$]”h&]”uh1j·hj´ubj¸)”}”(hŒDEBUG_SLAB puede encontrar una variedad de errores en la asignación y uso de memoria; debe usarse en la mayoría de los kernels de desarrollo. ”h]”h¨)”}”(hŒDEBUG_SLAB puede encontrar una variedad de errores en la asignación y uso de memoria; debe usarse en la mayoría de los kernels de desarrollo.”h]”hŒDEBUG_SLAB puede encontrar una variedad de errores en la asignación y uso de memoria; debe usarse en la mayoría de los kernels de desarrollo.”…””}”(hjíhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Mhjéubah}”(h]”h ]”h"]”h$]”h&]”uh1j·hj´ubj¸)”}”(hŒiDEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP y DEBUG_MUTEXES encontrarán una serie de errores comunes de bloqueo. ”h]”h¨)”}”(hŒhDEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP y DEBUG_MUTEXES encontrarán una serie de errores comunes de bloqueo.”h]”hŒhDEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP y DEBUG_MUTEXES encontrarán una serie de errores comunes de bloqueo.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j·hj´ubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1j²hŸhØh Mhj®ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¬hŸhØh Mhjchžhubh¨)”}”(hX;Hay bastantes otras opciones de depuración, algunas de las cuales se discutirán más adelante. Algunas de ellas tienen un impacto significativo en el rendimiento y no deben usarse todo el tiempo. Pero dedicar tiempo a aprender las opciones disponibles probablemente será recompensado muchas veces en poco tiempo.”h]”hX;Hay bastantes otras opciones de depuración, algunas de las cuales se discutirán más adelante. Algunas de ellas tienen un impacto significativo en el rendimiento y no deben usarse todo el tiempo. Pero dedicar tiempo a aprender las opciones disponibles probablemente será recompensado muchas veces en poco tiempo.”…””}”(hj'hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M#hjchžhubh¨)”}”(hX°Una de las herramientas de depuración más pesadas es el verificador de bloqueos, o "lockdep". Esta herramienta rastreará la adquisición y liberación de cada bloqueo (spinlock o mutex) en el sistema, el orden en que se adquieren los bloqueos en relación entre sí, el entorno actual de interrupción, y más. Luego, puede asegurarse de que los bloqueos siempre se adquieran en el mismo orden, que las mismas suposiciones de interrupción se apliquen en todas las situaciones, y así sucesivamente. En otras palabras, lockdep puede encontrar varios escenarios en los que el sistema podría, en raras ocasiones, bloquearse. Este tipo de problema puede ser doloroso (tanto para desarrolladores como para usuarios) en un sistema desplegado; lockdep permite encontrarlos de manera automatizada con anticipación. El código con cualquier tipo de bloqueo no trivial debe ejecutarse con lockdep habilitado antes de ser enviado para su inclusión.”h]”hX´Una de las herramientas de depuración más pesadas es el verificador de bloqueos, o “lockdepâ€. Esta herramienta rastreará la adquisición y liberación de cada bloqueo (spinlock o mutex) en el sistema, el orden en que se adquieren los bloqueos en relación entre sí, el entorno actual de interrupción, y más. Luego, puede asegurarse de que los bloqueos siempre se adquieran en el mismo orden, que las mismas suposiciones de interrupción se apliquen en todas las situaciones, y así sucesivamente. En otras palabras, lockdep puede encontrar varios escenarios en los que el sistema podría, en raras ocasiones, bloquearse. Este tipo de problema puede ser doloroso (tanto para desarrolladores como para usuarios) en un sistema desplegado; lockdep permite encontrarlos de manera automatizada con anticipación. El código con cualquier tipo de bloqueo no trivial debe ejecutarse con lockdep habilitado antes de ser enviado para su inclusión.”…””}”(hj5hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M)hjchžhubh¨)”}”(hXÕComo programador diligente del kernel, sin duda alguna, verificará el estado de retorno de cualquier operación (como una asignación de memoria) que pueda fallar. Sin embargo, el hecho es que las rutas de recuperación de fallos resultantes probablemente no hayan sido probadas en absoluto. El código no probado tiende a ser código roto; podría tener mucha más confianza en su código si todas esas rutas de manejo de errores se hubieran ejercitado algunas veces.”h]”hXÕComo programador diligente del kernel, sin duda alguna, verificará el estado de retorno de cualquier operación (como una asignación de memoria) que pueda fallar. Sin embargo, el hecho es que las rutas de recuperación de fallos resultantes probablemente no hayan sido probadas en absoluto. El código no probado tiende a ser código roto; podría tener mucha más confianza en su código si todas esas rutas de manejo de errores se hubieran ejercitado algunas veces.”…””}”(hjChžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M7hjchžhubh¨)”}”(hXPEl kernel proporciona un marco de inyección de fallos que puede hacer precisamente eso, especialmente donde están involucradas las asignaciones de memoria. Con la inyección de fallos habilitada, un porcentaje configurable de las asignaciones de memoria fallarán; estas fallas pueden restringirse a un rango específico de código. Ejecutar con la inyección de fallos habilitada permite al programador ver cómo responde el código cuando las cosas van mal. Consulte Documentation/fault-injection/fault-injection.rst para obtener más información sobre cómo utilizar esta funcionalidad.”h]”hXPEl kernel proporciona un marco de inyección de fallos que puede hacer precisamente eso, especialmente donde están involucradas las asignaciones de memoria. Con la inyección de fallos habilitada, un porcentaje configurable de las asignaciones de memoria fallarán; estas fallas pueden restringirse a un rango específico de código. Ejecutar con la inyección de fallos habilitada permite al programador ver cómo responde el código cuando las cosas van mal. Consulte Documentation/fault-injection/fault-injection.rst para obtener más información sobre cómo utilizar esta funcionalidad.”…””}”(hjQhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M?hjchžhubh¨)”}”(hXLOtros tipos de errores se pueden encontrar con la herramienta de análisis estático "sparse". Con sparse, el programador puede recibir advertencias sobre confusiones entre direcciones del espacio de usuario y del kernel, mezcla de cantidades big-endian y little-endian, el paso de valores enteros donde se espera un conjunto de banderas de bits, y así sucesivamente. Sparse debe instalarse por separado (puede encontrarse en https://sparse.wiki.kernel.org/index.php/Main_Page si su distribución no lo empaqueta); luego, puede ejecutarse en el código agregando "C=1" a su comando make.”h]”(hX¯Otros tipos de errores se pueden encontrar con la herramienta de análisis estático “sparseâ€. Con sparse, el programador puede recibir advertencias sobre confusiones entre direcciones del espacio de usuario y del kernel, mezcla de cantidades big-endian y little-endian, el paso de valores enteros donde se espera un conjunto de banderas de bits, y así sucesivamente. Sparse debe instalarse por separado (puede encontrarse en ”…””}”(hj_hžhhŸNh Nubj)”}”(hŒ2https://sparse.wiki.kernel.org/index.php/Main_Page”h]”hŒ2https://sparse.wiki.kernel.org/index.php/Main_Page”…””}”(hjghžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jiuh1jhj_ubhŒs si su distribución no lo empaqueta); luego, puede ejecutarse en el código agregando “C=1†a su comando make.”…””}”(hj_hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh MIhjchžhubh¨)”}”(hXLa herramienta "Coccinelle" (http://coccinelle.lip6.fr/) puede encontrar una amplia variedad de posibles problemas de codificación; también puede proponer correcciones para esos problemas. Bastantes "parches semánticos" para el kernel se han empaquetado en el directorio scripts/coccinelle; ejecutar "make coccicheck" ejecutará esos parches semánticos e informará sobre cualquier problema encontrado. Consulte: ref:`Documentation/dev-tools/coccinelle.rst ` para obtener más información.”h]”(hŒ!La herramienta “Coccinelle†(”…””}”(hj€hžhhŸNh Nubj)”}”(hŒhttp://coccinelle.lip6.fr/”h]”hŒhttp://coccinelle.lip6.fr/”…””}”(hjˆhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jŠuh1jhj€ubhXv) puede encontrar una amplia variedad de posibles problemas de codificación; también puede proponer correcciones para esos problemas. Bastantes “parches semánticos†para el kernel se han empaquetado en el directorio scripts/coccinelle; ejecutar “make coccicheck†ejecutará esos parches semánticos e informará sobre cualquier problema encontrado. Consulte: ref:”…””}”(hj€hžhhŸNh NubjÁ)”}”(hŒ>`Documentation/dev-tools/coccinelle.rst `”h]”hŒ”…””}”(hj›hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÀhj€ubhŒ para obtener más información.”…””}”(hj€hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh MShjchžhubh¨)”}”(hX1Otros tipos de errores de portabilidad se encuentran mejor compilando su código para otras arquitecturas. Si no tiene un sistema S/390 o una placa de desarrollo Blackfin a mano, aún puede realizar el paso de compilación. Un gran conjunto de compiladores cruzados para sistemas x86 se puede encontrar en”h]”hX1Otros tipos de errores de portabilidad se encuentran mejor compilando su código para otras arquitecturas. Si no tiene un sistema S/390 o una placa de desarrollo Blackfin a mano, aún puede realizar el paso de compilación. Un gran conjunto de compiladores cruzados para sistemas x86 se puede encontrar en”…””}”(hj³hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M\hjchžhubj­)”}”(hŒ,https://www.kernel.org/pub/tools/crosstool/ ”h]”h¨)”}”(hŒ+https://www.kernel.org/pub/tools/crosstool/”h]”j)”}”(hjÇh]”hŒ+https://www.kernel.org/pub/tools/crosstool/”…””}”(hjÉhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jÇuh1jhjÅubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh MbhjÁubah}”(h]”h ]”h"]”h$]”h&]”uh1j¬hŸhØh Mbhjchžhubh¨)”}”(hŒMuchos sistemas de compilación disponibles comercialmente también se pueden utilizar para compilar código de kernel para una amplia gama de arquitecturas.”h]”hŒMuchos sistemas de compilación disponibles comercialmente también se pueden utilizar para compilar código de kernel para una amplia gama de arquitecturas.”…””}”(hjãhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Mdhjchžhubh¨)”}”(hXBLos desarrolladores del kernel son afortunados: tienen acceso a una variedad de herramientas de verificación de código de la que los desarrolladores de la mayoría de los otros sistemas pueden estar celosos. Pero todas esas herramientas no servirán de nada si no las usa. El resultado final de ignorar estas herramientas es simple: alguien más puede notificarle de un problema en su código a través de un "oportuno" comentario en la lista de correo o, peor aún, el código problemático podría ser eliminado. Es mucho más fácil usar estas herramientas en primer lugar.”h]”hXFLos desarrolladores del kernel son afortunados: tienen acceso a una variedad de herramientas de verificación de código de la que los desarrolladores de la mayoría de los otros sistemas pueden estar celosos. Pero todas esas herramientas no servirán de nada si no las usa. El resultado final de ignorar estas herramientas es simple: alguien más puede notificarle de un problema en su código a través de un “oportuno†comentario en la lista de correo o, peor aún, el código problemático podría ser eliminado. Es mucho más fácil usar estas herramientas en primer lugar.”…””}”(hjñhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Mhhjchžhubeh}”(h]”Œ&herramientas-de-verificacion-de-codigo”ah ]”h"]”Œ(herramientas de verificación de código”ah$]”h&]”uh1jehj–hžhhŸhØh Kóubjf)”}”(hhh]”(jk)”}”(hŒDocumentación”h]”hŒDocumentación”…””}”(hj hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhjhžhhŸhØh Mrubh¨)”}”(hXvLa documentación a menudo ha sido más la excepción que la regla en el desarrollo del kernel. Aun así, una documentación adecuada ayudará a facilitar la integración de nuevo código en el kernel, hará la vida más fácil a otros desarrolladores, y será útil para sus usuarios. En muchos casos, la inclusión de documentación se ha vuelto esencialmente obligatoria.”h]”hXvLa documentación a menudo ha sido más la excepción que la regla en el desarrollo del kernel. Aun así, una documentación adecuada ayudará a facilitar la integración de nuevo código en el kernel, hará la vida más fácil a otros desarrolladores, y será útil para sus usuarios. En muchos casos, la inclusión de documentación se ha vuelto esencialmente obligatoria.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Mthjhžhubh¨)”}”(hXùLa primera pieza de documentación para cualquier parche es su changelog asociado. Las entradas de registro deben describir el problema que se está esolviendo, la forma de la solución, las personas que trabajaron en el parche, cualquier efecto relevante en el rendimiento, y cualquier otra cosa que pueda ser necesaria para entender el parche. Asegúrese de que el changelog diga *por qué* el parche vale la pena ser aplicado; un sorprendente número de desarrolladores no proporciona esa información.”h]”(hX~La primera pieza de documentación para cualquier parche es su changelog asociado. Las entradas de registro deben describir el problema que se está esolviendo, la forma de la solución, las personas que trabajaron en el parche, cualquier efecto relevante en el rendimiento, y cualquier otra cosa que pueda ser necesaria para entender el parche. Asegúrese de que el changelog diga ”…””}”(hj&hžhhŸNh Nubjm)”}”(hŒ *por qué*”h]”hŒpor qué”…””}”(hj.hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jlhj&ubhŒq el parche vale la pena ser aplicado; un sorprendente número de desarrolladores no proporciona esa información.”…””}”(hj&hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M{hjhžhubh¨)”}”(hX”Cualquier código que agregue una nueva interfaz para el espacio de usuario, incluidos los nuevos archivos de sysfs o /proc, debe incluir documentación de esa interfaz que permita a los desarrolladores del espacio de usuario saber con qué están trabajando. Consulte `Documentation/ABI/README` para una descripción de cómo debe formatearse esta documentación y qué información debe proporcionarse.”h]”(hX Cualquier código que agregue una nueva interfaz para el espacio de usuario, incluidos los nuevos archivos de sysfs o /proc, debe incluir documentación de esa interfaz que permita a los desarrolladores del espacio de usuario saber con qué están trabajando. Consulte ”…””}”(hjFhžhhŸNh NubjÁ)”}”(hŒ`Documentation/ABI/README`”h]”hŒDocumentation/ABI/README”…””}”(hjNhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÀhjFubhŒm para una descripción de cómo debe formatearse esta documentación y qué información debe proporcionarse.”…””}”(hjFhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Mƒhjhžhubh¨)”}”(hŒöEl archivo :ref:`Documentation/admin-guide/kernel-parameters.rst ` describe todos los parámetros de arranque del kernel. Cualquier parche que agregue nuevos parámetros debe agregar las entradas correspondientes a este archivo.”h]”(hŒ El archivo ”…””}”(hjfhžhhŸNh Nubh)”}”(hŒI:ref:`Documentation/admin-guide/kernel-parameters.rst `”h]”hŒinline”“”)”}”(hjph]”hŒ/Documentation/admin-guide/kernel-parameters.rst”…””}”(hjthžhhŸNh Nubah}”(h]”h ]”(Œxref”Œstd”Œstd-ref”eh"]”h$]”h&]”uh1jrhjnubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œ#translations/sp_SP/process/4.Coding”Œ refdomain”jŒreftype”Œref”Œ refexplicit”ˆŒrefwarn”ˆŒ reftarget”Œkernelparameters”uh1hhŸhØh MŠhjfubhŒ¢ describe todos los parámetros de arranque del kernel. Cualquier parche que agregue nuevos parámetros debe agregar las entradas correspondientes a este archivo.”…””}”(hjfhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh MŠhjhžhubh¨)”}”(hŒ«Cualquier nueva opción de configuración debe ir acompañada de un texto de ayuda que explique claramente las opciones y cuándo el usuario podría querer seleccionarlas.”h]”hŒ«Cualquier nueva opción de configuración debe ir acompañada de un texto de ayuda que explique claramente las opciones y cuándo el usuario podría querer seleccionarlas.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Mhjhžhubh¨)”}”(hXLa información de la API interna para muchos subsistemas está documentada mediante comentarios especialmente formateados; estos comentarios pueden extraerse y formatearse de diversas maneras mediante el script "kernel-doc". Si está trabajando dentro de un subsistema que tiene comentarios de kerneldoc, debe mantenerlos y agregarlos según corresponda para las funciones disponibles externamente. Incluso en áreas que no han sido tan documentadas, no hay ningún inconveniente en agregar comentarios de kerneldoc para el futuro; de hecho, esta puede ser una actividad útil para desarrolladores de kernel principiantes. El formato de estos comentarios, junto con alguna información sobre cómo crear plantillas de kerneldoc, se puede encontrar en :ref:`Documentation/doc-guide/ `.”h]”(hXôLa información de la API interna para muchos subsistemas está documentada mediante comentarios especialmente formateados; estos comentarios pueden extraerse y formatearse de diversas maneras mediante el script “kernel-docâ€. Si está trabajando dentro de un subsistema que tiene comentarios de kerneldoc, debe mantenerlos y agregarlos según corresponda para las funciones disponibles externamente. Incluso en áreas que no han sido tan documentadas, no hay ningún inconveniente en agregar comentarios de kerneldoc para el futuro; de hecho, esta puede ser una actividad útil para desarrolladores de kernel principiantes. El formato de estos comentarios, junto con alguna información sobre cómo crear plantillas de kerneldoc, se puede encontrar en ”…””}”(hj«hžhhŸNh Nubh)”}”(hŒ+:ref:`Documentation/doc-guide/ `”h]”js)”}”(hjµh]”hŒDocumentation/doc-guide/”…””}”(hj·hžhhŸNh Nubah}”(h]”h ]”(j~Œstd”Œstd-ref”eh"]”h$]”h&]”uh1jrhj³ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”j‹Œ refdomain”jÁŒreftype”Œref”Œ refexplicit”ˆŒrefwarn”ˆj‘Œ doc_guide”uh1hhŸhØh M”hj«ubhŒ.”…””}”(hj«hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M”hjhžhubh¨)”}”(hXÀCualquiera que lea una cantidad significativa de código existente del kernel notará que, a menudo, los comentarios son notables por su ausencia. Una vez más, las expectativas para el nuevo código son más altas que en el pasado; integrar código sin comentarios será más difícil. Dicho esto, hay poco deseo de tener código excesivamente comentado. El código en sí debe ser legible, con comentarios que expliquen los aspectos más sutiles.”h]”hXÀCualquiera que lea una cantidad significativa de código existente del kernel notará que, a menudo, los comentarios son notables por su ausencia. Una vez más, las expectativas para el nuevo código son más altas que en el pasado; integrar código sin comentarios será más difícil. Dicho esto, hay poco deseo de tener código excesivamente comentado. El código en sí debe ser legible, con comentarios que expliquen los aspectos más sutiles.”…””}”(hjÝhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M¡hjhžhubh¨)”}”(hXZCiertas cosas siempre deben comentarse. El uso de barreras de memoria debe ir acompañado de una línea que explique por qué la barrera es necesaria. Las reglas de bloqueo para las estructuras de datos generalmente necesitan explicarse en algún lugar. Las estructuras de datos importantes en general necesitan documentación completa. Las dependencias no obvias entre fragmentos de código separados deben señalarse. Cualquier cosa que pueda tentar a un maintainer de código a hacer una "limpieza" incorrecta necesita un comentario que explique por qué se hace de esa manera. Y así sucesivamente.”h]”hX^Ciertas cosas siempre deben comentarse. El uso de barreras de memoria debe ir acompañado de una línea que explique por qué la barrera es necesaria. Las reglas de bloqueo para las estructuras de datos generalmente necesitan explicarse en algún lugar. Las estructuras de datos importantes en general necesitan documentación completa. Las dependencias no obvias entre fragmentos de código separados deben señalarse. Cualquier cosa que pueda tentar a un maintainer de código a hacer una “limpieza†incorrecta necesita un comentario que explique por qué se hace de esa manera. Y así sucesivamente.”…””}”(hjëhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M¨hjhžhubeh}”(h]”Œ documentacion”ah ]”h"]”Œdocumentación”ah$]”h&]”uh1jehj–hžhhŸhØh Mrubjf)”}”(hhh]”(jk)”}”(hŒCambios en la API interna”h]”hŒCambios en la API interna”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jjhjhžhhŸhØh M³ubh¨)”}”(hX@La interfaz binaria proporcionada por el kernel al espacio de usuario no se puede romper, excepto en las circunstancias más graves. Las interfaces de programación internas del kernel, en cambio, son altamente fluidas y pueden cambiarse cuando surge la necesidad. Si usted se encuentra teniendo que hacer un rodeo alrededor de una API del kernel, o simplemente no utilizando una funcionalidad específica porque no cumple con sus necesidades, eso puede ser una señal de que la API necesita cambiar. Como desarrollador del kernel, usted está autorizado a hacer esos cambios.”h]”hX@La interfaz binaria proporcionada por el kernel al espacio de usuario no se puede romper, excepto en las circunstancias más graves. Las interfaces de programación internas del kernel, en cambio, son altamente fluidas y pueden cambiarse cuando surge la necesidad. Si usted se encuentra teniendo que hacer un rodeo alrededor de una API del kernel, o simplemente no utilizando una funcionalidad específica porque no cumple con sus necesidades, eso puede ser una señal de que la API necesita cambiar. Como desarrollador del kernel, usted está autorizado a hacer esos cambios.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh Mµhjhžhubh¨)”}”(hX’Hay, por supuesto, algunas condiciones. Los cambios en la API se pueden hacer, pero necesitan estar bien justificados. Entonces, cualquier parche que realice un cambio en la API interna debe ir acompañado de una descripción de cuál es el cambio y por qué es necesario. Este tipo de cambio también debe desglosarse en un parche separado, en lugar de estar enterrado dentro de un parche más grande.”•h]”hX’Hay, por supuesto, algunas condiciones. Los cambios en la API se pueden hacer, pero necesitan estar bien justificados. Entonces, cualquier parche que realice un cambio en la API interna debe ir acompañado de una descripción de cuál es el cambio y por qué es necesario. Este tipo de cambio también debe desglosarse en un parche separado, en lugar de estar enterrado dentro de un parche más grande.”…””}”(hj hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh M¾hjhžhubh¨)”}”(hX‹La otra condición es que un desarrollador que cambia una API interna generalmente está encargado de la tarea de corregir cualquier código dentro del árbol del kernel que se vea afectado por el cambio. Para una función ampliamente utilizada, este deber puede llevar a literalmente cientos o miles de cambios, muchos de los cuales probablemente entren en conflicto con el trabajo que otros desarrolladores están realizando. No hace falta decir que esto puede ser un trabajo grande, por lo que es mejor asegurarse de que la justificación sea sólida. Tenga en cuenta que la herramienta Coccinelle puede ayudar con los cambios de API a gran escala.”h]”hX‹La otra condición es que un desarrollador que cambia una API interna generalmente está encargado de la tarea de corregir cualquier código dentro del árbol del kernel que se vea afectado por el cambio. Para una función ampliamente utilizada, este deber puede llevar a literalmente cientos o miles de cambios, muchos de los cuales probablemente entren en conflicto con el trabajo que otros desarrolladores están realizando. No hace falta decir que esto puede ser un trabajo grande, por lo que es mejor asegurarse de que la justificación sea sólida. Tenga en cuenta que la herramienta Coccinelle puede ayudar con los cambios de API a gran escala.”…””}”(hj.hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh MÅhjhžhubh¨)”}”(hX/Cuando se realice un cambio incompatible en la API, siempre que sea posible, se debe asegurar que el código que no ha sido actualizado sea detectado por el compilador. Esto le ayudará a estar seguro de que ha encontrado todos los usos en el árbol de esa interfaz. También alertará a los desarrolladores de código fuera del árbol de que hay un cambio al que necesitan responder. Apoyar el código fuera del árbol no es algo de lo que los desarrolladores del kernel deban preocuparse, pero tampoco tenemos que dificultarles la vida más de lo necesario.”h]”hX/Cuando se realice un cambio incompatible en la API, siempre que sea posible, se debe asegurar que el código que no ha sido actualizado sea detectado por el compilador. Esto le ayudará a estar seguro de que ha encontrado todos los usos en el árbol de esa interfaz. También alertará a los desarrolladores de código fuera del árbol de que hay un cambio al que necesitan responder. Apoyar el código fuera del árbol no es algo de lo que los desarrolladores del kernel deban preocuparse, pero tampoco tenemos que dificultarles la vida más de lo necesario.”…””}”(hj<hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h§hŸhØh MÏhjhžhubeh}”(h]”Œcambios-en-la-api-interna”ah ]”h"]”Œcambios en la api interna”ah$]”h&]”uh1jehj–hžhhŸhØh M³ubeh}”(h]”Œ problemas”ah ]”h"]”Œ problemas”ah$]”h&]”uh1jehjghžhhŸhØh Kubeh}”(h]”(Œconseguir-el-codigo-correcto”jdeh ]”h"]”(Œconseguir el código correcto”Œsp_development_coding”eh$]”h&]”uh1jehhhžhhŸhØh K Œexpect_referenced_by_name”}”j`jYsŒexpect_referenced_by_id”}”jdjYsubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hØuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(jjNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jŠŒerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hØŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”jd]”jYasŒnameids”}”(j`jdj_j\jWjTjxjujÉjÆjBj?j™j–jêjçj`j]jjjþjûjOjLuŒ nametypes”}”(j`ˆj_‰jW‰jx‰jɉjB‰j™‰jê‰j`‰j‰jþ‰jO‰uh}”(jdjgj\jgjTj–juj§jÆj{j?jÌj–jEjçjœj]jíjjcjûjjLjuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”hŒsystem_message”“”)”}”(hhh]”h¨)”}”(hhh]”hŒ;Hyperlink target "sp-development-coding" is not referenced.”…””}”hjôsbah}”(h]”h ]”h"]”h$]”h&]”uh1h§hjñubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”ŒINFO”Œsource”hØŒline”Kuh1jïubaŒ transformer”NŒ include_log”]”Œ5Documentation/translations/sp_SP/process/4.Coding.rst”(NNNNt”†”aŒ decoration”Nhžhub.