The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sys/pcpu.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2001 Wind River Systems, Inc.
    3  * All rights reserved.
    4  * Written by: John Baldwin <jhb@FreeBSD.org>
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 4. Neither the name of the author nor the names of any co-contributors
   15  *    may be used to endorse or promote products derived from this software
   16  *    without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  *
   30  * $FreeBSD: releng/8.3/sys/sys/pcpu.h 214198 2010-10-22 08:42:44Z avg $
   31  */
   32 
   33 #ifndef _SYS_PCPU_H_
   34 #define _SYS_PCPU_H_
   35 
   36 #ifdef LOCORE
   37 #error "no assembler-serviceable parts inside"
   38 #endif
   39 
   40 #include <sys/queue.h>
   41 #include <sys/vmmeter.h>
   42 #include <sys/resource.h>
   43 #include <machine/pcpu.h>
   44 
   45 /*
   46  * Define a set for pcpu data.
   47  */
   48 extern uintptr_t *__start_set_pcpu;
   49 extern uintptr_t *__stop_set_pcpu;
   50 
   51 /*
   52  * Array of dynamic pcpu base offsets.  Indexed by id.
   53  */
   54 extern uintptr_t dpcpu_off[];
   55 
   56 /*
   57  * Convenience defines.
   58  */
   59 #define DPCPU_START             ((uintptr_t)&__start_set_pcpu)
   60 #define DPCPU_STOP              ((uintptr_t)&__stop_set_pcpu)
   61 #define DPCPU_BYTES             (DPCPU_STOP - DPCPU_START)
   62 #define DPCPU_MODMIN            2048
   63 #define DPCPU_SIZE              roundup2(DPCPU_BYTES, PAGE_SIZE)
   64 #define DPCPU_MODSIZE           (DPCPU_SIZE - (DPCPU_BYTES - DPCPU_MODMIN))
   65 
   66 /*
   67  * Declaration and definition.
   68  */
   69 #define DPCPU_NAME(n)           pcpu_entry_##n
   70 #define DPCPU_DECLARE(t, n)     extern t DPCPU_NAME(n)
   71 #define DPCPU_DEFINE(t, n)      t DPCPU_NAME(n) __section("set_pcpu") __used
   72 
   73 /*
   74  * Accessors with a given base.
   75  */
   76 #define _DPCPU_PTR(b, n)                                                \
   77     (__typeof(DPCPU_NAME(n))*)((b) + (uintptr_t)&DPCPU_NAME(n))
   78 #define _DPCPU_GET(b, n)        (*_DPCPU_PTR(b, n))
   79 #define _DPCPU_SET(b, n, v)     (*_DPCPU_PTR(b, n) = v)
   80 
   81 /*
   82  * Accessors for the current cpu.
   83  */
   84 #define DPCPU_PTR(n)            _DPCPU_PTR(PCPU_GET(dynamic), n)
   85 #define DPCPU_GET(n)            (*DPCPU_PTR(n))
   86 #define DPCPU_SET(n, v)         (*DPCPU_PTR(n) = v)
   87 
   88 /*
   89  * Accessors for remote cpus.
   90  */
   91 #define DPCPU_ID_PTR(i, n)      _DPCPU_PTR(dpcpu_off[(i)], n)
   92 #define DPCPU_ID_GET(i, n)      (*DPCPU_ID_PTR(i, n))
   93 #define DPCPU_ID_SET(i, n, v)   (*DPCPU_ID_PTR(i, n) = v)
   94 
   95 /*
   96  * Utility macros.
   97  */
   98 #define DPCPU_SUM(n) __extension__                                      \
   99 ({                                                                      \
  100         u_int _i;                                                       \
  101         __typeof(*DPCPU_PTR(n)) sum;                                    \
  102                                                                         \
  103         sum = 0;                                                        \
  104         CPU_FOREACH(_i) {                                               \
  105                 sum += *DPCPU_ID_PTR(_i, n);                            \
  106         }                                                               \
  107         sum;                                                            \
  108 })
  109 
  110 #define DPCPU_VARSUM(n, var) __extension__                              \
  111 ({                                                                      \
  112         u_int _i;                                                       \
  113         __typeof((DPCPU_PTR(n))->var) sum;                              \
  114                                                                         \
  115         sum = 0;                                                        \
  116         CPU_FOREACH(_i) {                                               \
  117                 sum += (DPCPU_ID_PTR(_i, n))->var;                      \
  118         }                                                               \
  119         sum;                                                            \
  120 })
  121 
  122 #define DPCPU_ZERO(n) do {                                              \
  123         u_int _i;                                                       \
  124                                                                         \
  125         CPU_FOREACH(_i) {                                               \
  126                 bzero(DPCPU_ID_PTR(_i, n), sizeof(*DPCPU_PTR(n)));      \
  127         }                                                               \
  128 } while(0)
  129 
  130 /* 
  131  * XXXUPS remove as soon as we have per cpu variable
  132  * linker sets and can define rm_queue in _rm_lock.h
  133  */
  134 struct rm_queue {
  135         struct rm_queue* volatile rmq_next;
  136         struct rm_queue* volatile rmq_prev;
  137 };
  138 
  139 #define PCPU_NAME_LEN (sizeof("CPU ") + sizeof(__XSTRING(MAXCPU) + 1))
  140 
  141 /*
  142  * This structure maps out the global data that needs to be kept on a
  143  * per-cpu basis.  The members are accessed via the PCPU_GET/SET/PTR
  144  * macros defined in <machine/pcpu.h>.  Machine dependent fields are
  145  * defined in the PCPU_MD_FIELDS macro defined in <machine/pcpu.h>.
  146  */
  147 struct pcpu {
  148         struct thread   *pc_curthread;          /* Current thread */
  149         struct thread   *pc_idlethread;         /* Idle thread */
  150         struct thread   *pc_fpcurthread;        /* Fp state owner */
  151         struct thread   *pc_deadthread;         /* Zombie thread or NULL */
  152         struct pcb      *pc_curpcb;             /* Current pcb */
  153         uint64_t        pc_switchtime;          /* cpu_ticks() at last csw */
  154         int             pc_switchticks;         /* `ticks' at last csw */
  155         u_int           pc_cpuid;               /* This cpu number */
  156         cpumask_t       pc_cpumask;             /* This cpu mask */
  157         cpumask_t       pc_other_cpus;          /* Mask of all other cpus */
  158         SLIST_ENTRY(pcpu) pc_allcpu;
  159         struct lock_list_entry *pc_spinlocks;
  160 #ifdef KTR
  161         char            pc_name[PCPU_NAME_LEN]; /* String name for KTR */
  162 #endif
  163         struct vmmeter  pc_cnt;                 /* VM stats counters */
  164         long            pc_cp_time[CPUSTATES];  /* statclock ticks */
  165         struct device   *pc_device;
  166         void            *pc_netisr;             /* netisr SWI cookie */
  167 
  168         /*
  169          * Stuff for read mostly lock
  170          *
  171          * XXXUPS remove as soon as we have per cpu variable
  172          * linker sets.
  173          */
  174         struct rm_queue pc_rm_queue;
  175 
  176         uintptr_t       pc_dynamic;             /* Dynamic per-cpu data area */
  177 
  178         /*
  179          * Keep MD fields last, so that CPU-specific variations on a
  180          * single architecture don't result in offset variations of
  181          * the machine-independent fields of the pcpu.  Even though
  182          * the pcpu structure is private to the kernel, some ports
  183          * (e.g., lsof, part of gtop) define _KERNEL and include this
  184          * header.  While strictly speaking this is wrong, there's no
  185          * reason not to keep the offsets of the MI fields constant
  186          * if only to make kernel debugging easier.
  187          */
  188         PCPU_MD_FIELDS;
  189 } __aligned(128);
  190 
  191 #ifdef _KERNEL
  192 
  193 SLIST_HEAD(cpuhead, pcpu);
  194 
  195 extern struct cpuhead cpuhead;
  196 extern struct pcpu *cpuid_to_pcpu[MAXCPU];
  197 
  198 #define curcpu          PCPU_GET(cpuid)
  199 #define curproc         (curthread->td_proc)
  200 #ifndef curthread
  201 #define curthread       PCPU_GET(curthread)
  202 #endif
  203 #define curvidata       PCPU_GET(vidata)
  204 
  205 /*
  206  * Machine dependent callouts.  cpu_pcpu_init() is responsible for
  207  * initializing machine dependent fields of struct pcpu, and
  208  * db_show_mdpcpu() is responsible for handling machine dependent
  209  * fields for the DDB 'show pcpu' command.
  210  */
  211 void    cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size);
  212 void    db_show_mdpcpu(struct pcpu *pcpu);
  213 
  214 void    *dpcpu_alloc(int size);
  215 void    dpcpu_copy(void *s, int size);
  216 void    dpcpu_free(void *s, int size);
  217 void    dpcpu_init(void *dpcpu, int cpuid);
  218 void    pcpu_destroy(struct pcpu *pcpu);
  219 struct  pcpu *pcpu_find(u_int cpuid);
  220 void    pcpu_init(struct pcpu *pcpu, int cpuid, size_t size);
  221 
  222 #endif /* _KERNEL */
  223 
  224 #endif /* !_SYS_PCPU_H_ */

Cache object: 5112f0b7647d67c2d525ad60ba06682b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.