(12) Patent Application Publication (10) Pub. No.: US 2004/0107227 A1 Michael (43) Pub
Total Page:16
File Type:pdf, Size:1020Kb
US 2004O107227A1 (19) United States (12) Patent Application Publication (10) Pub. No.: US 2004/0107227 A1 Michael (43) Pub. Date: Jun. 3, 2004 (54) METHOD FOR EFFICIENT Publication Classification IMPLEMENTATION OF DYNAMIC LOCK-FREE DATASTRUCTURES WITH (51) Int. Cl." ............................ G06F 17/30; G06F 12/00 SAFE MEMORY RECLAMATION (52) U.S. Cl. .............................................................. 707/206 (57) ABSTRACT Inventor: (75) Maged M. Michael, Danbury, CT (US) A method for Safe memory reclamation for dynamic lock free data structures employs a plurality of Shared pointers, Correspondence Address: called hazard pointers, that are associated with each partici F. CHAU & ASSOCIATES, LLP pating thread. Hazard pointers either have null values or Suite 501 point to nodes that may potentially be accessed by a thread 1900 Hempstead Turnpike without further verification of the validity of the local East Meadow, NY 11554 (US) references used in their access. Each hazard pointer can be written only by its associated thread, but can be read by all (73) Assignee: International Business Machines Cor threads. The method requires target lock-free algorithms to poration, Armonk, NY (US) guarantee that no thread can access a dynamic node at a time when it is possibly unsafe (i.e., removed from the data (21) Appl. No.: 10/308,449 Structure), unless one or more of its associated hazard pointerS has been pointing to the node continuously, from a (22) Filed: Dec. 3, 2002 time when it was not removed. 2 3 4. Hash table With 7 buckets and hash function h(k) F k mod 7 Patent Application Publication Jun. 3, 2004 Sheet 1 of 8 US 2004/0107227A1 PRIMARY STORAGE OPERATING SECONDARY I/O SYSTEM STORAGE SERVICES Application Programs FIG. Patent Application Publication Jun. 3, 2004 Sheet 2 of 8 US 2004/0107227 A1 // Node structure structure NodeType {Data:DataType; Next:*NodeType;} // Shared variables Top:*NodeType; // Initially Top = null // hp is a private pointer to a hazard pointer of the current thread Pop(): DataType { While true { 1. t = Top; 2 ift = null return EMPTY; 3 *hp = ti 4 if Top = t continue; // try again; 5 next = t.Next; 6 if CAS(&Top, t, next) break; } data = t Data; RetireNode(t); return data; } Exemplary lock-free Pop operation from a shared stack with hazard pointers FIG. 2 Patent Application Publication Jun. 3, 2004 Sheet 3 of 8 US 2004/0107227 A1 // Per-thread hazard pointer record structure HPRecType (HPIK) : *NodeType; Next: *HPRecType;} // The header of the HPRec list FirstHPRec: *HPRecType; // Static private variables rlist : *NodeType; // initially null rcount : integer; // initially 0 FIG. 3(A) RetireNode(node:*NodeType) { node'.rlink= rlist; rlist = node, rcount----, ifrcount >= R ScanG); FIG. 3(B) Patent Application Publication Jun. 3, 2004 Sheet 4 of 8 US 2004/0107227 A1 Scan() { i, p: integer, hptr, node, next, plist K*P) : *NodeType; // Stage 1 - scan HP list p = 0; hprec= FirstHPRec; while hprec = null { for i = 0 to K-1 if (hptr = hprec.HPi)) = null plist p-t = hptr; hprec = hprec/.Next; } // Stage 2 - sort plist Sort(p.plist); // Stage 3 - search sorted list next = rlist; rlist = null; rcount = 0; while next = null { node F next; next = node'.rlink; if search(node.p.plist) { node'.rlink = rlist; rlist = node, rcount++; } else PrepareForReuse(node); FIG. 3(C) Patent Application Publication Jun. 3, 2004 Sheet 5 of 8 US 2004/0107227 A1 Hash table with 7 buckets and hash function h(k) FK mod 7 FIG. 4 Patent Application Publication Jun. 3, 2004 Sheet 6 of 8 US 2004/0107227 A1 // Types and structures Structure NodeType {Key: KeyType; Next: *NodeType} // T is the hash table - // M is the number of hash buckets TMI: *NodeType; // Initially null Types and structures FIG. 5 // Hash function h(key: KeyType): 0.M-1 {...} // Hash table operations Hashinsert(key: KeyType): boolean { // Assuming new node allocation always succeeds node = NewNode(); node. Key = key; if Insert(&Th(key), node) return true; FreeNode(node); return false; HashDelete(key: KeyType): boolean { Return Delete(&Th(key)),key); } - HashSearch(key: KeyType): boolean { Return Search(&Th(key)),key); } Hash table operations FIG. 6 Patent Application Publication Jun. 3, 2004 Sheet 7 of 8 US 2004/0107227 A1 // hp0 and hp1 are private pointers to the hazard pointers of the current thread // *hp0 has a lower index than *hp1 in the thread's HPRec // Static private variables prev:**NodeType; cur, next : *NodeType; Find(head:**NodeType;key:KeyType) : boolean { try again: 1 prev = head; 2 cur = *head; 3 while curl= null { 5 if *prev = cur goto try again; 6 next = cur.Next; 7 if next & 1 { 8 if CAS(prev,cur, next-1) goto try again; 9 RetireNode(cur); 10 cur = next-l; 1 } else { 12 ckey - cur.Key; 13 if prev - curgoto try again; 14 ifckey >= key returnckey - key; 15 prev = &cur.Next; 16 hp1 = cur; 17 cur = next; 18 } - 19 } 20 return false; List-base set algorithm with hazard pointers FIG. 7(A) Patent Application Publication Jun. 3, 2004 Sheet 8 of 8 US 2004/0107227 A1 Insert (head:**NodeType, node:*NodeType):boolean { key - node?. Key; while true { 21 if Find(head,key) { result = false; break;} 22 node^.Next = cur; 23 if CAS(prev,cur.node) { result = true; break;} } return result, } Delete(head:**NodeType,key:KeyType):boolean { while true { 24 if Find (head,key) (result = false; break;} 25 if CAS(&cur.Next{\tuple{Mark,Next, next, next{-1) continue; 26 if CAS(prev,cur, next) RetireNode(cur); else Find(head,key); result = true, break; } return result, }. Search(head:**NodeType, key:KeyType):boolean { result = Find(head,key), return result, List-base set algorithm with hazard pointers FIG. 7 (B) US 2004/0107227 A1 Jun. 3, 2004 METHOD FOR EFFICIENT IMPLEMENTATION an old reference to the node with the intent to use that OF DYNAMIC LOCK-FREE DATASTRUCTURES reference as an expected value of an atomic operation on the WITH SAFE MEMORY RECLAMATION object. This can happen even if nodes are only reused but never reclaimed. For these objects, the ABA problem can be BACKGROUND OF THE INVENTION prevented if it is guaranteed that no thread can use the address of a node as an expected value of an atomic 0001) 1. Field of the Invention operation, while the node is free or ready for reuse. 0002 The present invention relates generally to memory 0010 Another significant problem associated with some management, and more particularly, to techniques for man important lock-free data Structures based on linked-lists is aging shared access among multiple threads. that they require garbage collection (GC) for memory man 0003 2. Background of the Invention agement, which is not always available, and hence limit the portability of Such data Structures acroSS programming envi 0004. A shared object is lock-free (also called non blocking) if it guarantees that in a System with multiple rOnmentS. threads attempting to perform operations on the object, Some SUMMARY OF THE INVENTION thread will complete an operation Successfully in a finite 0011. According to various embodiments of the present number of system steps even with the possibility of arbitrary invention, a computer-implemented method for managing a thread delays, provided that not all threads are delayed shared dynamic data Structure in a multithreaded operating indefinitely. By definition, lock-free objects are immune to environment includes Setting a hazard pointer to an address deadlock even with thread failures and provide robust per of a portion of the data Structure to be removed, removing formance even when faced with inopportune thread delayS. the portion of the data structure, and ensuring that memory Dynamic lock-free objects have the added advantage of asSociated with the removed portion of the data structure is arbitrary size. freed only when the hazard pointer no longer points to the 0005. However, there are various problems associated removed portion of the data Structure. with lock-free objects. For instance, it may be difficult to 0012 Each thread sharing the dynamic data structure will ensure Safe reclamation of memory occupied by removed preferably have at least one hazard pointer which may be Set nodes. In a lock-based object, when a thread removes a node to a null value or to portions of the data Structure that are from the object, it can be guaranteed that no other thread will accessed by the thread without verification of references Subsequently access the contents of the removed node while used in their access. The thread Setting the hazard pointer Still assuming its retention of type and content Semantics. ensures that it accesses a portion of the data structure to be Consequently, it is Safe for the removing thread to free the removed, only if the hazard pointer continuously points to memory occupied by the removed node into the general the portion of the data Structure from a time it was not memory pool for arbitrary future reuse. removed. Another thread can then free the removed portion 0006. This is not the case for a lock-free object. When a of the data Structure for arbitrary reuse. Operations on the thread removes a node, it is possible that one or more data Structure are guaranteed to proceed concurrently with contending threads, in the course of their lock-free opera out any one of the operations preventing other operations tions, have earlier read a pointer to the Subsequently from completing indefinitely. removed node, and are about to access its contents. A 0013 The data structure used can be a linked list and, in contending thread might corrupt the shared object or another this case, the removed portion of the data structure will be object, if the thread performing the removal were to free the a node. The linked-list data Structure may be used to removed node for arbitrary reuse.