/[hurd]/hurd-l4/libl4/l4/ipc.h
ViewVC logotype

Diff of /hurd-l4/libl4/l4/ipc.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.10 by marcus, Sun Jan 30 23:00:39 2005 UTC revision 1.11 by marcus, Wed Feb 9 04:07:00 2005 UTC
# Line 1  Line 1 
1  /* l4/ipc.h - Public interface to the L4 IPC primitive.  /* l4/ipc.h - Public interface to the L4 IPC primitive.
2     Copyright (C) 2003, 2004 Free Software Foundation, Inc.     Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3     Written by Marcus Brinkmann <marcus@gnu.org>.     Written by Marcus Brinkmann <marcus@gnu.org>.
4    
5     This file is part of the GNU L4 library.     This file is part of the GNU L4 library.
# Line 74  static inline _L4_word_t Line 74  static inline _L4_word_t
74  _L4_attribute_always_inline  _L4_attribute_always_inline
75  _L4_label (_L4_msg_tag_t tag)  _L4_label (_L4_msg_tag_t tag)
76  {  {
77    __L4_msg_tag_t _tag;    __L4_msg_tag_t _tag = { .raw = tag };
78    
   _tag.raw = tag;  
79    return _tag.label;    return _tag.label;
80  }  }
81    
# Line 85  static inline _L4_word_t Line 84  static inline _L4_word_t
84  _L4_attribute_always_inline  _L4_attribute_always_inline
85  _L4_untyped_words (_L4_msg_tag_t tag)  _L4_untyped_words (_L4_msg_tag_t tag)
86  {  {
87    __L4_msg_tag_t _tag;    __L4_msg_tag_t _tag = { .raw = tag };
88    
   _tag.raw = tag;  
89    return _tag.untyped;    return _tag.untyped;
90  }  }
91    
# Line 96  static inline _L4_word_t Line 94  static inline _L4_word_t
94  _L4_attribute_always_inline  _L4_attribute_always_inline
95  _L4_typed_words (_L4_msg_tag_t tag)  _L4_typed_words (_L4_msg_tag_t tag)
96  {  {
97    __L4_msg_tag_t _tag;    __L4_msg_tag_t _tag = { .raw = tag };
98    
   _tag.raw = tag;  
99    return _tag.typed;    return _tag.typed;
100  }  }
101    
# Line 107  static inline _L4_msg_tag_t Line 104  static inline _L4_msg_tag_t
104  _L4_attribute_always_inline  _L4_attribute_always_inline
105  _L4_msg_tag_add_label (_L4_msg_tag_t tag, _L4_word_t label)  _L4_msg_tag_add_label (_L4_msg_tag_t tag, _L4_word_t label)
106  {  {
107    __L4_msg_tag_t _tag;    __L4_msg_tag_t _tag = { .raw = tag };
108    
   _tag.raw = tag;  
109    _tag.label = label;    _tag.label = label;
110    return _tag.raw;    return _tag.raw;
111  }  }
# Line 119  static inline void Line 115  static inline void
115  _L4_attribute_always_inline  _L4_attribute_always_inline
116  _L4_msg_tag_add_label_to (_L4_msg_tag_t *tag, _L4_word_t label)  _L4_msg_tag_add_label_to (_L4_msg_tag_t *tag, _L4_word_t label)
117  {  {
118    __L4_msg_tag_t _tag;    __L4_msg_tag_t _tag = { .raw = *tag };
119    
   _tag.raw = *tag;  
120    _tag.label = label;    _tag.label = label;
121    *tag = _tag.raw;    *tag = _tag.raw;
122  }  }
# Line 136  _L4_msg_tag (void) Line 131  _L4_msg_tag (void)
131    return tag;    return tag;
132  }  }
133    
134    
135  static inline void  static inline void
136  _L4_attribute_always_inline  _L4_attribute_always_inline
137  _L4_set_msg_tag (_L4_msg_tag_t tag)  _L4_set_msg_tag (_L4_msg_tag_t tag)
# Line 144  _L4_set_msg_tag (_L4_msg_tag_t tag) Line 140  _L4_set_msg_tag (_L4_msg_tag_t tag)
140  }  }
141    
142    
143    /* All items.  */
144    
145    /* Get the continuation flag.  */
146    static inline _L4_word_t
147    _L4_attribute_always_inline
148    _L4_item_not_last (void *item)
149    {
150      _L4_word_t _item;
151      __builtin_memcpy (&_item, item, sizeof (_L4_word_t));
152    
153      /* The not_last flag is always the lowest bit in the item.  */
154      return _item & 1;
155    }
156    
157    
158    /* Get the continuation flag.  */
159    static inline void
160    _L4_attribute_always_inline
161    _L4_set_item_not_last (void *item, _L4_word_t val)
162    {
163      _L4_word_t _item;
164      __builtin_memcpy (&_item, item, sizeof (_L4_word_t));
165    
166      /* The not_last flag is always the lowest bit in the item.  */
167      _item = (_item & ~0) | !!val;
168    
169      __builtin_memcpy (item, &_item, sizeof (_L4_word_t));
170    }
171    
172    
173  /* Map items.  */  /* Map items.  */
174    
175  typedef _L4_dword_t _L4_map_item_t;  typedef _L4_dword_t _L4_map_item_t;
# Line 187  static inline _L4_word_t Line 213  static inline _L4_word_t
213  _L4_attribute_always_inline  _L4_attribute_always_inline
214  _L4_is_map_item (_L4_map_item_t map_item)  _L4_is_map_item (_L4_map_item_t map_item)
215  {  {
216    __L4_map_item_t _map_item;    __L4_map_item_t _map_item = { .raw = map_item };
217    
   _map_item.raw = map_item;  
218    return _map_item._four == 4;    return _map_item._four == 4;
219  }  }
220    
# Line 198  static inline _L4_word_t Line 223  static inline _L4_word_t
223  _L4_attribute_always_inline  _L4_attribute_always_inline
224  _L4_map_item_snd_fpage (_L4_map_item_t map_item)  _L4_map_item_snd_fpage (_L4_map_item_t map_item)
225  {  {
226    __L4_map_item_t _map_item;    __L4_map_item_t _map_item = { .raw = map_item };
227    
   _map_item.raw = map_item;  
228    return _map_item.send_fpage;    return _map_item.send_fpage;
229  }  }
230    
# Line 209  static inline _L4_word_t Line 233  static inline _L4_word_t
233  _L4_attribute_always_inline  _L4_attribute_always_inline
234  _L4_map_item_snd_base (_L4_map_item_t map_item)  _L4_map_item_snd_base (_L4_map_item_t map_item)
235  {  {
236    __L4_map_item_t _map_item;    __L4_map_item_t _map_item = { .raw = map_item };
237    
   _map_item.raw = map_item;  
238    return _map_item.send_base << 10;    return _map_item.send_base << 10;
239  }  }
240    
# Line 259  static inline _L4_word_t Line 282  static inline _L4_word_t
282  _L4_attribute_always_inline  _L4_attribute_always_inline
283  _L4_is_grant_item (_L4_grant_item_t grant_item)  _L4_is_grant_item (_L4_grant_item_t grant_item)
284  {  {
285    __L4_grant_item_t _grant_item;    __L4_grant_item_t _grant_item = { .raw = grant_item };
286    _grant_item.raw = grant_item;  
287    return _grant_item._five == 5;    return _grant_item._five == 5;
288  }  }
289    
# Line 269  static inline _L4_word_t Line 292  static inline _L4_word_t
292  _L4_attribute_always_inline  _L4_attribute_always_inline
293  _L4_grant_item_snd_fpage (_L4_grant_item_t grant_item)  _L4_grant_item_snd_fpage (_L4_grant_item_t grant_item)
294  {  {
295    __L4_grant_item_t _grant_item;    __L4_grant_item_t _grant_item = { .raw = grant_item };
296    
   _grant_item.raw = grant_item;  
297    return _grant_item.send_fpage;    return _grant_item.send_fpage;
298  }  }
299    
# Line 280  static inline _L4_word_t Line 302  static inline _L4_word_t
302  _L4_attribute_always_inline  _L4_attribute_always_inline
303  _L4_grant_item_snd_base (_L4_grant_item_t grant_item)  _L4_grant_item_snd_base (_L4_grant_item_t grant_item)
304  {  {
305    __L4_grant_item_t _grant_item;    __L4_grant_item_t _grant_item = { .raw = grant_item };
306    
   _grant_item.raw = grant_item;  
307    return _grant_item.send_base << 10;    return _grant_item.send_base << 10;
308  }  }
309    
# Line 336  _L4_string_item (int length, void *addre Line 357  _L4_string_item (int length, void *addre
357    
358  static inline _L4_word_t  static inline _L4_word_t
359  _L4_attribute_always_inline  _L4_attribute_always_inline
360  _L4_is_string_item (_L4_string_item_t *string_item)  _L4_is_string_item (void *string_item)
361  {  {
362    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;    __L4_string_item_t _string_item;
363      __builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw));
364    
365    return _string_item->_zero == 0;    return _string_item._zero == 0;
366  }  }
367    
368    
369  static inline _L4_word_t  static inline _L4_word_t
370  _L4_attribute_always_inline  _L4_attribute_always_inline
371  _L4_compound_string (_L4_string_item_t *string_item)  _L4_compound_string (void *string_item)
372  {  {
373    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;    __L4_string_item_t _string_item;
374      __builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw));
375    
376    return _string_item->cont;    return _string_item.cont;
377    }
378    
379    
380    static inline void
381    _L4_attribute_always_inline
382    _L4_set_compound_string (void *string_item, _L4_word_t cont)
383    {
384      __L4_string_item_t _string_item;
385      __builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw));
386    
387      _string_item.cont = !!cont;
388    
389      __builtin_memcpy (string_item, &_string_item.raw, sizeof (_string_item.raw));
390  }  }
391    
392    
393  static inline _L4_word_t  static inline _L4_word_t
394  _L4_attribute_always_inline  _L4_attribute_always_inline
395  _L4_substrings (_L4_string_item_t *string_item)  _L4_substrings (void *string_item)
396  {  {
397    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;    __L4_string_item_t _string_item;
398      __builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw));
399    
400      return _string_item.nr_substrings + 1;
401    }
402    
403    
404    return _string_item->nr_substrings + 1;  static inline void
405    _L4_attribute_always_inline
406    _L4_set_substrings (void *string_item, _L4_word_t substrings)
407    {
408      __L4_string_item_t _string_item;
409      __builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw));
410    
411      _string_item.nr_substrings = substrings - 1;
412    
413      __builtin_memcpy (string_item, &_string_item, sizeof (_string_item.raw));
414  }  }
415    
416    
417  static inline void *  static inline void *
418  _L4_attribute_always_inline  _L4_attribute_always_inline
419  _L4_substring (_L4_string_item_t *string_item, _L4_word_t nr)  _L4_substring (void *string_item, _L4_word_t nr)
420  {  {
421      /* This does not break strict aliasing, see below.  */
422    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;
423    return (void *) _string_item->string[nr];    _L4_word_t string;
424    
425      /* To avoid breaking strict aliasing rules, we must not actually use
426         _string_item for anything but pointer arithmetics, as we don't
427         know the type of the underlying storage.  To be safe, we have to
428         actually copy the memory through a char pointer.  */
429      __builtin_memcpy (&string, &_string_item->string[nr - 1], sizeof (_L4_word_t));
430    
431      return (void *) string;
432    }
433    
434    
435    /* Count the number of all words used by the string item STRING_ITEM.
436       If ALL_ITEMS is true, words used by following string items (until
437       NOT_LAST is not set) will also be counted.  */
438    static inline _L4_word_t
439    _L4_attribute_always_inline
440    _L4_string_item_words (void *string_item, _L4_word_t all_items)
441    {
442      /* We do not break any strict aliasing rules here, as we only use
443         the pointers for pointer arithmetic.  */
444      __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;
445      int cont;
446      int count = 0;
447    
448      do
449        {
450          int nr = 1 + _L4_substrings (_string_item);
451    
452          cont = _L4_compound_string (_string_item);
453          if (all_items)
454            cont = cont || _L4_item_not_last (_string_item);
455    
456          /* Remember how many words are used by all string items.  */
457          count += nr;
458    
459          /* Skip over the current string item.  */
460          _string_item = (__L4_string_item_t *)
461            (((_L4_word_t *) _string_item) + nr);
462        }
463      while (cont);
464    
465      return count;
466  }  }
467    
468    
469  /* Append the string described by string item SOURCE to the string  /* Append the string described by string item SOURCE to the string
470     described by string item STRING_ITEM.  */     described by string item STRING_ITEM.  */
471  static inline _L4_string_item_t *  static inline void *
472  _L4_attribute_always_inline  _L4_attribute_always_inline
473  _L4_add_substring_to (_L4_string_item_t *string_item,  _L4_add_substring_to (void *string_item, void *source)
                               _L4_string_item_t *source)  
474  {  {
475      /* We do not break any strict aliasing rules here, as we only use
476         the pointers for pointer arithmetic.  */
477    __L4_string_item_t *target = (__L4_string_item_t *) string_item;    __L4_string_item_t *target = (__L4_string_item_t *) string_item;
478    __L4_string_item_t *_source = (__L4_string_item_t *) source;    __L4_string_item_t *_source = (__L4_string_item_t *) source;
479    int cont;    int cont;
480      int count;
481    
482    /* First search for end of target string item.  */    /* First search for end of target string item.  */
483    do    do
484      {      {
485        cont = target->cont;        cont = _L4_compound_string (target);
486        if (!cont)        if (!cont)
487          target->cont = 1;          _L4_set_compound_string (target, 1);
488        target = (__L4_string_item_t *)        target = (__L4_string_item_t *)
489          (((_L4_word_t *) target) + 1 + target->nr_substrings + 1);          (((_L4_word_t *) target) + 1 + _L4_substrings (target));
490      }      }
491    while (cont);    while (cont);
492    
493    /* Now copy the source string item.  */    /* Now copy the source string item.  */
494    do    count = _L4_string_item_words (_source, 0);
495      while (count--)
496      {      {
497        int nr = 1 + _source->nr_substrings + 1;        __builtin_memcpy (target, _source, sizeof (_L4_word_t));
498        cont = _source->cont;        target = (__L4_string_item_t *) (((_L4_word_t *) target) + 1);
499        while (nr--)        _source = (__L4_string_item_t *) (((_L4_word_t *) source) + 1);
         *(target++) = *(_source++);  
500      }      }
   while (cont);  
501    
502    return string_item;    return string_item;
503  }  }
504    
505    
506  /* Append the string described by string item SOURCE as a substring  /* Append the string pointed to by SOURCE as a substring (of the same
507     (of the same length) to the string item STRING_ITEM.  */     length) to the string item STRING_ITEM.  */
508  static inline _L4_string_item_t *  static inline void *
509  _L4_attribute_always_inline  _L4_attribute_always_inline
510  _L4_add_substring_address_to (_L4_string_item_t *string_item, void *source)  _L4_add_substring_address_to (void *string_item, void *source)
511  {  {
512      /* We do not break any strict aliasing rules here, as we only use
513         the pointers for pointer arithmetic.  */
514    __L4_string_item_t *target = (__L4_string_item_t *) string_item;    __L4_string_item_t *target = (__L4_string_item_t *) string_item;
515    
516    /* First search for end of target string item.  */    /* First search for end of target string item.  */
517    while (target->cont)    while (_L4_compound_string (target))
518      target = (__L4_string_item_t *)      target = (__L4_string_item_t *)
519        (((_L4_word_t *) target) + 1 + target->nr_substrings + 1);        (((_L4_word_t *) target) + 1 + _L4_substrings (target));
520    
521    /* Now add the source substring.  */    /* Now add the source substring.  */
522    target->nr_substrings++;    _L4_set_substrings (target, _L4_substrings (target) + 1);
523    target->string[target->nr_substrings] = (_L4_word_t) source;    __builtin_memcpy (&target->string[_L4_substrings (target) - 1], source,
524              sizeof (_L4_word_t));
525    
526    return string_item;    return string_item;
527  }  }
# Line 434  static inline _L4_cache_allocation_hint_ Line 531  static inline _L4_cache_allocation_hint_
531  _L4_attribute_always_inline  _L4_attribute_always_inline
532  _L4_cache_allocation_hint (_L4_string_item_t string_item)  _L4_cache_allocation_hint (_L4_string_item_t string_item)
533  {  {
534    __L4_string_item_t _string_item;    __L4_string_item_t _string_item = { .raw = string_item };
535    
   _string_item.raw = string_item;  
536    return _string_item.cache_hint;    return _string_item.cache_hint;
537  }  }
538    
# Line 446  _L4_attribute_always_inline Line 542  _L4_attribute_always_inline
542  _L4_add_cache_allocation_hint (_L4_string_item_t string_item,  _L4_add_cache_allocation_hint (_L4_string_item_t string_item,
543                                 _L4_cache_allocation_hint_t hint)                                 _L4_cache_allocation_hint_t hint)
544  {  {
545    __L4_string_item_t _string_item;    __L4_string_item_t _string_item = { .raw = string_item };
546    
   _string_item.raw = string_item;  
547    _string_item.cache_hint = hint;    _string_item.cache_hint = hint;
548    return _string_item.raw;    return _string_item.raw;
549  }  }
550    
551    
552  static inline _L4_string_item_t *  static inline void *
553  _L4_attribute_always_inline  _L4_attribute_always_inline
554  _L4_add_cache_allocation_hint_to (_L4_string_item_t *string_item,  _L4_add_cache_allocation_hint_to (void *string_item,
555                                    _L4_cache_allocation_hint_t hint)                                    _L4_cache_allocation_hint_t hint)
556  {  {
557    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;    __L4_string_item_t _string_item;
558      __builtin_memcpy (&_string_item.raw, string_item, sizeof (_string_item.raw));
559    
560    _string_item->cache_hint = hint;    _string_item.cache_hint = hint;
561    
562      __builtin_memcpy (string_item, &_string_item.raw, sizeof (_string_item.raw));
563    return string_item;    return string_item;
564  }  }
565    
# Line 484  typedef _L4_RAW (_L4_acceptor_t, _L4_STR Line 582  typedef _L4_RAW (_L4_acceptor_t, _L4_STR
582    
583  typedef _L4_word_t _L4_msg_buffer_t[_L4_NUM_BRS - 1];  typedef _L4_word_t _L4_msg_buffer_t[_L4_NUM_BRS - 1];
584    
585    
586    static inline _L4_fpage_t
587    _L4_attribute_always_inline
588    _L4_rcv_window (_L4_acceptor_t acceptor)
589    {
590      __L4_acceptor_t _acceptor = { .raw = acceptor };
591    
592      /* The acceptor looks just like a receive window fpage, just that
593         the lower bits have a different meaning.  So we just clear
594         them.  */
595      _acceptor.string_items = 0;
596    
597      return (_L4_fpage_t) _acceptor.raw;
598    }
599    
600    
601    static inline _L4_word_t
602    _L4_attribute_always_inline
603    _L4_has_map_grant_items (_L4_acceptor_t acceptor)
604    {
605      /* FIXME: 0 is _L4_nilpage.  */
606      return _L4_rcv_window (acceptor) != 0;
607    }
608    
609    
610  static inline _L4_acceptor_t  static inline _L4_acceptor_t
611  _L4_attribute_always_inline  _L4_attribute_always_inline
612  _L4_map_grant_items (_L4_fpage_t rcv_window)  _L4_map_grant_items (_L4_fpage_t rcv_window)
613  {  {
614    __L4_acceptor_t acceptor;    __L4_acceptor_t acceptor = { .raw = rcv_window };
615    acceptor.raw = rcv_window;  
616    acceptor.string_items = 0;    acceptor.string_items = 0;
617    acceptor._zero = 0;    acceptor._zero = 0;
618    return acceptor.raw;    return acceptor.raw;
# Line 500  static inline _L4_acceptor_t Line 623  static inline _L4_acceptor_t
623  _L4_attribute_always_inline  _L4_attribute_always_inline
624  _L4_add_acceptor (_L4_acceptor_t acceptor1, _L4_acceptor_t acceptor2)  _L4_add_acceptor (_L4_acceptor_t acceptor1, _L4_acceptor_t acceptor2)
625  {  {
626    __L4_acceptor_t _acceptor1;    __L4_acceptor_t _acceptor1 = { .raw = acceptor1 };
627    __L4_acceptor_t _acceptor2;    __L4_acceptor_t _acceptor2 = { .raw = acceptor2 };
628    
   _acceptor1.raw = acceptor1;  
   _acceptor2.raw = acceptor2;  
629    _acceptor1.string_items |= _acceptor2.string_items;    _acceptor1.string_items |= _acceptor2.string_items;
630    if (_acceptor2.rcv_window)    if (_L4_has_map_grant_items (acceptor2))
631      _acceptor1.rcv_window = _acceptor2.rcv_window;      _acceptor1.rcv_window = _acceptor2.rcv_window;
632    return _acceptor1.raw;    return _acceptor1.raw;
633  }  }
# Line 516  static inline _L4_acceptor_t * Line 637  static inline _L4_acceptor_t *
637  _L4_attribute_always_inline  _L4_attribute_always_inline
638  _L4_add_acceptor_to (_L4_acceptor_t *acceptor1, _L4_acceptor_t acceptor2)  _L4_add_acceptor_to (_L4_acceptor_t *acceptor1, _L4_acceptor_t acceptor2)
639  {  {
640    __L4_acceptor_t *_acceptor1 = (__L4_acceptor_t *) acceptor1;    __L4_acceptor_t _acceptor1 = { .raw = *acceptor1 };
641    __L4_acceptor_t _acceptor2;    __L4_acceptor_t _acceptor2 = { .raw = acceptor2 };
642    
643    _acceptor2.raw = acceptor2;    _acceptor1.string_items |= _acceptor2.string_items;
644    _acceptor1->string_items |= _acceptor2.string_items;    if (_L4_has_map_grant_items (acceptor2))
645    if (_acceptor2.rcv_window)      _acceptor1.rcv_window = _acceptor2.rcv_window;
646      _acceptor1->rcv_window = _acceptor2.rcv_window;  
647      *acceptor1 = _acceptor1.raw;
648    return acceptor1;    return acceptor1;
649  }  }
650    
# Line 531  static inline _L4_acceptor_t Line 653  static inline _L4_acceptor_t
653  _L4_attribute_always_inline  _L4_attribute_always_inline
654  _L4_remove_acceptor (_L4_acceptor_t acceptor1, _L4_acceptor_t acceptor2)  _L4_remove_acceptor (_L4_acceptor_t acceptor1, _L4_acceptor_t acceptor2)
655  {  {
656    __L4_acceptor_t _acceptor1;    __L4_acceptor_t _acceptor1 = { .raw = acceptor1 };
657    __L4_acceptor_t _acceptor2;    __L4_acceptor_t _acceptor2 = { .raw = acceptor2 };
658    
   _acceptor1.raw = acceptor1;  
   _acceptor2.raw = acceptor2;  
659    _acceptor1.string_items &= ~_acceptor2.string_items;    _acceptor1.string_items &= ~_acceptor2.string_items;
660    if (_acceptor2.rcv_window)    if (_L4_has_map_grant_items (acceptor2))
661      _acceptor1.rcv_window = 0;      _acceptor1.rcv_window = 0;
662    return _acceptor1.raw;    return _acceptor1.raw;
663  }  }
# Line 547  static inline _L4_acceptor_t * Line 667  static inline _L4_acceptor_t *
667  _L4_attribute_always_inline  _L4_attribute_always_inline
668  _L4_remove_acceptor_from (_L4_acceptor_t *acceptor1, _L4_acceptor_t acceptor2)  _L4_remove_acceptor_from (_L4_acceptor_t *acceptor1, _L4_acceptor_t acceptor2)
669  {  {
670    __L4_acceptor_t *_acceptor1 = (__L4_acceptor_t *) acceptor1;    __L4_acceptor_t _acceptor1 = { .raw = *acceptor1 };
671    __L4_acceptor_t _acceptor2;    __L4_acceptor_t _acceptor2 = { .raw = acceptor2 };
672    
673    _acceptor2.raw = acceptor2;    _acceptor1.string_items &= ~_acceptor2.string_items;
674    _acceptor1->string_items &= ~_acceptor2.string_items;    if (_L4_has_map_grant_items (acceptor2))
675    if (_acceptor2.rcv_window)      _acceptor1.rcv_window = 0;
676      _acceptor1->rcv_window = 0;  
677      *acceptor1 = _acceptor1.raw;
678    return acceptor1;    return acceptor1;
679  }  }
680    
# Line 562  static inline _L4_word_t Line 683  static inline _L4_word_t
683  _L4_attribute_always_inline  _L4_attribute_always_inline
684  _L4_has_string_items (_L4_acceptor_t acceptor)  _L4_has_string_items (_L4_acceptor_t acceptor)
685  {  {
686    __L4_acceptor_t _acceptor;    __L4_acceptor_t _acceptor = { .raw = acceptor };
687    
   _acceptor.raw = acceptor;  
688    return _acceptor.string_items;    return _acceptor.string_items;
689  }  }
690    
691    
 static inline _L4_word_t  
 _L4_attribute_always_inline  
 _L4_has_map_grant_items (_L4_acceptor_t acceptor)  
 {  
   __L4_acceptor_t _acceptor;  
   
   _acceptor.raw = acceptor;  
   return _acceptor.rcv_window;  
 }  
   
   
 static inline _L4_fpage_t  
 _L4_attribute_always_inline  
 _L4_rcv_window (_L4_acceptor_t acceptor)  
 {  
   __L4_acceptor_t _acceptor;  
   
   _acceptor.raw = acceptor;  
   _acceptor.string_items = 0;  
   return (_L4_fpage_t) _acceptor.rcv_window;  
 }  
   
   
692  static inline void  static inline void
693  _L4_attribute_always_inline  _L4_attribute_always_inline
694  _L4_accept (_L4_acceptor_t acceptor)  _L4_accept (_L4_acceptor_t acceptor)
# Line 604  static inline void Line 701  static inline void
701  _L4_attribute_always_inline  _L4_attribute_always_inline
702  _L4_accept_strings (_L4_acceptor_t acceptor, _L4_msg_buffer_t msg_buffer)  _L4_accept_strings (_L4_acceptor_t acceptor, _L4_msg_buffer_t msg_buffer)
703  {  {
704      /* We do not break any strict aliasing rules here, as we only use
705         the pointers for pointer arithmetic.  */
706    __L4_string_item_t *string_item = (__L4_string_item_t *) msg_buffer;    __L4_string_item_t *string_item = (__L4_string_item_t *) msg_buffer;
707    int br = 1;    int count;
   int cont;  
708    
709    _L4_load_br (0, acceptor);    _L4_load_br (0, acceptor);
710    do  
711      {    /* We do not check if the message buffer is empty.  If the user
712        int nr = 1 + string_item->nr_substrings + 1;       accepts string items, he better adds at least one string item
713        cont = string_item->cont || string_item->not_last;       buffer.  In any case, if he doesn't, we will only add a harmless
714        _L4_load_brs (br, nr, (_L4_word_t *) string_item);       simple string item of length 0 with a random address.  */
715        br += nr;    count = _L4_string_item_words (string_item, 1);
716        string_item = (__L4_string_item_t *) (((_L4_word_t *) string_item) + nr);  
717      }    /* Load the string item buffers.  */
718    while (cont);    _L4_load_brs (1, count, msg_buffer);
719  }  }
720    
721    
# Line 636  _L4_attribute_always_inline Line 734  _L4_attribute_always_inline
734  _L4_msg_buffer_clear (_L4_msg_buffer_t msg_buffer)  _L4_msg_buffer_clear (_L4_msg_buffer_t msg_buffer)
735  {  {
736    msg_buffer[0] = 0;    msg_buffer[0] = 0;
737    
738      /* The first word being not 0 is a sufficient, but not necessary
739         indicator for a non-empty message buffer: A message with a simple
740         string item of length 0 can also have a first word 0 (depending
741         on the cache allocation hint).  The second word has only the
742         pointer address, which is arbitrary, so it can't be used for
743         differentiation either (0 is a valid pointer as far as L4 is
744         concerned).
745    
746         So, we use the third word as an indicator if the message buffer
747         is empty (in this case the first and the third word are 0), or if
748         there is a single simple string item of length 0 in it (in this
749         case the first word is 0, but the third word will be set to ~0 by
750         _L4_msg_buffer_prepare_append).
751    
752         In all other cases (simple string item with length not 0,
753         compound string items, more than one simple string item) the
754         first word will not be 0.
755    
756         All this boils down to a simple rule: If the first and the third
757         word are 0, then the message buffer is clear.  Otherwise, if at
758         least one of them is not 0, then the message buffer contains some
759         string items (you can determine how many by looking at the
760         continuation flags and substring numbers).  */
761      msg_buffer[2] = 0;
762  }  }
763    
764    
765  static inline void  /* Search for the end of the message buffer, and set the not_last bit
766       in the last existing item (thus preparing the message buffer for
767       adding a new item).  */
768    static inline __L4_string_item_t *
769  _L4_attribute_always_inline  _L4_attribute_always_inline
770  _L4_msg_buffer_append_simple_rcv_string (_L4_msg_buffer_t msg_buffer,  _L4_msg_buffer_prepare_append (_L4_msg_buffer_t msg_buffer)
                                          _L4_string_item_t string_item)  
771  {  {
772      /* We do not break any strict aliasing rules here, as we only use
773         the pointers for pointer arithmetic.  */
774    __L4_string_item_t *target = (__L4_string_item_t *) msg_buffer;    __L4_string_item_t *target = (__L4_string_item_t *) msg_buffer;
775    __L4_string_item_t _string_item;    int found_last = 0;
776    int cont;    int cont;
777    
778    _string_item.raw = string_item;    /* Check if this is an empty message buffer (see comment in
779         _L4_msg_buffer_clear).  */
780      if (msg_buffer[0] == 0 && msg_buffer[2] == 0)
781        {
782          /* It doesn't hurt to set the not-empty indicator here even if
783             we are not going to add a simple string item of length zero,
784             but something more complex.  */
785    
786          msg_buffer[2] = ~0;
787          return target;
788        }
789    
790      /* This is not an empty message buffer, so walk down the string
791         items.  */
792    do    do
793      {      {
794        int nr = 1 + target->nr_substrings + 1;        int nr = 1 + _L4_substrings (target);
795        cont = target->cont | target->not_last;        cont = _L4_compound_string (target);
796        if (!cont)  
797          target->not_last = 1;        /* Set the not_last bit in the last item.  */
798          if (!_L4_item_not_last (target))
799            {
800              _L4_set_item_not_last (target, 1);
801              found_last = 1;
802            }
803    
804          /* Skip over this item.  */
805        target = (__L4_string_item_t *) (((_L4_word_t *) target) + nr);        target = (__L4_string_item_t *) (((_L4_word_t *) target) + nr);
806      }      }
807    while (cont);    while (!found_last || cont);
808    
809      return target;
810    }
811    
812    
813    static inline void
814    _L4_attribute_always_inline
815    _L4_msg_buffer_append_simple_rcv_string (_L4_msg_buffer_t msg_buffer,
816                                             _L4_string_item_t string_item)
817    {
818      __L4_string_item_t *target;
819      __L4_string_item_t _string_item = { .raw = string_item };
820    
821    _string_item.not_last = 0;    _string_item.not_last = 0;
822    _string_item.nr_substrings = 0;    _string_item.nr_substrings = 0;
823    *target = _string_item;  
824      target = _L4_msg_buffer_prepare_append (msg_buffer);
825      __builtin_memcpy (target, &_string_item, sizeof (__L4_string_item_t));
826  }  }
827    
828    
829  static inline void  static inline void
830  _L4_attribute_always_inline  _L4_attribute_always_inline
831  _L4_msg_buffer_append_rcv_string (_L4_msg_buffer_t msg_buffer,  _L4_msg_buffer_append_rcv_string (_L4_msg_buffer_t msg_buffer,
832                                    _L4_string_item_t *string_item)                                    void *string_item)
833  {  {
834    __L4_string_item_t *target = (__L4_string_item_t *) msg_buffer;    /* We do not break any strict aliasing rules here, as we only use
835         the pointers for pointer arithmetic.  */
836      __L4_string_item_t *target;
837    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;
   _L4_word_t *brp;  
838    int cont;    int cont;
839    
840    /* Find the end of the message buffer.  */    target = _L4_msg_buffer_prepare_append (msg_buffer);
841    do    __builtin_memcpy (target, &_string_item, sizeof (__L4_string_item_t));
     {  
       int nr = 1 + target->nr_substrings + 1;  
       cont = target->cont | target->not_last;  
       if (!cont)  
         target->not_last = 1;  
       target = (__L4_string_item_t *) (((_L4_word_t *) target) + nr);  
     }  
   while (cont);  
842    
843    brp = (_L4_word_t *) target;    _L4_set_item_not_last (_string_item, 0);
844    
845    /* Copy the source string.  */    /* Copy the source string.  */
846    do    do
847      {      {
848        int nr = _string_item->nr_substrings;        int nr = _L4_substrings (_string_item) + 1;
849        _L4_word_t *substrings = &_string_item->string[1];        cont = _L4_compound_string (_string_item);
850          
       cont = _string_item->cont;  
       *((__L4_string_item_t *) brp) = *_string_item;  
       brp += 2;  
   
851        while (nr-- > 0)        while (nr-- > 0)
852          *(brp++) = *(substrings++);          {
853        _string_item = (__L4_string_item_t *) substrings;            __builtin_memcpy (target, _string_item, sizeof (_L4_word_t));
854    
855              target = (__L4_string_item_t *) (((_L4_word_t *) target) + 1);
856              _string_item = (__L4_string_item_t *)
857                (((_L4_word_t *) _string_item) + 1);
858            }
859      }      }
860    while (cont);    while (cont);
861  }  }
# Line 709  _L4_msg_buffer_append_rcv_string (_L4_ms Line 863  _L4_msg_buffer_append_rcv_string (_L4_ms
863    
864  /* Message composition.  */  /* Message composition.  */
865  typedef _L4_word_t _L4_msg_t[_L4_NUM_MRS];  typedef _L4_word_t _L4_msg_t[_L4_NUM_MRS];
866  typedef union  
867    
868    static inline _L4_msg_tag_t
869    _L4_attribute_always_inline
870    _L4_msg_msg_tag (_L4_msg_t msg)
871  {  {
872    _L4_msg_t _msg;    return msg[0];
873    __L4_msg_tag_t tag;  }
874  } __L4_msg_t;  
875    
876    static inline void
877    _L4_attribute_always_inline
878    _L4_set_msg_msg_tag (_L4_msg_t msg, _L4_msg_tag_t tag)
879    {
880      msg[0] = tag;
881    }
882    
883    
884  static inline void  static inline void
# Line 721  _L4_attribute_always_inline Line 886  _L4_attribute_always_inline
886  _L4_msg_put (_L4_msg_t msg, _L4_word_t label, int untyped_nr,  _L4_msg_put (_L4_msg_t msg, _L4_word_t label, int untyped_nr,
887               _L4_word_t *untyped, int typed_nr, void *any_typed)               _L4_word_t *untyped, int typed_nr, void *any_typed)
888  {  {
889    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag;
890    _L4_word_t *mrs = msg;    _L4_word_t *mrs = &msg[1];
891    _L4_word_t *typed = (_L4_word_t *) any_typed;  
892      tag.untyped = untyped_nr;
893    _msg->tag.untyped = untyped_nr;    tag.typed = typed_nr;
894    _msg->tag.typed = typed_nr;    tag.propagated = 0;
895    _msg->tag.propagated = 0;    tag.redirected = 0;
896    _msg->tag.redirected = 0;    tag.cross_cpu = 0;
897    _msg->tag.cross_cpu = 0;    tag.error = 0;
898    _msg->tag.error = 0;    tag.label = label;
899    _msg->tag.label = label;    _L4_set_msg_msg_tag (msg, tag.raw);
900    
901    while (untyped_nr--)    while (untyped_nr--)
902      *(mrs++) = *(untyped++);      *(mrs++) = *(untyped++);
903    
904      /* We can't cast ANY_TYPED to anything useful and dereference it, as
905         that would break strict aliasing rules.  This is why we use
906         __builtin_memcpy, but only for known, small, fixed sizes, so that it is
907         optimized away.  We know that sizeof (_L4_word_t) == sizeof (void *).  */
908    while (typed_nr--)    while (typed_nr--)
909      *(mrs++) = *(typed++);      __builtin_memcpy (mrs++, any_typed++, sizeof (void *));
910  }  }
911    
912    
# Line 745  static inline void Line 914  static inline void
914  _L4_attribute_always_inline  _L4_attribute_always_inline
915  _L4_msg_get (_L4_msg_t msg, _L4_word_t *untyped, void *any_typed)  _L4_msg_get (_L4_msg_t msg, _L4_word_t *untyped, void *any_typed)
916  {  {
917    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
918    int untyped_nr = _msg->tag.untyped;    int untyped_nr = tag.untyped;
919    int typed_nr = _msg->tag.typed;    int typed_nr = tag.typed;
920    _L4_word_t *mrs = msg;    _L4_word_t *mrs = &msg[1];
   _L4_word_t *typed = (_L4_word_t *) any_typed;  
921    
922    while (untyped_nr--)    while (untyped_nr--)
923      *(untyped++) = *(mrs++);      *(untyped++) = *(mrs++);
924    
925      /* We can't cast ANY_TYPED to anything useful and dereference it, as
926         that would break strict aliasing rules.  This is why we use
927         __builtin_memcpy, but only for known, small, fixed sizes, so that it is
928         optimized away.  We know that sizeof (_L4_word_t) == sizeof (void *).  */
929    while (typed_nr--)    while (typed_nr--)
930      *(typed++) = *(mrs++);      __builtin_memcpy (any_typed++, mrs++, sizeof (_L4_word_t));
 }  
   
   
 static inline _L4_msg_tag_t  
 _L4_attribute_always_inline  
 _L4_msg_msg_tag (_L4_msg_t msg)  
 {  
   __L4_msg_t *_msg = (__L4_msg_t *) msg;  
   return _msg->tag.raw;  
 }  
   
   
 static inline void  
 _L4_attribute_always_inline  
 _L4_set_msg_msg_tag (_L4_msg_t msg, _L4_msg_tag_t tag)  
 {  
   __L4_msg_t *_msg = (__L4_msg_t *) msg;  
   _msg->tag.raw = tag;  
931  }  }
932    
933    
# Line 781  static inline _L4_word_t Line 935  static inline _L4_word_t
935  _L4_attribute_always_inline  _L4_attribute_always_inline
936  _L4_msg_msg_label (_L4_msg_t msg)  _L4_msg_msg_label (_L4_msg_t msg)
937  {  {
938    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
939    return _msg->tag.label;    return tag.label;
940  }  }
941    
942    
# Line 790  static inline void Line 944  static inline void
944  _L4_attribute_always_inline  _L4_attribute_always_inline
945  _L4_set_msg_msg_label (_L4_msg_t msg, _L4_word_t label)  _L4_set_msg_msg_label (_L4_msg_t msg, _L4_word_t label)
946  {  {
947    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
948    _msg->tag.label = label;    tag.label = label;
949      _L4_set_msg_msg_tag (msg, tag.raw);
950  }  }
951    
952    
# Line 799  static inline void Line 954  static inline void
954  _L4_attribute_always_inline  _L4_attribute_always_inline
955  _L4_msg_load (_L4_msg_t msg)  _L4_msg_load (_L4_msg_t msg)
956  {  {
957    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
958    _L4_load_mrs (0, 1 + _msg->tag.untyped + _msg->tag.typed, msg);    _L4_load_mrs (0, 1 + tag.untyped + tag.typed, msg);
959  }  }
960    
961    
# Line 808  static inline void Line 963  static inline void
963  _L4_attribute_always_inline  _L4_attribute_always_inline
964  _L4_msg_store (_L4_msg_tag_t tag, _L4_msg_t msg)  _L4_msg_store (_L4_msg_tag_t tag, _L4_msg_t msg)
965  {  {
966    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t _tag = { .raw = tag };
967    _msg->tag.raw = tag;    _L4_set_msg_msg_tag (msg, tag);
968    _L4_store_mrs (1, _msg->tag.untyped + _msg->tag.typed, &msg[1]);    _L4_store_mrs (1, _tag.untyped + _tag.typed, &msg[1]);
969  }  }
970    
971    
# Line 818  static inline void Line 973  static inline void
973  _L4_attribute_always_inline  _L4_attribute_always_inline
974  _L4_msg_clear (_L4_msg_t msg)  _L4_msg_clear (_L4_msg_t msg)
975  {  {
976    __L4_msg_t *_msg = (__L4_msg_t *) msg;    _L4_set_msg_msg_tag (msg, _L4_niltag);
   _msg->tag.raw = _L4_niltag;  
977  }  }
978    
979    
# Line 827  static inline void Line 981  static inline void
981  _L4_attribute_always_inline  _L4_attribute_always_inline
982  _L4_msg_append_word (_L4_msg_t msg, _L4_word_t data)  _L4_msg_append_word (_L4_msg_t msg, _L4_word_t data)
983  {  {
984    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
985    _L4_word_t new_untyped_nr = ++_msg->tag.untyped;    _L4_word_t untyped_nr;
986    _L4_word_t typed_nr = _msg->tag.typed;    _L4_word_t typed_nr;
987    
988    if (typed_nr)    untyped_nr = tag.untyped;
989      {    typed_nr = tag.typed;
990        _L4_word_t *mrs = &msg[new_untyped_nr + typed_nr];  
991        while (typed_nr--)    while (typed_nr)
992          {      __builtin_memcpy (&msg[untyped_nr + typed_nr + 1], &msg[untyped_nr + typed_nr],
993            *(mrs) = *(mrs - 1);              sizeof (_L4_word_t));
994            mrs--;  
995          }    tag.untyped++;
996        *mrs = data;    msg[tag.untyped] = data;
997      }    _L4_set_msg_msg_tag (msg, tag.raw);
   else  
     msg[new_untyped_nr] = data;  
998  }  }
999    
1000    
# Line 850  static inline void Line 1002  static inline void
1002  _L4_attribute_always_inline  _L4_attribute_always_inline
1003  _L4_msg_append_map_item (_L4_msg_t msg, _L4_map_item_t map_item)  _L4_msg_append_map_item (_L4_msg_t msg, _L4_map_item_t map_item)
1004  {  {
1005    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1006    /* The "not last" bit is ignored for sending.  */    /* The "not last" bit is ignored for sending.  */
1007    int pos = 1 + _msg->tag.untyped + _msg->tag.typed;    int pos = 1 + tag.untyped + tag.typed;
1008    
1009    ((__L4_map_item_t *) &msg[pos])->raw = map_item;    __builtin_memcpy (&msg[pos], &map_item, sizeof (_L4_map_item_t));
1010    _msg->tag.typed += 2;    tag.typed += sizeof (_L4_map_item_t) / sizeof (_L4_word_t);
1011      _L4_set_msg_msg_tag (msg, tag.raw);
1012  }  }
1013    
1014    
# Line 863  static inline void Line 1016  static inline void
1016  _L4_attribute_always_inline  _L4_attribute_always_inline
1017  _L4_msg_append_grant_item (_L4_msg_t msg, _L4_grant_item_t grant_item)  _L4_msg_append_grant_item (_L4_msg_t msg, _L4_grant_item_t grant_item)
1018  {  {
1019    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1020    /* The "not last" bit is ignored for sending.  */    /* The "not last" bit is ignored for sending.  */
1021    int pos = 1 + _msg->tag.untyped + _msg->tag.typed;    int pos = 1 + tag.untyped + tag.typed;
1022    
1023    ((__L4_grant_item_t *) &msg[pos])->raw = grant_item;    __builtin_memcpy (&msg[pos], &grant_item, sizeof (_L4_grant_item_t));
1024    _msg->tag.typed += 2;    tag.typed += sizeof (_L4_grant_item_t) / sizeof (_L4_word_t);
1025      _L4_set_msg_msg_tag (msg, tag.raw);
1026  }  }
1027            
1028        
# Line 877  _L4_attribute_always_inline Line 1031  _L4_attribute_always_inline
1031  _L4_msg_append_simple_string_item (_L4_msg_t msg,  _L4_msg_append_simple_string_item (_L4_msg_t msg,
1032                                     _L4_string_item_t string_item)                                     _L4_string_item_t string_item)
1033  {  {
1034    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1035    __L4_string_item_t _string_item;    __L4_string_item_t _string_item = { .raw = string_item };
1036    /* The "not last" bit is ignored for sending.  */    /* The "not last" bit is ignored for sending.  */
1037    int pos = 1 + _msg->tag.untyped + _msg->tag.typed;    int pos = 1 + tag.untyped + tag.typed;
1038    
1039    _string_item.raw = string_item;    _string_item.raw = string_item;
1040    _string_item.cont = 0;    _string_item.cont = 0;
1041    _string_item.nr_substrings = 0;    _string_item.nr_substrings = 0;
1042    
1043    ((__L4_string_item_t *) &msg[pos])->raw = string_item;    __builtin_memcpy (&msg[pos], &_string_item, sizeof (__L4_string_item_t));
1044    _msg->tag.typed += 2;    tag.typed += sizeof (_L4_string_item_t) / sizeof (_L4_word_t);
1045      _L4_set_msg_msg_tag (msg, tag.raw);
1046  }  }
1047            
1048        
1049  static inline void  static inline void
1050  _L4_attribute_always_inline  _L4_attribute_always_inline
1051  _L4_msg_append_string_item (_L4_msg_t msg, _L4_string_item_t *string_item)  _L4_msg_append_string_item (_L4_msg_t msg, void *string_item)
1052  {  {
1053    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1054      /* We do not break any strict aliasing rules here, as we only use
1055         the pointers for pointer arithmetic.  */
1056    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;
1057    /* The "not last" bit is ignored for sending.  */    /* The "not last" bit is ignored for sending.  */
1058    int pos = 1 + _msg->tag.untyped + _msg->tag.typed;    int pos = 1 + tag.untyped + tag.typed;
1059    int cont;    int count;
1060    
1061    do    count = _L4_string_item_words (_string_item, 0);
1062      tag.typed += count;
1063      while (count--)
1064      {      {
1065        int nr = _string_item->nr_substrings;        __builtin_memcpy (&msg[pos++], _string_item, sizeof (_L4_word_t));
1066        _L4_word_t *substrings = &_string_item->string[1];        _string_item = (__L4_string_item_t *)
1067            (((_L4_word_t *) _string_item) + 1);
       cont = _string_item->cont;  
       msg[pos++] = _string_item->mr[0];  
       msg[pos++] = _string_item->mr[1];  
   
       while (nr-- > 0)  
         msg[pos++] = *(substrings++);  
       _string_item = (__L4_string_item_t *) substrings;  
1068      }      }
1069    while (cont);    _L4_set_msg_msg_tag (msg, tag.raw);
   
   _msg->tag.typed += pos - 1 - _msg->tag.untyped;  
1070  }  }
1071    
1072    
# Line 932  static inline void Line 1082  static inline void
1082  _L4_attribute_always_inline  _L4_attribute_always_inline
1083  _L4_msg_put_map_item (_L4_msg_t msg, _L4_word_t nr, _L4_map_item_t map_item)  _L4_msg_put_map_item (_L4_msg_t msg, _L4_word_t nr, _L4_map_item_t map_item)
1084  {  {
1085    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1086    _L4_word_t pos = 1 + _msg->tag.untyped + nr;    _L4_word_t pos = 1 + tag.untyped + nr;
1087    
1088    ((__L4_map_item_t *) &msg[pos])->raw = map_item;    __builtin_memcpy (&msg[pos], &map_item, sizeof (_L4_map_item_t));
1089  }  }
1090    
1091    
# Line 944  _L4_attribute_always_inline Line 1094  _L4_attribute_always_inline
1094  _L4_msg_put_grant_item (_L4_msg_t msg, _L4_word_t nr,  _L4_msg_put_grant_item (_L4_msg_t msg, _L4_word_t nr,
1095                          _L4_grant_item_t grant_item)                          _L4_grant_item_t grant_item)
1096  {  {
1097    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1098    _L4_word_t pos = 1 + _msg->tag.untyped + nr;    _L4_word_t pos = 1 + tag.untyped + nr;
1099    
1100    ((__L4_grant_item_t *) &msg[pos])->raw = grant_item;    __builtin_memcpy (&msg[pos], &grant_item, sizeof (_L4_grant_item_t));
1101  }  }
1102    
1103    
# Line 956  _L4_attribute_always_inline Line 1106  _L4_attribute_always_inline
1106  _L4_msg_put_simple_string_item (_L4_msg_t msg, _L4_word_t nr,  _L4_msg_put_simple_string_item (_L4_msg_t msg, _L4_word_t nr,
1107                                  _L4_string_item_t string_item)                                  _L4_string_item_t string_item)
1108  {  {
1109    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1110    __L4_string_item_t _string_item;    _L4_word_t pos = 1 + tag.untyped + nr;
1111    _L4_word_t pos = 1 + _msg->tag.untyped + nr;    __L4_string_item_t _string_item = { .raw = string_item };
1112    
   _string_item.raw = string_item;  
1113    _string_item.cont = 0;    _string_item.cont = 0;
1114    _string_item.nr_substrings = 0;    _string_item.nr_substrings = 0;
1115    
1116    ((__L4_string_item_t *) &msg[pos])->raw = string_item;    __builtin_memcpy (&msg[pos], &_string_item, sizeof (__L4_string_item_t));
1117  }  }
1118    
1119    
1120  static inline void  static inline void
1121  _L4_attribute_always_inline  _L4_attribute_always_inline
1122  _L4_msg_put_string_item (_L4_msg_t msg, _L4_word_t nr,  _L4_msg_put_string_item (_L4_msg_t msg, _L4_word_t nr, void *string_item)
                          _L4_string_item_t *string_item)  
1123  {  {
1124    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1125      /* We do not break any strict aliasing rules here, as we only use
1126         the pointers for pointer arithmetic.  */
1127    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;
1128    _L4_word_t pos = 1 + _msg->tag.untyped + nr;    _L4_word_t pos = 1 + tag.untyped + nr;
1129    int cont;    int count;
1130    
1131    do    count = _L4_string_item_words (_string_item, 0);
1132      while (count--)
1133      {      {
1134        int nr = _string_item->nr_substrings;        __builtin_memcpy (&msg[pos++], _string_item, sizeof (_L4_word_t));
1135        _L4_word_t *substrings = &_string_item->string[1];        _string_item = (__L4_string_item_t *)
1136            (((_L4_word_t *) _string_item) + 1);
       cont = _string_item->cont;  
       msg[pos++] = _string_item->mr[0];  
       msg[pos++] = _string_item->mr[1];  
   
       while (nr-- > 0)  
         msg[pos++] = *(substrings++);  
       _string_item = (__L4_string_item_t *) substrings;  
1137      }      }
   while (cont);  
1138  }  }
1139    
1140    
# Line 1015  static inline _L4_word_t Line 1158  static inline _L4_word_t
1158  _L4_attribute_always_inline  _L4_attribute_always_inline
1159  _L4_msg_get_map_item (_L4_msg_t msg, _L4_word_t nr, _L4_map_item_t *map_item)  _L4_msg_get_map_item (_L4_msg_t msg, _L4_word_t nr, _L4_map_item_t *map_item)
1160  {  {
1161    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1162    _L4_word_t pos = 1 + _msg->tag.untyped + nr;    _L4_word_t pos = 1 + tag.untyped + nr;
1163    
1164    *map_item = ((__L4_map_item_t *) &msg[pos])->raw;    __builtin_memcpy (map_item, &msg[pos], sizeof (_L4_map_item_t));
1165    return sizeof (_L4_map_item_t) / sizeof (_L4_word_t);    return sizeof (_L4_map_item_t) / sizeof (_L4_word_t);
1166  }  }
1167    
# Line 1028  _L4_attribute_always_inline Line 1171  _L4_attribute_always_inline
1171  _L4_msg_get_grant_item (_L4_msg_t msg, _L4_word_t nr,  _L4_msg_get_grant_item (_L4_msg_t msg, _L4_word_t nr,
1172                          _L4_grant_item_t *grant_item)                          _L4_grant_item_t *grant_item)
1173  {  {
1174    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1175    _L4_word_t pos = 1 + _msg->tag.untyped + nr;    _L4_word_t pos = 1 + tag.untyped + nr;
1176    
1177    *grant_item = ((__L4_grant_item_t *) &msg[pos])->raw;    __builtin_memcpy (grant_item, &msg[pos], sizeof (_L4_grant_item_t));
1178    return sizeof (_L4_grant_item_t) / sizeof (_L4_word_t);    return sizeof (_L4_grant_item_t) / sizeof (_L4_word_t);
1179  }  }
1180    
1181    
1182  static inline _L4_word_t  static inline _L4_word_t
1183  _L4_attribute_always_inline  _L4_attribute_always_inline
1184  _L4_msg_get_string_item (_L4_msg_t msg, _L4_word_t nr,  _L4_msg_get_string_item (_L4_msg_t msg, _L4_word_t nr, void *string_item)
                          _L4_string_item_t *string_item)  
1185  {  {
1186    __L4_msg_t *_msg = (__L4_msg_t *) msg;    __L4_msg_tag_t tag = { .raw = _L4_msg_msg_tag (msg) };
1187    __L4_string_item_t *_string_item = (__L4_string_item_t *) string_item;    /* We do not break any strict aliasing rules here, as we only use
1188    _L4_word_t pos = 1 + _msg->tag.untyped + nr;       the pointers for pointer arithmetic.  */
1189    int cont;    _L4_word_t pos = 1 + tag.untyped + nr;
1190      __L4_string_item_t *_string_item = (__L4_string_item_t *) &msg[pos];
1191    do    int count;
1192      int i;
1193    
1194      count = _L4_string_item_words (_string_item, 0);
1195      i = count;
1196      while (i--)
1197      {      {
1198        int nr = _string_item->nr_substrings;        __builtin_memcpy (_string_item, &msg[pos++], sizeof (_L4_word_t));
1199        _L4_word_t *substrings = &_string_item->string[1];        _string_item = (__L4_string_item_t *)
1200            (((_L4_word_t *) _string_item) + 1);
       cont = _string_item->cont;  
       *((__L4_string_item_t *) &msg[pos]) = *_string_item;  
       pos += 2;  
   
       while (nr-- > 0)  
         *(substrings++) = msg[pos++];  
       _string_item = (__L4_string_item_t *) substrings;  
1201      }      }
1202    while (cont);    return count;
   
   return ((_L4_word_t *) _string_item) - ((_L4_word_t *) string_item);  
1203  }  }
1204    
1205    
1206  /* l4_ipc convenience interface.  */  /* _L4_ipc convenience interface.  */
1207    
1208  static inline _L4_word_t  static inline _L4_word_t
1209  _L4_attribute_always_inline  _L4_attribute_always_inline
# Line 1204  static inline _L4_word_t Line 1342  static inline _L4_word_t
1342  _L4_attribute_always_inline  _L4_attribute_always_inline
1343  _L4_ipc_succeeded (_L4_msg_tag_t tag)  _L4_ipc_succeeded (_L4_msg_tag_t tag)
1344  {  {
1345    __L4_msg_tag_t _tag;    __L4_msg_tag_t _tag = { .raw = tag };
1346    
   _tag.raw = tag;  
1347    return !_tag.error;    return !_tag.error;
1348  }  }
1349    
# Line 1215  static inline _L4_word_t Line 1352  static inline _L4_word_t
1352  _L4_attribute_always_inline  _L4_attribute_always_inline
1353  _L4_ipc_failed (_L4_msg_tag_t tag)  _L4_ipc_failed (_L4_msg_tag_t tag)
1354  {  {
1355    __L4_msg_tag_t _tag;    __L4_msg_tag_t _tag = { .raw = tag };
1356    
   _tag.raw = tag;  
1357    return _tag.error;    return _tag.error;
1358  }  }
1359    
# Line 1226  static inline _L4_word_t Line 1362  static inline _L4_word_t
1362  _L4_attribute_always_inline  _L4_attribute_always_inline
1363  _L4_ipc_propagated (_L4_msg_tag_t tag)  _L4_ipc_propagated (_L4_msg_tag_t tag)
1364  {  {
1365    __L4_msg_tag_t _tag;    __L4_msg_tag_t _tag = { .raw = tag };
1366    
   _tag.raw = tag;  
1367    return _tag.propagated;    return _tag.propagated;
1368  }  }
1369    
# Line 1237  static inline _L4_word_t Line 1372  static inline _L4_word_t
1372  _L4_attribute_always_inline  _L4_attribute_always_inline
1373  _L4_ipc_redirected (_L4_msg_tag_t tag)  _L4_ipc_redirected (_L4_msg_tag_t tag)
1374  {  {
1375    __L4_msg_tag_t _tag;    __L4_msg_tag_t _tag = { .raw = tag };
1376    
   _tag.raw = tag;  
1377    return _tag.redirected;    return _tag.redirected;
1378  }  }
1379    
# Line 1248  static inline _L4_word_t Line 1382  static inline _L4_word_t
1382  _L4_attribute_always_inline  _L4_attribute_always_inline
1383  _L4_ipc_xcpu (_L4_msg_tag_t tag)  _L4_ipc_xcpu (_L4_msg_tag_t tag)
1384  {  {
1385    __L4_msg_tag_t _tag;    __L4_msg_tag_t _tag = { .raw = tag };
1386    
   _tag.raw = tag;  
1387    return _tag.cross_cpu;    return _tag.cross_cpu;
1388  }  }
1389    
# Line 1259  static inline void Line 1392  static inline void
1392  _L4_attribute_always_inline  _L4_attribute_always_inline
1393  _L4_set_propagation (_L4_msg_tag_t *tag)  _L4_set_propagation (_L4_msg_tag_t *tag)
1394  {  {
1395    __L4_msg_tag_t *_tag = (__L4_msg_tag_t *) tag;    __L4_msg_tag_t _tag = { .raw = *tag };
1396    
1397      _tag.propagated = 1;
1398    
1399    _tag->propagated = 1;    *tag = _tag.raw;
1400  }  }
1401    
1402    
# Line 1269  static inline void Line 1404  static inline void
1404  _L4_attribute_always_inline  _L4_attribute_always_inline
1405  _L4_clear_propagation (_L4_msg_tag_t *tag)  _L4_clear_propagation (_L4_msg_tag_t *tag)
1406  {  {
1407    __L4_msg_tag_t *_tag = (__L4_msg_tag_t *) tag;    __L4_msg_tag_t _tag = { .raw = *tag };
1408    
1409      _tag.propagated = 0;
1410    
1411    _tag->propagated = 0;    *tag = _tag.raw;
1412  }  }
1413    
1414    

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26