Bits
====

This module provides helper functions allowing compound synchronizations based 
on AND/ORs on a 32bits unsigned long. In other OSes similar objects are often 
referred as flags/events. Their use is similar to that of semaphores except 
that signal/waits are not related just to a simple counter but depends on a 
combinations of bits set.

Test operations provided:

Single tests:
#define ALL_SET: test if an entire mask is set
#define ANY_SET: test if any entry of a mask is set
#define ALL_CLR: test if an entire mask is cleared
#define ANY_CLR: test if any entry of a mask is cleared

Combined tests (meaning easily inferred from macros names):
#define ALL_SET_AND_ANY_SET 
#define ALL_SET_AND_ALL_CLR 
#define ALL_SET_AND_ANY_CLR
#define ANY_SET_AND_ALL_CLR
#define ANY_SET_AND_ANY_CLR
#define ALL_CLR_AND_ANY_CLR
#define ALL_SET_OR_ANY_SET
#define ALL_SET_OR_ALL_CLR
#define ALL_SET_OR_ANY_CLR
#define ANY_SET_OR_ALL_CLR
#define ANY_SET_OR_ANY_CLR
#define ALL_CLR_OR_ANY_CLR

Bit operations provided:

#define SET_BITS:     set bits according to the given mask
#define CLR_BITS:     clear bits according to the given mask 
#define SET_CLR_BITS: combined operation
#define NOP_BITS:     do nothing

Services provided:

struct rt_bits_struct {
	struct rt_queue queue;  // must be first in struct
	int magic;
	int type;  // to align mask to semaphore count, for easier uspace init
	unsigned long mask;
};

typedef struct rt_bits_struct BITS;

To be noticed. The int variable type above is inserted to keep
rt_bits_struct aligned with the initial part of SEM, to ease use in user
space. For the same reason BITS_MAGIC and error returns are also the same
as those of SEM.  Not so strange, bits code and APIs are very similar to
those of semaphores.

#include <rtai_bits.h>

- void rt_bits_init(BITS *bits, unsigned long mask) 
  create and initialize the bits structure pointed by bits support
  structure, setting bits mask to mask.

- int rt_bits_delete(BITS *bits)  
  delete bits; returns: BITS_ERR if bits has already been deleted, 0 if OK.

- unsigned long rt_get_bits(BITS *bits)
  get the actual value of bits mask.

- unsigned long rt_bits_signal(BITS *bits, int setfun, unsigned long masks)
  execute setfun, any bits operation above, or/anding masks onto the actual bits 
  mask, schedule any task blocked on bits if the new bits mask meets its request;
  returns the value of bits after executing setfun; in case of combined operations
  masks is to be cast to a pointer of a two elements array of unsigned longs 
  containing the masks to be used for the combined setfun used.

- int rt_bits_reset(BITS *bits, unsigned long mask)
  unconditionally schedule any task blocked on bits and reset its mask to mask;
  returns the value of bits mask before being reset to mask.

- int rt_bits_wait(BITS *bits, int testfun, unsigned long testmasks, int exitfun, unsigned long exitmasks, unsigned long *resulting_mask)
  test bits mask against testmasks according to testfun, any of the test funs
  above, if the test is not satisfied block the task; whenever the condition is 
  met execute exitfun, any bits operation above, using exitmasks, save the
  the mask resulting after the whole processing in the variable pointed by
  resulting_mask; returns: BITS_ERR if the task was blocked and resumed because 
  bits was deleted, 0 if OK; in case of combined operations testmasks and/or 
  exitmasks are to be cast to pointers of two elements arrays of unsigned 
  longs containing the masks to be used for the combined tests/executions.

- int rt_bits_wait_if(BITS *bits, int testfun, unsigned long testmasks, int exitfun, unsigned long exitmasks, unsigned long *resulting_mask) 
  as rt_bits_wait but does not block if testfun is not satisfied; returns 1 if 
  it succeeded, 0 if it failed.

- int rt_bits_wait_until(BITS *bits, int testfun, unsigned long testmasks, int exitfun, unsigned long exitmasks, RTIME time, unsigned long *resulting_mask)
  as rt_bits_wait but waits at most till time expires; returns the same values 
  also, BITS_TIMOUT if the task blocked and has been resumed because a timeout 
  occured.

- unsigned long rt_bits_wait_timed(BITS *bits, int testfun, unsigned long testmasks, int exitfun, unsigned long exitmasks, RTIME delay, unsigned long *resulting_mask)
  as rt_bits_wait_until but waits at most for delay to meet the required 
  condition.

As usual, comments and bug fixes are welcomed.

Paolo Mantegazza (mantegazza@aero.polimi.it)
