UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer jpgl
Observer
15,318 Views
Registered: ‎02-02-2010

SDK Thread Safety and Reentrancy - Contructor and Sprintf PROBLEM

Jump to solution

Hi everyone!

 

I notice that some functions, like sprintf for example, had an incorrect behavior when running my routines, like:

 

    while (1)
    {

        xil_printf("test1");

        sleep(2000);
        TRACE->SHOW(LEVEL_SHOW, "running");

        xil_printf("test2");

    }

 

 

void Trace::SHOW(int Level,  char *form, ...)
{

        (...)

        sprintf (str1, "Tick [%d] ",xget_clock_ticks());

        xil_printf(str1);

        (...)

}

 

I was hopping to see on TeraTerm:

test1

Tick[10]

test2

test1

Tick[20]

test2

test1

Tick[30]

test2

test1

Tick[40]

test2

(....) etc

 

Instead, I see only

 

test1

Tick[10]

test2

test1

--program ended

 

It appears the program terminated sudendly ..with no error reported..:(...

If I comment the sprintf...and use strcat, and xil_printf instead,I'll see on TeraTerm what I was expecting..

 

Other similar problem is when call my constructor:

 

Trace *TRACE;

TRACE = new Trace("running");//inside this constructor I have an empty function:

 

this one:

 

Trace::Trace(char *CsciName)
{}

 

And I see my program hangs here...like a infinite loop...that makes no sense :(

 

After some investigation, I read  from Xilkernel MANUAL the text:

 

Thread Safety and Reentrancy

Xilkernel, by definition, creates a multi-threaded environment. Many library and driver routines
might not be written in a thread-safe or re-entrant manner. Examples include the C library
routines such as printf( ), sprintf( ), malloc( ), free( ). When using any library
or driver API that is not a part of Xilkernel, you must make sure to review thread-safety and reentrancy
features of the routine. One common way to prevent incorrect behavior with unsafe
routines is to protect entry into the routine with locks or semaphores.

 

 

You think this has anything to do with my problem?

I tried to use:

 

xil_printf("lock :%d\r\n",pthread_mutex_lock(&mutex));
TRACE = new Trace("running");
xil_printf("unlock :%d\r\n",pthread_mutex_unlock(&mutex));

 

But the problem continues...

 

And I tried also:

 

void Trace::SHOW(int Level,  char *form, ...)
{

        static pthread_mutex_t  mutex;

        (...)

        pthread_mutex_lock(&mutex);

        sprintf (str1, "Tick [%d] ",xget_clock_ticks());

        xil_printf(str1);

        pthread_mutex_unlock(&mutex);

        (...)

}

 

 

But without success too....

 

Anybody know what could be the problem?

 

I already found this

But it has no answer...

 

Thanks in advance!!!

 

Message Edited by jpgl on 02-23-2010 08:06 AM
0 Kudos
1 Solution

Accepted Solutions
Observer jpgl
Observer
17,586 Views
Registered: ‎02-02-2010

Re: SDK Thread Safety and Reentrancy - Contructor and Sprintf PROBLEM

Jump to solution

Ok... the solution... do not use functions like sprintf, printf, even objects, constructors,etc.... :smileyhappy:

 

 

0 Kudos
3 Replies
Observer jpgl
Observer
17,587 Views
Registered: ‎02-02-2010

Re: SDK Thread Safety and Reentrancy - Contructor and Sprintf PROBLEM

Jump to solution

Ok... the solution... do not use functions like sprintf, printf, even objects, constructors,etc.... :smileyhappy:

 

 

0 Kudos
Highlighted
Newbie jasonjiang
Newbie
14,363 Views
Registered: ‎07-20-2010

Re: SDK Thread Safety and Reentrancy - Contructor and Sprintf PROBLEM

Jump to solution

I got the same issue.

 

You have to use Microblaze library, my_sprintf(), defined in xil_printf.c like below:


/*-------------------------------------------------------------------------*/

//
// This is the start of the file for other *printf functions
// that are used in the embedded system.  For some reason,
// the standard printf functions provided in the Xilinx
// library do not seem to work.
//

int my_sprintf(char *buff, char *fmt, ... )
{
    va_list ap;
    int     length;

    va_start(ap, fmt);
    length = xil_vsprintf(buff, fmt, ap);
    va_end(ap);

    return (length);
}


 

Tags (1)
0 Kudos
Participant n5ac
Participant
14,294 Views
Registered: ‎10-29-2008

Re: SDK Thread Safety and Reentrancy - Contructor and Sprintf PROBLEM

Jump to solution

From the Xilkernel documentation:

3-10-2012 7-58-47 AM.jpg

 

This is not a problem, though, since you can protect any of these that you use by enclosing them in a mutex.  For example, here is what I do for printf -- in a header file define as such:

 

#define safe_printf(fmt,args...) { lock_printf(); printf(fmt, ##args); fflush(stdout); unlock_printf(); }

 

Then here are the routines for your c file:

 

static pthread_mutex_t printf_mutex;

 

void lock_printf_init()
{
pthread_mutex_init(&printf_mutex, NULL);
}

void lock_printf(void)
{
pthread_mutex_lock(&printf_mutex);
}

void unlock_printf(void)
{
pthread_mutex_unlock(&printf_mutex);
}

 

And finally in an initialization routine somewhere, make sure this runs ONCE:

 

lock_printf_init();

 

Then when you want to do a printf, instead do it like this:

 

safe_printf("%d,%d\n",isamp[i],qsamp[i]);

 

Note that printf is BIG -- watch the size of your executable before and after you add a printf.  If you are using external DDR, this is generally not a problem as DDR is cheap.  If you are running in BRAM inside the FPGA, you may want to stick with xil_printf which works nicely, but does not support all format strings such as floating point (no "%3.2f" in your format strings).


0 Kudos