In versions 4 and 5 of the C-library, approximately half the routines were reentrant. What is the current status? Will some functions ( such as the memory allocation routines ) never be reentrant? [Note: I know I can bracket non-reentrant routines with a semaphore.]
I'm wondering how malloc() could ever be reentrant. Since the system must keep global status about total memory and that which has been allocated and to which pointers; it is non-reentrant by definition. I'm interested to know how this could be done reentrantly. Maybe I'm just being dense today (not an uncommon thing). - Mark
Thanks for your reply Mark. Yes, as I thought about it, "how can malloc ever be reentrant?" I'm thinking of using it with a RTOS or task-switcher. Any function which accesses a system resource ( such as global memory, serial port, etc.. ) would have to serialize access. This would necesitate knowledge of the task switching mechanism. The compiler doesn't know how to do this. How does MS, etc do it? Presumambly, their libraries malloc can only be used with the corresponding OS. I'm not familiar with other embedded compilers. Some claim to be reentrant and support multiple 3-rd party RTOS's. How? Bracketting non-reentrant f's with the RTX-51 example os_wait( K_MBX + SEM_PRINTF, 255, 0 ) printf(); os_send_token(SEM_PRINTF); is awkward. Would simply suspending task-switching be sufficient? It might be for global memory, but problems would occur if two tasks wrote out to the SBUF.
I'm sorry to say but for objects that are inherently global you must semaphore protect or disable task-switching/interrupts. The latter is not so appealing to me in a real-time system. Semaphores are nice because for things like a tty port (SBUF) you can give the display to one task and let it finish writing its coherent block of data to the tty. When this is complete, then another task pending on the tty semaphore will resume and write its coherent block of data to the tty and then release the semaphore. Not using a semaphore means you get text interspersed on the tty from both tasks, yuk. Pending on resources is just part of using a pre-emptive mulititasking kernel so, despite the ackwardness, semaphores are the way to do it properly, IMHO. - Mark
If you just want to protect a library function like puts from reentrancy, you can create the following:
void R_puts (unsigned char *p) { os_wait( K_MBX + SEM_PUTS, 255, 0 ) puts(p); os_send_token(SEM_PUTS); }
void func (void) { R_puts("This is great."); R_puts("This is great, 2."); R_puts("This is great, 3."); }