84 #define SIZEOF_CSKLNODE_T(L) (sizeof(csklnode_t) + sizeof(void*) * L) 189 GF_cskl_nodes = GF_cskl_nodes->
nexts[0];
223 candidate->
height - 1 == layer &&
255 for (
int layer = max_height-1; layer >= 0; layer--) {
262 current = pred->
nexts[layer];
270 succs[layer] = current;
317 for (
int layer = 0; layer <= highestLocked; layer++) {
319 if (pred != prevPred) {
331 for (
int i = 0; i < max_height; i++) {
332 str_len = strlen(str);
333 strncat(str,
" |", max_cskl_str_len - str_len - 1);
335 str_len = strlen(str);
336 strncat(str,
"\n", max_cskl_str_len - str_len - 1);
373 int layer = max_height - 1;
374 while (layer > hlayer) {
376 lpreds[layer]->
nexts[layer] = succs[layer]->
nexts[layer];
381 while (hlayer >= 0) {
383 lpreds[hlayer]->
nexts[hlayer] = succs[hlayer]->
nexts[hlayer]->
nexts[hlayer];
401 return first !=
last;
412 printf(
"DXN_DBG: cskl_init mcs_init(&GFCN_lock)\n");
428 for (
int i = 0; i < node->
height; i++) {
435 GF_cskl_nodes =
node;
458 left->
val = lsentinel;
459 right->
val = rsentinel;
461 for(
int i = 0; i < max_height; i++)
462 left->
nexts[i] = right;
471 return found? found->
val:
NULL;
478 return found? found->
val:
NULL;
503 node = succs[found_layer];
528 int my_height = new_node->
height;
530 int highestLocked = -1;
533 for (layer = 0; layer < my_height; layer++) {
536 if (pred != prevPred) {
538 highestLocked = layer;
546 if (layer == my_height) {
549 for (
int layer = 0; layer < my_height; layer++) {
550 node->
nexts[layer] = succs[layer];
572 bool node_is_marked =
false;
576 csklnode_t *preds[max_height], *succs[max_height];
589 if (node_is_marked ||
597 if (!node_is_marked) {
606 node_is_marked =
true;
622 int highestLocked = -1;
626 for (
int layer = 0; valid && (layer < height); layer++) {
629 if (pred != prevPred) {
631 highestLocked = layer;
634 valid = !pred->
marked && pred->
nexts[layer] == succ;
649 for (
int layer = height - 1; layer >= 0; layer--) {
651 preds[layer]->
nexts[layer] = node->
nexts[layer];
679 int max_cskl_str_len)
684 for (
int i = 1; i < height; i++) {
685 str_len = strlen(str);
686 strncat(str,
"-+", max_cskl_str_len - str_len - 1);
688 for (
int i = height; i < max_height; i++) {
689 str_len = strlen(str);
690 strncat(str,
" |", max_cskl_str_len - str_len - 1);
692 str_len = strlen(str);
693 strncat(str,
" ", max_cskl_str_len - str_len - 1);
699 int str_len = strlen(str);
700 strncat(str, nodestr, max_cskl_str_len - str_len - 1);
701 str_len = strlen(str);
702 strncat(str,
"\n", max_cskl_str_len - str_len - 1);
715 int temp_len = max_cskl_str_len/2;
716 char temp_buff[temp_len];
719 for (; ; node = node->
nexts[0]) {
721 strncat(csklstr, temp_buff, max_cskl_str_len - str_len - 1);
722 str_len = strlen(csklstr);
724 str_len = strlen(csklstr);
725 node_tostr(node->
val, node->
height, max_height, temp_buff, temp_len - 1);
726 strncat(csklstr, temp_buff, max_cskl_str_len - str_len - 1);
727 str_len = strlen(csklstr);
728 if (node == right)
break;
730 strncat(csklstr,
"\n", max_cskl_str_len - str_len - 1);
741 int height = node->
height;
743 printf(
"0x%016lx: ", (
unsigned long) node);
746 for (i = 0; i < height; i++) {
747 printf(
"0x%016lx ", (
unsigned long) node->nexts[i]);
751 for (i = height; i < max_height; i++) {
752 printf(
"------------------ ");
757 #define NODE_STR_LEN 4096 770 for (; ; node = node->
nexts[0]) {
773 printf(
"%s", nodestr);
774 if (node == right)
break;
786 int height = node->
height;
788 printf(
"0x%016lx: ", (
unsigned long) node);
792 for (i = 1; i < height; i++) {
797 for (i = height; i < max_height; i++) {
816 printf(
"%s", nodestr);
835 int succIsGreater[node->
height];
836 for (i = 0; i < node->
height; i++) {
839 correct &= succIsGreater[i];
842 for (i = 0; i < node->
height; i++) {
843 printf(
"%c", succIsGreater[i] ?
'+' :
'X');
845 for (i = node->
height; i < max_height; i++) {
853 printf(
"%s", nodestr);
870 printf(
"***** BEGIN CHECK: skip list %p\n", cs);
874 printf(
"***** END CHECK: skip list %p is %s\n", cs, correct ?
"correct" :
"incorrect");
static void cskl_links_tostr(int max_height, char str[], int max_cskl_str_len)
void *(* mem_alloc)(size_t size)
void mcs_lock(mcs_lock_t *l, mcs_node_t *me)
static void csklnode_free_to_lfl(csklnode_t *node)
static mcs_lock_t GFCN_lock
void cskl_tostr(cskiplist_t *cskl, cskl_node_tostr node_tostr, char csklstr[], int max_cskl_str_len)
void(* cskl_node_tostr)(void *node_val, int node_height, int max_height, char str[], int max_cskl_str_len)
static void cskl_links_print(csklnode_t *node, int max_height)
cskiplist_t * cskl_new(void *lsentinel, void *rsentinel, int max_height, val_cmp compare, val_cmp inrange, mem_alloc m_alloc)
struct csklnode_s * nexts[]
static bool cskiplist_node_is_removable(csklnode_t *candidate, int layer)
void cskl_free(void *anode)
bool cskl_delete(cskiplist_t *cskl, void *value)
volatile bool fully_linked
bool cskl_inrange_del_bulk_unsynch(cskiplist_t *cskl, void *lo, void *hi, mem_free m_free)
void cskl_print(cskiplist_t *cskl, cskl_node_tostr node_tostr)
int random_level(int max_height)
void * cskl_inrange_find(cskiplist_t *cskl, void *value)
static int cskiplist_find_helper(val_cmp compare, int max_height, csklnode_t *pred, void *val, csklnode_t *preds[], csklnode_t *succs[], cskiplist_find_type ft)
bool cskl_cmp_del_bulk_unsynch(cskiplist_t *cskl, void *lo, void *hi, mem_free m_free)
void pfq_rwlock_init(pfq_rwlock_t *l)
struct binarytree_s * right
int compare(SrcFile::ln x, SrcFile::ln y)
bool mcs_trylock(mcs_lock_t *l, mcs_node_t *me)
static void cskl_links_dump(csklnode_t *node, int max_height)
void mcs_unlock(mcs_lock_t *l, mcs_node_t *me)
static csklnode_t * GF_cskl_nodes
void pfq_rwlock_write_lock(pfq_rwlock_t *l, pfq_rwlock_node_t *me)
static __thread csklnode_t * _lf_cskl_nodes
static csklnode_t * csklnode_malloc(void *val, int maxheight, mem_alloc m_alloc)
void cskl_check_dump(cskiplist_t *cs, cskl_node_tostr node_tostr)
#define SIZEOF_CSKLNODE_T(L)
void pfq_rwlock_read_lock(pfq_rwlock_t *l)
static void unlock_preds(csklnode_t *preds[], mcs_node_t mcs_nodes[], int highestLocked)
int cskl_check_node_dump(val_cmp compare, int max_height, cskl_node_tostr node_tostr, csklnode_t *node)
static void csklnode_populate_lfl(int maxheight, mem_alloc m_alloc)
void * cskl_cmp_find(cskiplist_t *cskl, void *value)
void pfq_rwlock_write_unlock(pfq_rwlock_t *l, pfq_rwlock_node_t *me)
int(* val_cmp)(void *lhs, void *rhs)
void pfq_rwlock_read_unlock(pfq_rwlock_t *l)
static void csklnode_add_nodes_to_lfl(int maxheight, mem_alloc m_alloc)
csklnode_t * cskl_insert(cskiplist_t *cskl, void *value, mem_alloc m_alloc)
void cskl_append_node_str(char nodestr[], char str[], int max_cskl_str_len)
struct binarytree_s * left
static csklnode_t * cskiplist_find(val_cmp compare, cskiplist_t *cskl, void *value)
csklnode_t * right_sentinel
static csklnode_t * csklnode_alloc_from_lfl(void *val)
void cskl_levels_tostr(int height, int max_height, char str[], int max_cskl_str_len)
static csklnode_t * csklnode_alloc_node(int height, mem_alloc m_alloc)
void cskl_dump(cskiplist_t *cskl, cskl_node_tostr node_tostr)
static bool cskl_del_bulk_unsynch(val_cmp cmpfn, cskiplist_t *cskl, void *lo, void *hi, mem_free m_free)
<!-- ********************************************************************--> n<!-- HPCToolkit Experiment DTD --> n<!-- Version 2.1 --> n<!-- ********************************************************************--> n<!ELEMENT HPCToolkitExperiment(Header,(SecCallPathProfile|SecFlatProfile) *)> n<!ATTLIST HPCToolkitExperiment\n version CDATA #REQUIRED > n n<!-- ******************************************************************--> n n<!-- Info/NV:flexible name-value pairs:(n) ame;(t) ype;(v) alue --> n<!ELEMENT Info(NV *)> n<!ATTLIST Info\n n CDATA #IMPLIED > n<!ELEMENT NV EMPTY > n<!ATTLIST NV\n n CDATA #REQUIRED\n t CDATA #IMPLIED\n v CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Header --> n<!-- ******************************************************************--> n<!ELEMENT Header(Info *)> n<!ATTLIST Header\n n CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Section Header --> n<!-- ******************************************************************--> n<!ELEMENT SecHeader(MetricTable?, MetricDBTable?, TraceDBTable?, LoadModuleTable?, FileTable?, ProcedureTable?, Info *)> n n<!-- MetricTable:--> n<!ELEMENT MetricTable(Metric) * > n n<!-- Metric:(i) d;(n) ame --> n<!--(v) alue-type:transient type of values --> n<!--(t) ype:persistent type of metric --> n<!-- fmt:format;show;--> n<!ELEMENT Metric(MetricFormula *, Info?)> n<!ATTLIST Metric\n i CDATA #REQUIRED\n n CDATA #REQUIRED\n es CDATA #IMPLIED\n em CDATA #IMPLIED\n ep CDATA #IMPLIED\n v(raw|final|derived-incr|derived) \"raw\\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ fmt CDATA #IMPLIED\ show (1|0) \1\\ show-percent (1|0) \1> n n<!-- MetricFormula represents derived metrics: (t)ype; (frm): formula --> n<!ELEMENT MetricFormula (Info?)> n<!ATTLIST MetricFormula\ t (combine|finalize) \finalize\\ i CDATA #IMPLIED\ frm CDATA #REQUIRED> n n<!-- Metric data, used in sections: (n)ame [from Metric]; (v)alue --> n<!ELEMENT M EMPTY> n<!ATTLIST M\ n CDATA #REQUIRED\ v CDATA #REQUIRED> n n<!-- MetricDBTable: --> n<!ELEMENT MetricDBTable (MetricDB)*> n n<!-- MetricDB: (i)d; (n)ame --> n<!-- (t)ype: persistent type of metric --> n<!-- db-glob: file glob describing files in metric db --> n<!-- db-id: id within metric db --> n<!-- db-num-metrics: number of metrics in db --> n<!-- db-header-sz: size (in bytes) of a db file header --> n<!ELEMENT MetricDB EMPTY> n<!ATTLIST MetricDB\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ db-glob CDATA #IMPLIED\ db-id CDATA #IMPLIED\ db-num-metrics CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- TraceDBTable: --> n<!ELEMENT TraceDBTable (TraceDB)> n n<!-- TraceDB: (i)d --> n<!-- db-min-time: min beginning time stamp (global) --> n<!-- db-max-time: max ending time stamp (global) --> n<!ELEMENT TraceDB EMPTY> n<!ATTLIST TraceDB\ i CDATA #REQUIRED\ db-glob CDATA #IMPLIED\ db-min-time CDATA #IMPLIED\ db-max-time CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- LoadModuleTable assigns a short name to a load module --> n<!ELEMENT LoadModuleTable (LoadModule)*> n n<!ELEMENT LoadModule (Info?)> n<!ATTLIST LoadModule\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- FileTable assigns a short name to a file --> n<!ELEMENT FileTable (File)*> n n<!ELEMENT File (Info?)> n<!ATTLIST File\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- ProcedureTable assigns a short name to a procedure --> n<!ELEMENT ProcedureTable (Procedure)*> n n<!-- Info/NV: flexible name-value pairs: (n)ame; (t)ype; (v)alue --> n<!-- f: family of the procedure (fake, root, ...)--> n<!ELEMENT Procedure (Info?)> n<!ATTLIST Procedure\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ f CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Call path profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecCallPathProfile (SecHeader, SecCallPathProfileData)> n<!ATTLIST SecCallPathProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecCallPathProfileData (PF|M)*> n<!-- Procedure frame --> n<!-- (i)d: unique identifier for cross referencing --> n<!-- (s)tatic scope id --> n<!-- (n)ame: a string or an id in ProcedureTable --> n<!-- (lm) load module: a string or an id in LoadModuleTable --> n<!-- (f)ile name: a string or an id in LoadModuleTable --> n<!-- (l)ine range: \beg-end\ (inclusive range) --> n<!-- (a)lien: whether frame is alien to enclosing P --> n<!-- (str)uct: hpcstruct node id --> n<!-- (t)ype: hpcrun node type: memory access, variable declaration, ... --> n<!-- (v)ma-range-set: \{[beg-end), [beg-end)...}\ --> n<!ELEMENT PF (PF|Pr|L|C|S|M)*> n<!ATTLIST PF\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Procedure (static): GOAL: replace with 'P' --> n<!ELEMENT Pr (Pr|L|C|S|M)*> n<!ATTLIST Pr\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ a (1|0) \0\\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Callsite (a special StatementRange) --> n<!ELEMENT C (PF|M)*> n<!ATTLIST C\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Flat profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecFlatProfile (SecHeader, SecFlatProfileData)> n<!ATTLIST SecFlatProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecFlatProfileData (LM|M)*> n<!-- Load module: (i)d; (n)ame; (v)ma-range-set --> n<!ELEMENT LM (F|P|M)*> n<!ATTLIST LM\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ v CDATA #IMPLIED> n<!-- File --> n<!ELEMENT F (P|L|S|M)*> n<!ATTLIST F\ i CDATA #IMPLIED\ n CDATA #REQUIRED> n<!-- Procedure (Note 1) --> n<!ELEMENT P (P|A|L|S|C|M)*> n<!ATTLIST P\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Alien (Note 1) --> n<!ELEMENT A (A|L|S|C|M)*> n<!ATTLIST A\ i CDATA #IMPLIED\ f CDATA #IMPLIED\ n CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Loop (Note 1,2) --> n<!ELEMENT L (A|Pr|L|S|C|M)*> n<!ATTLIST L\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ f CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Statement (Note 2) --> n<!-- (it): trace record identifier --> n<!ELEMENT S (S|M)*> n<!ATTLIST S\ i CDATA #IMPLIED\ it CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Note 1: Contained Cs may not contain PFs --> n<!-- Note 2: The 's' attribute is not used for flat profiles --> n
csklnode_t * left_sentinel
void(* mem_free)(void *ptr)
static void mcs_init(mcs_lock_t *l)