Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Nov 10th, 2012  |  syntax: C++  |  size: 4.95 KB  |  hits: 53  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. // ======================================================================== //
  2. // Copyright 2009-2012 Intel Corporation                                    //
  3. //                                                                          //
  4. // Licensed under the Apache License, Version 2.0 (the "License");          //
  5. // you may not use this file except in compliance with the License.         //
  6. // You may obtain a copy of the License at                                  //
  7. //                                                                          //
  8. //     http://www.apache.org/licenses/LICENSE-2.0                           //
  9. //                                                                          //
  10. // Unless required by applicable law or agreed to in writing, software      //
  11. // distributed under the License is distributed on an "AS IS" BASIS,        //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and      //
  14. // limitations under the License.                                           //
  15. // ======================================================================== //
  16.  
  17. #ifndef __EMBREE_ATOMIC_SET_H__
  18. #define __EMBREE_ATOMIC_SET_H__
  19.  
  20. #include "sys/intrinsics.h"
  21.  
  22. namespace embree
  23. {
  24.   /*! An atomic set. Insert calls are atomic and take calls are atomic
  25.       but only when not called intermixed. Thus one can only
  26.       atomically remove or insert items. */
  27.   template<typename T>
  28.     class __align(64) atomic_set
  29.   {
  30.     ALIGNED_CLASS;
  31.   public:
  32.  
  33.     /*! set item */
  34.     class item : public T
  35.     {
  36.     public:
  37.      
  38.       /*! default constructor */
  39.       item () : next(NULL) {}
  40.  
  41.     public:
  42.       item* next;
  43.     };
  44.  
  45.     /*! Iterator for the set. */
  46.     class iterator
  47.     {
  48.     public:
  49.  
  50.       /*! default constructor */
  51.      __forceinline  iterator ()
  52.         : root(NULL) {}
  53.  
  54.       /*! initialize the iterator from a set */
  55.       __forceinline iterator (atomic_set& other)
  56.         : root(other.root) {}
  57.  
  58.  
  59.       /*! return next element */
  60.       __forceinline item* next()
  61.       {
  62.         item* ptr;
  63.         while (!try_take(ptr));
  64.         return ptr;
  65.       }
  66.  
  67.     private:
  68.       __forceinline bool try_take(item*& ptr)
  69.       {
  70.         ptr = root;
  71.         if (ptr == NULL) return true;
  72.         return atomic_cmpxchg(&root,ptr->next,ptr) == ptr;
  73.       }
  74.  
  75.     private:
  76.       item* root;
  77.     };
  78.  
  79.     /*! Not thread safe iterator for iterating over elements of a list of blocks. */
  80.     class block_iterator_unsafe
  81.     {
  82.       typedef typename T::T Type;
  83.     public:
  84.       __forceinline block_iterator_unsafe (atomic_set& other)
  85.         : root(other.root), pos(0)
  86.       {
  87.         next();
  88.       }
  89.      
  90.       __forceinline void operator++(int)
  91.       {
  92.         pos++;
  93.         next();
  94.       }
  95.  
  96.       size_t size()
  97.       {
  98.         size_t s = 0;
  99.         while (root) {
  100.           s += root->size();
  101.           root = root->next;
  102.         }
  103.         return s;
  104.       }
  105.  
  106.       __forceinline operator bool( ) const { return root; }
  107.       __forceinline const Type& operator*( ) const { return (*root)[pos]; }
  108.       __forceinline       Type& operator*( )       { return (*root)[pos]; }
  109.  
  110.     private:
  111.  
  112.       __forceinline void next()
  113.       {
  114.         while (root && pos >= root->size()) {
  115.           root = root->next;
  116.           pos = 0;
  117.         }
  118.       }
  119.  
  120.     private:
  121.       item* root;
  122.       size_t pos;
  123.     };
  124.  
  125.   public:
  126.  
  127.      /*! default constructor */
  128.     __forceinline atomic_set () : root(NULL) {}
  129.  
  130.     /*! copy constructor */
  131.     __forceinline atomic_set (atomic_set& other) {
  132.       this->root = other.root; other.root = NULL;
  133.     }
  134.  
  135.     /*! assignment operator */
  136.     __forceinline atomic_set& operator=(atomic_set& other) {
  137.       this->root = other.root; other.root = NULL;
  138.       return *this;
  139.     }
  140.  
  141.     /*! add element to front of list */
  142.     __forceinline item* insert(item* ptr) {
  143.       while (!try_insert(ptr)); return ptr;
  144.     }
  145.  
  146.     /*! remove element from front of list */
  147.     __forceinline item* take()
  148.     {
  149.       item* ptr;
  150.       while (!try_take(ptr));
  151.       return ptr;
  152.     }
  153.  
  154.     /*! add element to front of list */
  155.     __forceinline item* insert_unsafe(item* ptr) {
  156.       ptr->next = root;
  157.       root = ptr;
  158.       return ptr;
  159.     }
  160.  
  161.     /*! remove element from front of list */
  162.     __forceinline item* take_unsafe()
  163.     {
  164.       if (root == NULL) return NULL;
  165.       item* cur = root;
  166.       root = cur->next;
  167.       return cur;
  168.     }
  169.  
  170.   private:
  171.  
  172.     __forceinline bool try_insert(item* ptr)
  173.     {
  174.       if (ptr == NULL) return true;
  175.       item* cur = root;
  176.       ptr->next = cur;
  177.       return atomic_cmpxchg(&root,ptr,cur) == cur;
  178.     }
  179.  
  180.     __forceinline bool try_take(item*& ptr)
  181.     {
  182.       ptr = root;
  183.       if (ptr == NULL) return true;
  184.       return atomic_cmpxchg(&root,ptr->next,ptr) == ptr;
  185.     }
  186.  
  187.   private:
  188.     item* root;
  189.   };
  190. }
  191.  
  192. #endif