librelist archives

« back to archive

uint32 queues parameters and indexes

uint32 queues parameters and indexes

From:
Pascal Sclafer
Date:
2014-02-10 @ 02:14
Thank you for your project. I use it successfully for my professional 
activities and it works very well.

Today, I was looking for bottlenecks in one of my program, and I found 
that you use int32 integers in the AtomQueue module.

typedef struct atom_queue
{
     ATOM_TCB *  putSuspQ;       /* Queue of threads waiting to send */
     ATOM_TCB *  getSuspQ;       /* Queue of threads waiting to receive */
     uint8_t *   buff_ptr;       /* Pointer to queue data area */
     uint32_t    unit_size;      /* Size of each message */
     uint32_t    max_num_msgs;   /* Max number of storable messages */
     uint32_t    insert_index;   /* Next byte index to insert into */
     uint32_t    remove_index;   /* Next byte index to remove from */
     uint32_t    num_msgs_stored;/* Number of messages stored */
} ATOM_QUEUE;


Atomthreads is designed to work with very small micro-controllers.

32 bits integers are slow to compute, and can take a lot of memory 
resources (stack). For example, there is in "queue_insert" a 
uint32*uint32 multiplication, and 32 bits multiplications are a pain in 
the ass on a 8bit micro-controller.

Moreover, on small micro controllers, there is often less than 4kb 
memory. That's why  using a 32 bits integer for a queue length is pretty 
unuseful.


Is there a reason for using 32 bits integers that I've not understood?


I think that the queues should be modified as below:

typedef struct atom_queue
{
     ATOM_TCB *  putSuspQ;       /* Queue of threads waiting to send */
     ATOM_TCB *  getSuspQ;       /* Queue of threads waiting to receive */
     uint8_t *   buff_ptr;       /* Pointer to queue data area */
     uint8_t    unit_size;      /* Size of each message */
     uint8_t    max_num_msgs;   /* Max number of storable messages */
     uint16_t    insert_index;   /* Next byte index to insert into */
     uint16_t    remove_index;   /* Next byte index to remove from */
     uint8_t    num_msgs_stored;/* Number of messages stored */
} ATOM_QUEUE;

extern uint8_t atomQueueCreate (ATOM_QUEUE *qptr, uint8_t *buff_ptr, 
uint8_t unit_size, uint8_t max_num_msgs);
extern uint8_t atomQueueDelete (ATOM_QUEUE *qptr);
extern uint8_t atomQueueGet (ATOM_QUEUE *qptr, int32_t timeout, uint8_t 
*msgptr);
extern uint8_t atomQueuePut (ATOM_QUEUE *qptr, int32_t timeout, uint8_t 
*msgptr);


It makes a big difference in terms of code size, code speed and stack usage.


Best regards,

Pascal




Re: [atomthreads] uint32 queues parameters and indexes

From:
Kelvin Lawson
Date:
2014-02-14 @ 00:52
Hi Pascal,

Thank you for your project. I use it successfully for my professional
> activities and it works very well.
>

Very glad to hear it, thanks for getting in touch.


> Today, I was looking for bottlenecks in one of my program, and I found
> that you use int32 integers in the AtomQueue module.
>
> typedef struct atom_queue
> {
>     ATOM_TCB *  putSuspQ;       /* Queue of threads waiting to send */
>     ATOM_TCB *  getSuspQ;       /* Queue of threads waiting to receive */
>     uint8_t *   buff_ptr;       /* Pointer to queue data area */
>     uint32_t    unit_size;      /* Size of each message */
>     uint32_t    max_num_msgs;   /* Max number of storable messages */
>     uint32_t    insert_index;   /* Next byte index to insert into */
>     uint32_t    remove_index;   /* Next byte index to remove from */
>     uint32_t    num_msgs_stored;/* Number of messages stored */
> } ATOM_QUEUE;
>
> Atomthreads is designed to work with very small micro-controllers.
>

Although most ports are for small micro-controllers, and it is intended to
be lightweight, it is also intended to be highly portable and a universal
RTOS for many different platforms. I frequently use queues with message
sizes larger than 255 bytes, as well as queues with more than 255 entries.

Perhaps what we need here is conditional compilation or macros/typedefs to
allow reduced memory builds on 8-bit platforms as well as more flexible
sizing on larger processors. The only thing that puts me off from
committing this to the codebase is that (at least conditional compilation
within the structure definition) tends to reduce readability and make the
code look more complex. Macros/typedefs that affect the types used for
queue size etc would probably be neater than that. I'm happy to look
through any pull requests that introduce a tidy way of sizing flexibly.

Best regards,
Kelvin.