00001
00002
00003 #ifndef space_index_h
00004 #define space_index_h
00005
00006 #include "l4_types.h"
00007
00008
00009
00010
00011
00012
00013 class Space;
00014 class Space_registry;
00015
00016 class Space_index
00017 {
00018 public:
00019 enum
00020 {
00021 Max_space_number = L4_uid::Max_tasks
00022 };
00023
00024 private:
00025
00026 static Space_registry* spaces;
00027
00028
00029 unsigned space_id;
00030
00031 public:
00032 explicit inline Space_index(unsigned number);
00033
00034
00035 inline operator unsigned ();
00036
00037 inline Space * lookup();
00038
00039 inline bool set_chief(Space_index old_chief, Space_index new_chief);
00040
00041 inline Space_index chief();
00042
00043 static inline bool add(Space *new_space, unsigned new_number);
00044
00045 static inline bool del(Space_index number, Space_index chief);
00046
00047 static inline void aux_del(Space_index );
00048 };
00049
00050
00051
00052
00053
00054
00055 #include "atomic.h"
00056
00057 #include <cassert>
00058
00059
00060
00061
00062
00063
00064
00065
00066 inline Space_index::Space_index(unsigned number)
00067
00068 : space_id(number)
00069 { }
00070
00071
00072
00073 inline Space_index::operator unsigned ()
00074 { return space_id; }
00075
00076
00077
00078
00079 struct Space_registry
00080 {
00081 union {
00082 Space *space;
00083 struct {
00084 unsigned dead : 1;
00085 unsigned chief : 31;
00086 } state;
00087 };
00088
00089 operator Mword () { return (Mword)space; }
00090
00091
00092 public:
00093
00094 inline Space_registry();
00095 };
00096
00097
00098
00099 inline Space *
00100 Space_index::lookup()
00101 {
00102 if (spaces[space_id].state.dead)
00103 return 0;
00104
00105 return spaces[space_id].space;
00106 }
00107
00108
00109
00110
00111 inline Space_registry::Space_registry()
00112 {
00113 state.chief = 0;
00114 state.dead = 1;
00115 }
00116
00117
00118
00119 inline bool
00120 Space_index::set_chief(Space_index old_chief, Space_index new_chief)
00121 {
00122 Space_registry o(spaces[space_id]);
00123
00124 if (! o.state.dead || o.state.chief != old_chief)
00125 return false;
00126
00127 Space_registry n;
00128 n.state.chief = new_chief;
00129
00130 return cas (&spaces[space_id], o, n);
00131 }
00132
00133
00134
00135 inline Space_index
00136 Space_index::chief()
00137 {
00138 assert (spaces[space_id].state.dead);
00139
00140 return Space_index(spaces[space_id].state.chief);
00141 }
00142
00143
00144
00145 inline bool
00146 Space_index::add(Space *new_space, unsigned new_number)
00147 {
00148 Space_registry o(spaces[new_number]);
00149 assert(o.state.dead);
00150
00151 Space_registry n;
00152 n.space = new_space;
00153
00154 return cas (&spaces[new_number], o, n);
00155 }
00156
00157
00158
00159 inline void
00160 Space_index::aux_del(Space_index )
00161 {}
00162
00163
00164
00165 inline bool
00166 Space_index::del(Space_index number, Space_index chief)
00167 {
00168 assert(number < Max_space_number);
00169 assert(! spaces[number].state.dead);
00170
00171
00172 spaces[number].state.dead = 1;
00173 spaces[number].state.chief = chief;
00174
00175 aux_del(number);
00176
00177 return true;
00178 }
00179
00180 #endif // space_index_h