1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *  * Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in
12 *    the documentation and/or other materials provided with the
13 *    distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28#define _GNU_SOURCE 1
29#include <sched.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34
35int failures = 0;
36
37#define TEST_INT_EQ(cond,exp) \
38    do {\
39        int  _cond = (cond); \
40        int  _exp  = (exp); \
41        if ((_cond) != (_exp)) {\
42            fprintf(stderr, "Assertion failure:%s:%d: '%s' returned %d (%d expected)\n", \
43                    __FUNCTION__, __LINE__, #cond, _cond, _exp);\
44        }\
45    }while(0)
46
47#define  T(cond)  \
48    do {\
49        if (!(cond)) {\
50            fprintf(stderr,"Assertion failure:%s:%d: %s is not TRUE\n",\
51                           __FUNCTION__, __LINE__, #cond);\
52            failures++;\
53        }\
54    } while(0)
55
56#define  F(cond) \
57    do {\
58        if (!!(cond)) {\
59            fprintf(stderr,"Assertion failure:%s:%d: %s is not FALSE\n",\
60                           __FUNCTION__, __LINE__, #cond);\
61            failures++;\
62        }\
63    } while (0)
64
65
66static void
67test_1(cpu_set_t* set)
68{
69    cpu_set_t  other[1];
70    int nn, nnMax = CPU_SETSIZE;
71
72    memset(other, 0, sizeof *other);
73    TEST_INT_EQ(CPU_COUNT(other),0);
74
75    /* First, cheeck against zero */
76    CPU_ZERO(set);
77    TEST_INT_EQ(CPU_COUNT(set),0);
78    T(CPU_EQUAL(set, other));
79    T(CPU_EQUAL(other, set));
80
81    for (nn = 0; nn < nnMax; nn++)
82        F(CPU_ISSET(nn, set));
83
84    /* Check individual bits */
85    for (nn = 0; nn < nnMax; nn++) {
86        int mm;
87        CPU_SET(nn, set);
88        TEST_INT_EQ(CPU_COUNT(set),1);
89        for (mm = 0; mm < nnMax; mm++) {
90            T(CPU_ISSET(mm, set) == (mm == nn));
91        }
92        CPU_CLR(nn, set);
93        T(CPU_EQUAL(set, other));
94    }
95
96    /* Check cumulative bits, incrementing */
97    for (nn = 0; nn < nnMax; nn++) {
98        int mm;
99        CPU_SET(nn, set);
100        TEST_INT_EQ(CPU_COUNT(set), nn+1);
101        for (mm = 0; mm < nnMax; mm++) {
102            T(CPU_ISSET(mm, set) == (mm <= nn));
103        }
104    }
105
106    /* Check individual clear bits */
107    for (nn = 0; nn < nnMax; nn++) {
108        int mm;
109        CPU_CLR(nn, set);
110        TEST_INT_EQ(CPU_COUNT(set), nnMax-1);
111        for (mm = 0; mm < nnMax; mm++) {
112            T(CPU_ISSET(mm, set) == (mm != nn));
113        }
114        CPU_SET(nn, set);
115    }
116
117    /* Check cumulative bits, decrementing */
118    for (nn = nnMax-1; nn >= 0; nn--) {
119        int mm;
120        CPU_CLR(nn, set);
121        TEST_INT_EQ(CPU_COUNT(set), nn);
122        for (mm = 0; mm < nnMax; mm++) {
123            T(CPU_ISSET(mm, set) == (mm < nn));
124        }
125    }
126    T(CPU_EQUAL(set, other));
127}
128
129static void
130test_1_s(size_t setsize, cpu_set_t* set)
131{
132    int nn, nnMax;
133    cpu_set_t* other;
134
135    /* First, cheeck against zero */
136    other = calloc(1,setsize);
137    TEST_INT_EQ(CPU_COUNT(other),0);
138    CPU_ZERO_S(setsize, set);
139    T(CPU_EQUAL_S(setsize, set, other));
140    T(CPU_EQUAL_S(setsize, other, set));
141
142    nnMax = setsize*8;
143    for (nn = 0; nn < nnMax; nn++)
144        F(CPU_ISSET_S(nn, setsize, set));
145
146    /* Check individual bits */
147    for (nn = 0; nn < nnMax; nn++) {
148        int mm;
149        CPU_SET_S(nn, setsize, set);
150        TEST_INT_EQ(CPU_COUNT_S(setsize, set), 1);
151        for (mm = 0; mm < nnMax; mm++) {
152            T(CPU_ISSET_S(mm, setsize, set) == (mm == nn));
153        }
154        CPU_CLR_S(nn, setsize, set);
155        T(CPU_EQUAL_S(setsize, set, other));
156    }
157
158    /* Check cumulative bits, incrementing */
159    for (nn = 0; nn < nnMax; nn++) {
160        int mm;
161        CPU_SET_S(nn, setsize, set);
162        TEST_INT_EQ(CPU_COUNT_S(setsize, set), nn+1);
163        for (mm = 0; mm < nnMax; mm++) {
164            T(CPU_ISSET_S(mm, setsize, set) == (mm <= nn));
165        }
166    }
167
168    /* Check individual clear bits */
169    for (nn = 0; nn < nnMax; nn++) {
170        int mm;
171        CPU_CLR_S(nn, setsize, set);
172        TEST_INT_EQ(CPU_COUNT_S(setsize, set), nnMax-1);
173        for (mm = 0; mm < nnMax; mm++) {
174            T(CPU_ISSET_S(mm, setsize, set) == (mm != nn));
175        }
176        CPU_SET_S(nn, setsize, set);
177    }
178
179    /* Check cumulative bits, decrementing */
180    for (nn = nnMax-1; nn >= 0; nn--) {
181        int mm;
182        CPU_CLR_S(nn, setsize, set);
183        TEST_INT_EQ(CPU_COUNT_S(setsize, set), nn);
184        for (mm = 0; mm < nnMax; mm++) {
185            T(CPU_ISSET_S(mm, setsize, set) == (mm < nn));
186        }
187    }
188    T(CPU_EQUAL_S(setsize, set, other));
189
190    free(other);
191}
192
193
194int main(void)
195{
196    cpu_set_t  set0;
197    int cpu;
198    test_1(&set0);
199    test_1_s(sizeof(set0), &set0);
200
201    size_t count;
202    for (count = 32; count <= 1024; count *= 2) {
203        cpu_set_t* set = CPU_ALLOC(count);
204        test_1_s(count/8, set);
205        CPU_FREE(set);
206    }
207
208    T((cpu = sched_getcpu()) >= 0);
209
210    int ret;
211    TEST_INT_EQ((ret = sched_getaffinity(getpid(), sizeof(cpu_set_t), &set0)), 0);
212
213    CPU_ZERO(&set0);
214    CPU_SET(cpu, &set0);
215
216    TEST_INT_EQ((ret = sched_setaffinity(getpid(), sizeof(cpu_set_t), &set0)), 0);
217
218    if (failures == 0) {
219        printf("OK\n");
220        return 0;
221    } else {
222        printf("KO: %d failures\n", failures);
223        return 1;
224    }
225}
226