xref: /illumos-gate/usr/src/uts/common/os/cpu_uarray.c (revision 04e56356520b98d5a93c496b10f02530bb6647e0)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright (c) 2018, Joyent, Inc.
14  */
15 
16 #include <sys/cpu_uarray.h>
17 #include <sys/sysmacros.h>
18 #include <sys/cpuvar.h>
19 #include <sys/debug.h>
20 #include <sys/kmem.h>
21 
22 static size_t
23 cpu_uarray_size(size_t nr_items)
24 {
25 	size_t size = P2ROUNDUP(nr_items * sizeof (uint64_t), CUA_ALIGN);
26 	size *= NCPU;
27 	return (sizeof (cpu_uarray_t) + size);
28 }
29 
30 cpu_uarray_t *
31 cpu_uarray_zalloc(size_t nr_items, int kmflags)
32 {
33 	cpu_uarray_t *cua;
34 
35 	cua = kmem_zalloc(cpu_uarray_size(nr_items), kmflags);
36 
37 	if (cua != NULL) {
38 		VERIFY(IS_P2ALIGNED(cua->cu_vals, CUA_ALIGN));
39 		cua->cu_nr_items = nr_items;
40 	}
41 
42 	return (cua);
43 }
44 
45 void
46 cpu_uarray_free(cpu_uarray_t *cua)
47 {
48 	kmem_free(cua, cpu_uarray_size(cua->cu_nr_items));
49 }
50 
51 uint64_t
52 cpu_uarray_sum(cpu_uarray_t *cua, size_t index)
53 {
54 	uint64_t sum = 0;
55 
56 	VERIFY3U(index, <, cua->cu_nr_items);
57 
58 	for (size_t c = 0; c < ncpus; c++) {
59 		uint64_t addend = CPU_UARRAY_VAL(cua, c, index);
60 		sum = UINT64_OVERFLOW_ADD(sum, addend);
61 	}
62 
63 	return (sum);
64 }
65 
66 uint64_t
67 cpu_uarray_sum_all(cpu_uarray_t *cua)
68 {
69 	uint64_t sum = 0;
70 
71 	for (size_t c = 0; c < ncpus; c++) {
72 		for (size_t i = 0; i < cua->cu_nr_items; i++) {
73 			uint64_t addend = CPU_UARRAY_VAL(cua, c, i);
74 			sum = UINT64_OVERFLOW_ADD(sum, addend);
75 		}
76 	}
77 
78 	return (sum);
79 }
80