함수선언부 관련 매크로 (__attribute__)

__init

  • __section(.init.text) __cold notrace
    • __section(S) __attribute__ ((__section__(#S)))
  • init.text 섹션에 해당 코드를 배치한다.

__cold

  • __attribute__((__cold__))
  • 호출될 가능성이 희박한 함수를 뜻함.
  • 속도보다 사이즈에 더 최적화를 수행한다.
  • unlikely()의 사용을 줄일 수 있게 된다. unlikely() 함수들은 old compiler 호환성을 위해 그냥같이  사용한다.
  • text 섹션의 한 쪽에 __cold 펑션들을 모아두는 지역성(locality)도 있다. 당연히 이로 인한 cache 효율성도 좋아진다.

notrace

__weak

  • __attribute__((weak))
  • 해당 심볼을 weak symbol로 만든다.
  • 링커가 링크를 수행 시 다른곳에 같은 이름으로 만든 strong symbol이 존재하면 weak symbol 대신 strong symbol을 사용한다.
  • 참고: GCC Weak Function Attributes

__attribute_const__

__pure

  •  __attribute__((pure)
  • 전달 받은 인수외에 global 변수로의 access는 읽기만 가능한다.
  • side effect가 생기지 않는다.

 

__read_mostly

  • __attribute__((__section__(“.data.read_mostly”)))
  • 읽기 위주의 데이터들만을 위한 섹션으로 캐시 라인 바운싱을 회피하기 위한 솔루션
    • SMP 머신에서 cache eviction이 최소화될 수 있는 데이터들끼리 모여있도록 함으로 성능향상을 목표로 하였다.
    • 캐시 라인 바운싱 참고: Exclusive loads and store | 문c
  • 참고: Short subjects: kerneloops, read-mostly, and port 80 | LWN.net
  • .data.read_mostly 섹션은 RO_DATA_SECTION 다음에 위치한 RW_DATA_SECTION 에 정의되어 있다.

include/asm-generic/vmlinux.lds.h

/*
 * Helper macros to support writing architecture specific
 * linker scripts.
 *
 * A minimal linker scripts has following content:
 * [This is a sample, architectures may have special requiriements]
 *
 * OUTPUT_FORMAT(...)
 * OUTPUT_ARCH(...)
 * ENTRY(...)
 * SECTIONS
 * {
 *      . = START;
 *      __init_begin = .;
 *      HEAD_TEXT_SECTION
 *      INIT_TEXT_SECTION(PAGE_SIZE)
 *      INIT_DATA_SECTION(...)
 *      PERCPU_SECTION(CACHELINE_SIZE)
 *      __init_end = .;
 *
 *      _stext = .;
 *      TEXT_SECTION = 0
 *      _etext = .;
 *
 *      _sdata = .;
 *      RO_DATA_SECTION(PAGE_SIZE)
 *      RW_DATA_SECTION(...)
 *      _edata = .;
 *
 *      EXCEPTION_TABLE(...)
 *      NOTES
 *
 *      BSS_SECTION(0, 0, 0)
 *      _end = .;
 *
 *      STABS_DEBUG
 *      DWARF_DEBUG
 *
 *      DISCARDS                // must be the last
 * }
 *
 * [__init_begin, __init_end] is the init section that may be freed after init
 *      // __init_begin and __init_end should be page aligned, so that we can
 *      // free the whole .init memory
 * [_stext, _etext] is the text section
 * [_sdata, _edata] is the data section
 *
 * Some of the included output section have their own set of constants.
 * Examples are: [__initramfs_start, __initramfs_end] for initramfs and
 *               [__nosave_begin, __nosave_end] for the nosave data
 */

 

/*
 * Writeable data.
 * All sections are combined in a single .data section.
 * The sections following CONSTRUCTORS are arranged so their
 * typical alignment matches.
 * A cacheline is typical/always less than a PAGE_SIZE so
 * the sections that has this restriction (or similar)
 * is located before the ones requiring PAGE_SIZE alignment.
 * NOSAVE_DATA starts and ends with a PAGE_SIZE alignment which
 * matches the requirement of PAGE_ALIGNED_DATA.
 *
 * use 0 as page_align if page_aligned data is not used */
#define RW_DATA_SECTION(cacheline, pagealigned, inittask)               \
        . = ALIGN(PAGE_SIZE);                                           \
        .data : AT(ADDR(.data) - LOAD_OFFSET) {                         \
                INIT_TASK_DATA(inittask)                                \
                NOSAVE_DATA                                             \
                PAGE_ALIGNED_DATA(pagealigned)                          \
                CACHELINE_ALIGNED_DATA(cacheline)                       \
                READ_MOSTLY_DATA(cacheline)                             \
                DATA_DATA                                               \
                CONSTRUCTORS                                            \
        }

 

#define READ_MOSTLY_DATA(align)                                         \
        . = ALIGN(align);                                               \
        *(.data..read_mostly)                                           \
        . = ALIGN(align);

 

__used

  • __attribute__((used))
  • 해당 객체 또는 함수가 참조되지 않아도 사용하는 것처럼 컴파일러로 하여금 삭제되지 않도록 한다.

__visible

  • __attribute__((externally_visible))
  • LTO(Link Time Optimization) 기능을 사용하는 경우 caller(호출측)와 callee(피호출측)의 관계에서 링커가 callee가 한 번만 사용된다고 판단되는 경우 caller에 callee를 inline화 하여 집어 넣는다.
  • externally_visible 속성을 사용하는 경우 LTO 옵션을 사용하여 링크를 하는 경우에도 하나의 완전한 함수나 객체로 외부에 보여질 수 있도록 심볼화하여 해당 함수나 객체가 inline화 되지 않도록 막는다.
  • -flto 또는 -whole-program을 사용하여 LTO 기능을 동작시킨다.
  • 참고: Enable link-time optimization (after switching to avr-gcc 4.5 or greater) 

 

asmlinkage

  • 어셈블리 코드에서 C 함수를 호출할 때 함수 인자의 전달을 레지스터가 아닌 스택을 이용하도록 해주는 속성지정 매크로이다.
  • extern “C”로 정의되어 있다.
  • 참고: [Linux] asmlinkage – F/OSS

 

참고

댓글 남기기