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