From 204b456c7c08bc40ffe1f21575461d92a544e92b Mon Sep 17 00:00:00 2001 From: hunt Date: Wed, 9 Mar 2005 21:30:05 +0000 Subject: Initial runtime checkin. --- runtime/docs/html/map_8c-source.html | 661 +++++++++++++++++++++++++++++++++++ 1 file changed, 661 insertions(+) create mode 100644 runtime/docs/html/map_8c-source.html (limited to 'runtime/docs/html/map_8c-source.html') diff --git a/runtime/docs/html/map_8c-source.html b/runtime/docs/html/map_8c-source.html new file mode 100644 index 00000000..301087fb --- /dev/null +++ b/runtime/docs/html/map_8c-source.html @@ -0,0 +1,661 @@ + + +SystemTap: SystemTap Runtime Library + + +
Intro | Functions | Defines | Enumerations | Enumeration Values
+ + +

map.c

Go to the documentation of this file.
00001 /* -*- linux-c -*- */
+00002 
+00003 static int map_sizes[] = {
+00004         sizeof(struct map_node_int64),
+00005         sizeof(struct map_node_stat),
+00006         sizeof(struct map_node_str),
+00007         0
+00008 };
+00009 
+00010 static inline unsigned string_hash(const char *key1, const char *key2)
+00011 {
+00012         int hash = 0, count = 0;
+00013         char *v1 = (char *)key1;
+00014         char *v2 = (char *)key2;
+00015         while (*v1 && count++ < 5) {
+00016                 hash += *v1++;
+00017         }
+00018         while (v2 && *v2 && count++ < 5) {
+00019                 hash += *v2++;
+00020         }
+00021         return hash_long((unsigned long)hash, HASH_TABLE_BITS);
+00022 }
+00023 
+00024 static inline unsigned mixed_hash(const char *key1, long key2)
+00025 {
+00026         int hash = 0, count = 0;
+00027         char *v = (char *)key1;
+00028         while (v && *v && count++ < 5)
+00029                 hash += *v++;
+00030         return hash_long((unsigned long)(hash ^ key2), HASH_TABLE_BITS);
+00031 }
+00032 
+00043 MAP _stp_map_new(unsigned max_entries, enum valtype type)
+00044 {
+00045         size_t size;
+00046         MAP m = (MAP) _stp_valloc(sizeof(struct map_root));
+00047         if (m == NULL)
+00048                 return NULL;
+00049 
+00050         INIT_LIST_HEAD(&m->head);
+00051 
+00052         m->maxnum = max_entries;
+00053         m->type = type;
+00054         if (type >= END) {
+00055                 dbug ("map_new: unknown type %d\n", type);
+00056                 return NULL;
+00057         }
+00058 
+00059         if (max_entries) {
+00060                 void *tmp;
+00061                 int i;
+00062                 struct list_head *e;
+00063 
+00064                 INIT_LIST_HEAD(&m->pool);
+00065                 size = map_sizes[type];
+00066                 tmp = _stp_valloc(max_entries * size);
+00067 
+00068                 for (i = max_entries - 1; i >= 0; i--) {
+00069                         e = i * size + tmp;
+00070                         dbug ("e=%lx\n", (long)e);
+00071                         list_add(e, &m->pool);
+00072                 }
+00073                 m->membuf = tmp;
+00074         }
+00075         return m;
+00076 }
+00077 
+00078 static void map_free_strings(MAP map, struct map_node *n)
+00079 {
+00080         struct map_node_str *m = (struct map_node_str *)n;
+00081         dbug ("n = %lx\n", (long)n);
+00082         if (map->type == STRING) {
+00083                 dbug ("val STRING %lx\n", (long)m->str);
+00084                 if (m->str)
+00085                         _stp_free(m->str);
+00086         }
+00087         if (m->n.key1type == STR) {
+00088                 dbug ("key1 STR %lx\n", (long)key1str(m));
+00089                 if (key1str(m))
+00090                         _stp_free(key1str(m));
+00091         }
+00092         if (m->n.key2type == STR) {
+00093                 dbug ("key2 STR %lx\n", (long)key2str(m));
+00094                 if (key2str(m))
+00095                         _stp_free(key2str(m));
+00096         }
+00097 }
+00098 
+00104 void _stp_map_key_del(MAP map)
+00105 {
+00106         struct map_node *m;
+00107 
+00108         dbug ("create=%d key=%lx\n", map->create, (long)map->key);
+00109         if (map == NULL)
+00110                 return;
+00111 
+00112         if (map->create) {
+00113                 map->create = 0;
+00114                 map->key = NULL;
+00115                 return;
+00116         }
+00117 
+00118         if (map->key == NULL)
+00119                 return;
+00120 
+00121         m = (struct map_node *)map->key;
+00122 
+00123         /* remove node from old hash list */
+00124         hlist_del_init(&m->hnode);
+00125 
+00126         /* remove from entry list */
+00127         list_del(&m->lnode);
+00128 
+00129         /* remove any allocated string storage */
+00130         map_free_strings(map, (struct map_node *)map->key);
+00131 
+00132         if (map->maxnum)
+00133                 list_add(&m->lnode, &map->pool);
+00134         else
+00135                 _stp_free(m);
+00136 
+00137         map->key = NULL;
+00138         map->num--;
+00139 }
+00140 
+00149 struct map_node *_stp_map_start(MAP map)
+00150 {
+00151         if (map == NULL)
+00152                 return NULL;
+00153 
+00154         dbug ("%lx\n", (long)map->head.next);
+00155 
+00156         if (list_empty(&map->head))
+00157                 return NULL;
+00158 
+00159         return (struct map_node *)map->head.next;
+00160 }
+00161 
+00172 struct map_node *_stp_map_iter(MAP map, struct map_node *m)
+00173 {
+00174         if (map == NULL)
+00175                 return NULL;
+00176 
+00177         dbug ("%lx next=%lx  prev=%lx  map->head.next=%lx\n", (long)m, (long)m->lnode.next, (long)m->lnode.prev, (long)map->head.next);
+00178 
+00179         if (m->lnode.next == &map->head)
+00180                 return NULL;
+00181 
+00182         return (struct map_node *)m->lnode.next;
+00183 }
+00184 
+00190 void _stp_map_del(MAP map)
+00191 {
+00192         if (map == NULL)
+00193                 return;
+00194 
+00195         if (!list_empty(&map->head)) {
+00196                 struct map_node *ptr = (struct map_node *)map->head.next;
+00197                 while (ptr && ptr != (struct map_node *)&map->head) {
+00198                         map_free_strings(map, ptr);
+00199                         ptr = (struct map_node *)ptr->lnode.next;
+00200                 }
+00201         }
+00202         _stp_vfree(map->membuf);
+00203         _stp_vfree(map);
+00204 }
+00205 
+00206 /**********************  KEY FUNCTIONS *********************/
+00207 
+00208 
+00218 void _stp_map_key_long_long(MAP map, long key1, long key2)
+00219 {
+00220         unsigned hv;
+00221         struct hlist_head *head;
+00222         struct hlist_node *e;
+00223 
+00224         if (map == NULL)
+00225                 return;
+00226 
+00227         hv = hash_long(key1 ^ key2, HASH_TABLE_BITS);
+00228         head = &map->hashes[hv];
+00229 
+00230         dbug ("hash for %ld,%ld is %d\n", key1, key2, hv);
+00231 
+00232         hlist_for_each(e, head) {
+00233                 struct map_node *n =
+00234                         (struct map_node *)((long)e - sizeof(struct hlist_node));
+00235                 dbug ("n =%lx  key=%ld,%ld\n", (long)n, n->key1.val, n->key2.val);
+00236                 if (key1 == n->key1.val && key2 == n->key2.val) {
+00237                         map->key = n;
+00238                         dbug ("saving key %lx\n", (long)map->key);
+00239                         map->create = 0;
+00240                         return;
+00241                 }
+00242         }
+00243 
+00244         map->c_key1.val = key1;
+00245         map->c_key2.val = key2;
+00246         map->c_key1type = LONG;
+00247         map->c_key2type = LONG;
+00248         map->c_keyhead = head;
+00249         map->create = 1;
+00250 }
+00251 
+00261 void _stp_map_key_str_str(MAP map, char *key1, char *key2)
+00262 {
+00263         unsigned hv;
+00264         struct hlist_head *head;
+00265         struct hlist_node *e;
+00266 
+00267         if (map == NULL)
+00268                 return;
+00269 
+00270         if (key1 == NULL) {
+00271                 map->key = NULL;
+00272                 return;
+00273         }
+00274 
+00275         hv = string_hash(key1, key2);
+00276         head = &map->hashes[hv];
+00277 
+00278         dbug ("hash for %s,%s is %d\n", key1, key2, hv);
+00279 
+00280         hlist_for_each(e, head) {
+00281                 struct map_node *n =
+00282                         (struct map_node *)((long)e - sizeof(struct hlist_node));
+00283                 dbug ("e =%lx  key=%s,%s\n", (long)e, n->key1.str,n->key2.str);
+00284                 if (strcmp(key1, n->key1.str) == 0
+00285                     && (key2 == NULL || strcmp(key2, n->key2.str) == 0)) {
+00286                         map->key = n;
+00287                         dbug ("saving key %lx\n", (long)map->key);
+00288                         map->create = 0;
+00289                         return;
+00290                 }
+00291         }
+00292 
+00293         map->c_key1.str = key1;
+00294         map->c_key2.str = key2;
+00295         map->c_key1type = STR;
+00296         map->c_key2type = STR;
+00297         map->c_keyhead = head;
+00298         map->create = 1;
+00299 }
+00300 
+00310 void _stp_map_key_str_long(MAP map, char *key1, long key2)
+00311 {
+00312         unsigned hv;
+00313         struct hlist_head *head;
+00314         struct hlist_node *e;
+00315 
+00316         if (map == NULL)
+00317                 return;
+00318 
+00319         if (key1 == NULL) {
+00320                 map->key = NULL;
+00321                 return;
+00322         }
+00323 
+00324         hv = mixed_hash(key1, key2);
+00325         head = &map->hashes[hv];
+00326 
+00327         dbug ("hash for %s,%ld is %d\n", key1, key2, hv);
+00328 
+00329         hlist_for_each(e, head) {
+00330                 struct map_node *n =
+00331                         (struct map_node *)((long)e - sizeof(struct hlist_node));
+00332                 dbug ("e =%lx  key=%s,%ld\n", (long)e, n->key1.str,(long)n->key2.val);
+00333                 if (strcmp(key1, n->key1.str) == 0 && key2 == n->key2.val) {
+00334                         map->key = n;
+00335                         dbug ("saving key %lx\n", (long)map->key);
+00336                         map->create = 0;
+00337                         return;
+00338                 }
+00339         }
+00340 
+00341         map->c_key1.str = key1;
+00342         map->c_key2.val = key2;
+00343         map->c_key1type = STR;
+00344         map->c_key2type = LONG;
+00345         map->c_keyhead = head;
+00346         map->create = 1;
+00347 }
+00348 
+00358 void _stp_map_key_long_str(MAP map, long key1, char *key2)
+00359 {
+00360         unsigned hv;
+00361         struct hlist_head *head;
+00362         struct hlist_node *e;
+00363 
+00364         if (map == NULL)
+00365                 return;
+00366 
+00367         hv = mixed_hash(key2, key1);
+00368         head = &map->hashes[hv];
+00369         dbug ("hash for %ld,%s is %d\n", key1, key2, hv);
+00370 
+00371         hlist_for_each(e, head) {
+00372                 struct map_node *n =
+00373                         (struct map_node *)((long)e - sizeof(struct hlist_node));
+00374                 dbug ("e =%lx  key=%ld,%s\n", (long)e, n->key1.val,n->key2.str);
+00375                 if (key1 == n->key1.val && strcmp(key2, n->key2.str) == 0) {
+00376                         map->key = n;
+00377                         dbug ("saving key %lx\n", (long)map->key);
+00378                         map->create = 0;
+00379                         return;
+00380                 }
+00381         }
+00382 
+00383         map->c_key1.val = key1;
+00384         map->c_key2.str = key2;
+00385         map->c_key1type = LONG;
+00386         map->c_key2type = STR;
+00387         map->c_keyhead = head;
+00388         map->create = 1;
+00389 }
+00390 
+00399 void _stp_map_key_str(MAP map, char *key)
+00400 {
+00401         if (map == NULL)
+00402                 return;
+00403         _stp_map_key_str_str(map, key, NULL);
+00404         map->c_key2type = NONE;
+00405 }
+00406 
+00415 void _stp_map_key_long(MAP map, long key)
+00416 {
+00417         if (map == NULL)
+00418                 return;
+00419         _stp_map_key_long_long(map, key, 0);
+00420         map->c_key2type = NONE;
+00421 }
+00422 
+00423 /**********************  SET/GET VALUES *********************/
+00424 
+00425 static void map_copy_keys(MAP map, struct map_node *m)
+00426 {
+00427         m->key1type = map->c_key1type;
+00428         m->key2type = map->c_key2type;
+00429         switch (map->c_key1type) {
+00430         case STR:
+00431                 m->key1.str = _stp_alloc(strlen(map->c_key1.str) + 1);
+00432                 strcpy(m->key1.str, map->c_key1.str);
+00433                 break;
+00434         case LONG:
+00435                 m->key1.val = map->c_key1.val;
+00436                 break;
+00437         case NONE:
+00438                 /* ERROR */
+00439                 break;
+00440         }
+00441         switch (map->c_key2type) {
+00442         case STR:
+00443                 m->key2.str = _stp_alloc(strlen(map->c_key2.str) + 1);
+00444                 strcpy(m->key2.str, map->c_key2.str);
+00445                 break;
+00446         case LONG:
+00447                 m->key2.val = map->c_key2.val;
+00448                 break;
+00449         case NONE:
+00450                 break;
+00451         }
+00452 
+00453         /* add node to new hash list */
+00454         hlist_add_head(&m->hnode, map->c_keyhead);
+00455         
+00456         map->key = m;
+00457         map->create = 0;
+00458         map->num++;
+00459 }
+00460 
+00471 void _stp_map_set_int64(MAP map, int64_t val)
+00472 {
+00473         struct map_node_int64 *m;
+00474 
+00475         if (map == NULL)
+00476                 return;
+00477 
+00478         if (map->create) {
+00479                 if (val == 0)
+00480                         return;
+00481 
+00482                 if (map->maxnum) {
+00483                         if (list_empty(&map->pool)) {
+00484                                 if (map->no_wrap) {
+00485                                         /* ERROR. FIXME */
+00486                                         return;
+00487                                 }
+00488                                 m = (struct map_node_int64 *)map->head.next;
+00489                                 hlist_del_init(&m->n.hnode);
+00490                                 map_free_strings(map, (struct map_node *)m);
+00491                                 dbug ("got %lx off head\n", (long)m);
+00492                         } else {
+00493                                 m = (struct map_node_int64 *)map->pool.next;
+00494                                 dbug ("got %lx off pool\n", (long)m);
+00495                         }
+00496                         list_move_tail(&m->n.lnode, &map->head);
+00497                 } else {
+00498                         m = (struct map_node_int64 *)
+00499                             _stp_calloc(sizeof(struct map_node_int64));
+00500                         /* add node to list */
+00501                         list_add_tail(&m->n.lnode, &map->head);
+00502                 }
+00503 
+00504                 /* copy the key(s) */
+00505                 map_copy_keys(map, &m->n);
+00506 
+00507                 /* set the value */
+00508                 m->val = val;
+00509         } else {
+00510                 if (map->key == NULL)
+00511                         return;
+00512 
+00513                 if (val) {
+00514                         m = (struct map_node_int64 *)map->key;
+00515                         m->val = val;
+00516                 } else {
+00517                         /* setting value to 0 is the same as deleting */
+00518                         _stp_map_key_del(map);
+00519                 }
+00520         }
+00521 }
+00522 
+00528 int64_t _stp_map_get_int64(MAP map)
+00529 {
+00530         struct map_node_int64 *m;
+00531         if (map == NULL || map->create || map->key == NULL)
+00532                 return 0;
+00533         dbug ("%lx\n", (long)map->key);
+00534         m = (struct map_node_int64 *)map->key;
+00535         return m->val;
+00536 }
+00537 
+00548 void _stp_map_set_str(MAP map, char *val)
+00549 {
+00550         struct map_node_str *m;
+00551 
+00552         if (map == NULL)
+00553                 return;
+00554 
+00555         if (map->create) {
+00556                 if (val == NULL)
+00557                         return;
+00558 
+00559                 if (map->maxnum) {
+00560                         if (list_empty(&map->pool)) {
+00561                                 if (map->no_wrap) {
+00562                                         /* ERROR. FIXME */
+00563                                         return;
+00564                                 }
+00565                                 m = (struct map_node_str *)map->head.next;
+00566                                 hlist_del_init(&m->n.hnode);
+00567                                 map_free_strings(map, (struct map_node *)m);
+00568                                 dbug ("got %lx off head\n", (long)m);
+00569                         } else {
+00570                                 m = (struct map_node_str *)map->pool.next;
+00571                                 dbug ("got %lx off pool\n", (long)m);
+00572                         }
+00573                         list_move_tail(&m->n.lnode, &map->head);
+00574                 } else {
+00575                         m = (struct map_node_str *)
+00576                             _stp_calloc(sizeof(struct map_node_str));
+00577                         /* add node to list */
+00578                         list_add_tail(&m->n.lnode, &map->head);
+00579                 }
+00580 
+00581                 /* copy the key(s) */
+00582                 map_copy_keys(map, &m->n);
+00583 
+00584                 /* set the value */
+00585                 m->str = _stp_alloc(strlen(val) + 1);
+00586                 strcpy(m->str, val);
+00587         } else {
+00588                 if (map->key == NULL)
+00589                         return;
+00590 
+00591                 if (val) {
+00592                         m = (struct map_node_str *)map->key;
+00593                         if (m->str)
+00594                                 _stp_free(m->str);
+00595                         m->str = _stp_alloc(strlen(val) + 1);
+00596                         strcpy(m->str, val);
+00597                 } else {
+00598                         /* setting value to 0 is the same as deleting */
+00599                         _stp_map_key_del(map);
+00600                 }
+00601         }
+00602 }
+00603 
+00609 char *_stp_map_get_str(MAP map)
+00610 {
+00611         struct map_node_str *m;
+00612         if (map == NULL || map->create || map->key == NULL)
+00613                 return NULL;
+00614         dbug ("%lx\n", (long)map->key);
+00615         m = (struct map_node_str *)map->key;
+00616         return m->str;
+00617 }
+00618 
+00633 void _stp_map_set_stat(MAP map, stat * stats)
+00634 {
+00635         struct map_node_stat *m;
+00636 
+00637         if (map == NULL)
+00638                 return;
+00639         dbug ("set_stat %lx\n", (long)map->key);
+00640 
+00641         if (map->create) {
+00642                 if (stats == NULL)
+00643                         return;
+00644 
+00645                 if (map->maxnum) {
+00646                         if (list_empty(&map->pool)) {
+00647                                 if (map->no_wrap) {
+00648                                         /* ERROR. FIXME */
+00649                                         return;
+00650                                 }
+00651                                 m = (struct map_node_stat *)map->head.next;
+00652                                 hlist_del_init(&m->n.hnode);
+00653                                 map_free_strings(map, (struct map_node *)m);
+00654                                 dbug ("got %lx off head\n", (long)m);
+00655                         } else {
+00656                                 m = (struct map_node_stat *)map->pool.next;
+00657                                 dbug ("got %lx off pool\n", (long)m);
+00658                         }
+00659                         list_move_tail(&m->n.lnode, &map->head);
+00660                 } else {
+00661                         m = (struct map_node_stat *)
+00662                             _stp_calloc(sizeof(struct map_node_stat));
+00663                         /* add node to list */
+00664                         list_add_tail(&m->n.lnode, &map->head);
+00665                 }
+00666 
+00667                 /* copy the key(s) */
+00668                 map_copy_keys(map, &m->n);
+00669 
+00670                 /* set the value */
+00671                 memcpy(&m->stats, stats, sizeof(stat));
+00672         } else {
+00673                 if (map->key == NULL)
+00674                         return;
+00675 
+00676                 if (stats) {
+00677                         m = (struct map_node_stat *)map->key;
+00678                         memcpy(&m->stats, stats, sizeof(stat));
+00679                 } else {
+00680                         /* setting value to NULL is the same as deleting */
+00681                         _stp_map_key_del(map);
+00682                 }
+00683         }
+00684 }
+00685 
+00692 stat *_stp_map_get_stat(MAP map)
+00693 {
+00694         struct map_node_stat *m;
+00695         if (map == NULL || map->create || map->key == NULL)
+00696                 return NULL;
+00697         dbug ("%lx\n", (long)map->key);
+00698         m = (struct map_node_stat *)map->key;
+00699         return &m->stats;
+00700 }
+00701 
+00713 void _stp_map_stat_add(MAP map, int64_t val)
+00714 {
+00715         struct map_node_stat *m;
+00716         if (map == NULL)
+00717                 return;
+00718 
+00719         if (map->create) {
+00720                 stat st = { 1, val, val, val };
+00721                 /* histogram */
+00722                 _stp_map_set_stat(map, &st);
+00723                 return;
+00724         }
+00725 
+00726         if (map->key == NULL)
+00727                 return;
+00728 
+00729         dbug ("add_stat %lx\n", (long)map->key);
+00730         m = (struct map_node_stat *)map->key;
+00731         m->stats.count++;
+00732         m->stats.sum += val;
+00733         if (val > m->stats.max)
+00734                 m->stats.max = val;
+00735         if (val < m->stats.min)
+00736                 m->stats.min = val;
+00737         /* histogram */
+00738 }
+00739 
+00740 /**********************  List Functions *********************/
+00741 
+00753 MAP _stp_list_new(unsigned max_entries, enum valtype type)
+00754 {
+00755   MAP map = _stp_map_new (max_entries, type);
+00756   map->no_wrap = 1;
+00757   return map;
+00758 }
+00759 
+00765 inline void _stp_list_clear(MAP map)
+00766 {
+00767         if (map == NULL)
+00768                 return;
+00769 
+00770         if (!list_empty(&map->head)) {
+00771                 struct map_node *ptr = (struct map_node *)map->head.next;
+00772 
+00773                 while (ptr && ptr != (struct map_node *)&map->head) {
+00774                         struct map_node *next = (struct map_node *)ptr->lnode.next;
+00775 
+00776                         /* remove node from old hash list */
+00777                         hlist_del_init(&ptr->hnode);
+00778 
+00779                         /* remove from entry list */
+00780                         list_del(&ptr->lnode);
+00781                         
+00782                         /* remove any allocated string storage */
+00783                         map_free_strings(map, ptr);
+00784                         
+00785                         if (map->maxnum)
+00786                                 list_add(&ptr->lnode, &map->pool);
+00787                         else
+00788                                 _stp_free(ptr);
+00789 
+00790                         map->num--;
+00791                         ptr = next;
+00792                 }
+00793         }
+00794 
+00795         if (map->num != 0) {
+00796                 dlog ("ERROR: list is supposed to be empty (has %d)\n", map->num);
+00797         }
+00798 }
+00799 
+00805 inline void _stp_list_add_str(MAP map, char *str)
+00806 {
+00807         _stp_map_key_long(map, map->num);
+00808         _stp_map_set_str(map, str);
+00809 }
+00810 
+00816 inline void _stp_list_add_int64(MAP map, int64_t val)
+00817 {
+00818         _stp_map_key_long(map, map->num);
+00819         _stp_map_set_int64(map, val);
+00820 }
+00821 
+00827 inline int _stp_list_size(MAP map)
+00828 {
+00829         return map->num;
+00830 }
+

Generated on Wed Mar 9 13:21:28 2005 for SystemTap by  + +doxygen 1.3.9.1
+ + -- cgit