1 /*
2 * Copyright © 2009-2017 Inria. All rights reserved.
3 * Copyright © 2009 Université Bordeaux
4 * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
5 * See COPYING in top-level directory.
6 */
7
8 #include "hwloc.h"
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <stdint.h>
13 #include <string.h>
14 #include <assert.h>
15
16 /* check that object userdata is properly initialized */
17
18 #define RANDOMSTRINGLENGTH 128
19 #define RANDOMSTRINGSHORTTESTS 5
20 #define RANDOMSTRINGLONGTESTS 9
21 static char *randomstring;
22
check(hwloc_topology_t topology)23 static void check(hwloc_topology_t topology)
24 {
25 int depth, i;
26 unsigned j;
27
28 depth = hwloc_topology_get_depth(topology);
29 for(i=0; i<depth; i++) {
30 for(j=0; j<hwloc_get_nbobjs_by_depth(topology, i); j++) {
31 assert(hwloc_get_obj_by_depth(topology, i, j)->userdata == NULL);
32 }
33 }
34 }
35
export_cb(void * reserved,hwloc_topology_t topo,hwloc_obj_t obj)36 static void export_cb(void *reserved, hwloc_topology_t topo, hwloc_obj_t obj)
37 {
38 char tmp[32];
39 int err;
40 unsigned i;
41
42 sprintf(tmp, "%016llx", (unsigned long long) (uintptr_t) obj->userdata);
43 err = hwloc_export_obj_userdata(reserved, topo, obj, "MyName", tmp, 16);
44 assert(err >= 0);
45
46 err = hwloc_export_obj_userdata(reserved, topo, obj, NULL, "", 0);
47 assert(err >= 0);
48
49 err = hwloc_export_obj_userdata_base64(reserved, topo, obj, NULL, "", 0);
50 assert(err >= 0);
51
52 for(i=0; i<RANDOMSTRINGSHORTTESTS; i++) {
53 sprintf(tmp, "EncodedShort%u", i);
54 err = hwloc_export_obj_userdata_base64(reserved, topo, obj, tmp, randomstring+i, i);
55 assert(err >= 0);
56 }
57 for(i=0; i<RANDOMSTRINGLONGTESTS; i++) {
58 sprintf(tmp, "EncodedLong%u", i);
59 err = hwloc_export_obj_userdata_base64(reserved, topo, obj, tmp, randomstring+(i+1)/2, RANDOMSTRINGLENGTH-i);
60 assert(err >= 0);
61 }
62 }
63
import_cb(hwloc_topology_t topo __hwloc_attribute_unused,hwloc_obj_t obj,const char * name,const void * buffer,size_t length)64 static void import_cb(hwloc_topology_t topo __hwloc_attribute_unused, hwloc_obj_t obj, const char *name, const void *buffer, size_t length)
65 {
66 int err;
67 char tmp[17];
68 uint64_t val;
69
70 if (!name) {
71 assert(!*(char*)buffer);
72
73 } else if (!strcmp("MyName", name)) {
74 assert(length == 16);
75 memcpy(tmp, buffer, 16);
76 tmp[16] = '\0';
77
78 val = strtoull(buffer, NULL, 0);
79
80 switch (val) {
81 case 0x1:
82 assert(obj->type == HWLOC_OBJ_MACHINE);
83 obj->userdata = (void *)(uintptr_t) 0x4;
84 break;
85 case 0x2:
86 assert(obj->type == HWLOC_OBJ_L2CACHE);
87 obj->userdata = (void *)(uintptr_t) 0x5;
88 break;
89 case 0x3:
90 assert(obj->type == HWLOC_OBJ_PU);
91 obj->userdata = (void *)(uintptr_t) 0x6;
92 break;
93 default:
94 assert(0);
95 }
96
97 } else if (!strncmp("EncodedShort", name, 12)) {
98 unsigned i = atoi(name+12);
99 assert(i <= RANDOMSTRINGSHORTTESTS-1);
100 assert(i == (unsigned) length);
101 err = memcmp(buffer, randomstring+i, length);
102 assert(!err);
103
104 } else if (!strncmp("EncodedLong", name, 11)) {
105 unsigned i = atoi(name+11);
106 assert(i <= RANDOMSTRINGLONGTESTS-1);
107 assert(RANDOMSTRINGLENGTH-i == (unsigned) length);
108 err = memcmp(buffer, randomstring+(i+1)/2, length);
109 assert(!err);
110
111 } else
112 assert(0);
113 }
114
main(void)115 int main(void)
116 {
117 hwloc_topology_t topology, reimport;
118 hwloc_obj_t obj1, obj2, obj3;
119 char *xmlbuf;
120 int xmlbuflen;
121
122 randomstring = malloc(RANDOMSTRINGLENGTH);
123 /* keep it uninitialized, we want binary data */
124
125 /* check the real topology */
126 hwloc_topology_init(&topology);
127 hwloc_topology_load(topology);
128 check(topology);
129 assert(hwloc_topology_get_userdata(topology) == NULL);
130 hwloc_topology_destroy(topology);
131
132 /* check a synthetic topology */
133 hwloc_topology_init(&topology);
134 hwloc_topology_set_userdata(topology, (void *)(uintptr_t)0x987654);
135 hwloc_topology_set_synthetic(topology, "6 5 4 3 2");
136 hwloc_topology_load(topology);
137 check(topology);
138
139 /* now place some userdata and see if importing/exporting works well */
140 obj1 = hwloc_get_root_obj(topology);
141 assert(obj1);
142 obj1->userdata = (void *)(uintptr_t) 0x1;
143 obj2 = hwloc_get_obj_by_depth(topology, 3, 13);
144 assert(obj2);
145 obj2->userdata = (void *)(uintptr_t) 0x2;
146 obj3 = hwloc_get_obj_by_depth(topology, 5, 2*3*4*5*6-1);
147 assert(obj3);
148 obj3->userdata = (void *)(uintptr_t) 0x3;
149
150 /* export/import without callback, we get nothing */
151 hwloc_topology_export_xmlbuffer(topology, &xmlbuf, &xmlbuflen, 0);
152
153 hwloc_topology_init(&reimport);
154 hwloc_topology_set_xmlbuffer(reimport, xmlbuf, xmlbuflen);
155 hwloc_topology_load(reimport);
156 check(reimport); /* there should be no userdata */
157 hwloc_topology_destroy(reimport);
158
159 /* export/import with callback, we should get three userdata */
160 hwloc_topology_set_userdata_export_callback(topology, export_cb);
161 hwloc_topology_export_xmlbuffer(topology, &xmlbuf, &xmlbuflen, 0);
162
163 hwloc_topology_init(&reimport);
164 hwloc_topology_set_userdata_import_callback(reimport, import_cb);
165 hwloc_topology_set_xmlbuffer(reimport, xmlbuf, xmlbuflen);
166 hwloc_topology_load(reimport);
167 obj1 = hwloc_get_root_obj(reimport);
168 assert(obj1);
169 assert(obj1->userdata == (void *)(uintptr_t) 0x4);
170 obj2 = hwloc_get_obj_by_depth(reimport, 3, 13);
171 assert(obj2);
172 assert(obj2->userdata == (void *)(uintptr_t) 0x5);
173 obj3 = hwloc_get_obj_by_depth(reimport, 5, 2*3*4*5*6-1);
174 assert(obj3);
175 assert(obj3->userdata == (void *)(uintptr_t) 0x6);
176 hwloc_topology_destroy(reimport);
177
178 assert(hwloc_topology_get_userdata(topology) == (void *)(uintptr_t)0x987654);
179 hwloc_topology_destroy(topology);
180
181 free(randomstring);
182 return 0;
183 }
184