Discussion:
POSIX threads won't execute concurrently?
Martin Galvan
2014-08-27 17:58:00 UTC
Permalink
Hi everyone! I'm trying to run a simple program to test how RTEMS
handles concurrency when using POSIX threads. My code is fairly
simple: it creates two pthreads with each one printing its name in a
loop. Normally I'd get something like:

Thread 1
Thread 1
Thread 2
Thread 2
Thread 1
Thread 1
Thread 2
...

and so on. However, when I try this on RTEMS the second thread will
begin execution only after the first one ends, thus resulting in
something like:

Thread 1
Thread 1
Thread 1
...
End of Thread 1.
Thread 2
Thread 2
Thread 2
...
End of Thread 2.

I'm using the following configuration:

#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_MICROSECONDS_PER_TICK 1000 /* 1 millisecond */
#define CONFIGURE_TICKS_PER_TIMESLICE 20 /* 20 milliseconds */
#define CONFIGURE_MAXIMUM_POSIX_THREADS 4
#define CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
#define CONFIGURE_INIT

#include <rtems/confdefs.h>

Am I doing something wrong here?
Joel Sherrill
2014-08-27 18:00:46 UTC
Permalink
It all depends on how you created them, scheduler attributes, priority,
RTEMS
configuration, etc.

Can you post the code?

--joel
Post by Martin Galvan
Hi everyone! I'm trying to run a simple program to test how RTEMS
handles concurrency when using POSIX threads. My code is fairly
simple: it creates two pthreads with each one printing its name in a
Thread 1
Thread 1
Thread 2
Thread 2
Thread 1
Thread 1
Thread 2
...
and so on. However, when I try this on RTEMS the second thread will
begin execution only after the first one ends, thus resulting in
Thread 1
Thread 1
Thread 1
...
End of Thread 1.
Thread 2
Thread 2
Thread 2
...
End of Thread 2.
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_MICROSECONDS_PER_TICK 1000 /* 1 millisecond */
#define CONFIGURE_TICKS_PER_TIMESLICE 20 /* 20 milliseconds */
#define CONFIGURE_MAXIMUM_POSIX_THREADS 4
#define CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
Am I doing something wrong here?
_______________________________________________
users mailing list
http://lists.rtems.org/mailman/listinfo/users
--
Joel Sherrill, Ph.D. Director of Research & Development
joel.sherrill-***@public.gmane.org On-Line Applications Research
Ask me about RTEMS: a free RTOS Huntsville AL 35805
Support Available (256) 722-9985
Martin Galvan
2014-08-27 18:11:42 UTC
Permalink
On Wed, Aug 27, 2014 at 3:00 PM, Joel Sherrill
Post by Joel Sherrill
It all depends on how you created them, scheduler attributes, priority,
RTEMS
configuration, etc.
Can you post the code?
--joel
Sure, here you go:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <sched.h>
#include <pthread.h>
#include <rtems.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <bsp.h> /* for device driver prototypes */

void* thread(void* arg)
{
int i;

for (i = 0; i < INT_MAX; i++) {
printf("Thread %d\n", pthread_self());
}

printf("End of thread %d\n", pthread_self());

return 0;
}

void* POSIX_Init()
{
pthread_t id1, id2;

if (pthread_create(&id1, NULL, thread, NULL) != 0) {
perror("Thread 1");
}

if (pthread_create(&id2, NULL, thread, NULL) != 0) {
perror("Thread 2");
}

if (pthread_join(id1, NULL) != 0) {
perror("Join 1");
}

if (pthread_join(id2, NULL) != 0) {
perror("Join 2");
}

puts("Done.");

exit(0);
}

#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_MICROSECONDS_PER_TICK 1000 /* 1 millisecond */
#define CONFIGURE_TICKS_PER_TIMESLICE 20 /* 20 milliseconds */
#define CONFIGURE_MAXIMUM_POSIX_THREADS 4
#define CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
#define CONFIGURE_INIT

#include <rtems/confdefs.h>

One more thing: for some reason, if I use
CONFIGURE_MAXIMUM_POSIX_THREADS with a number greater than 4, I don't
see any output when running my program.
Post by Joel Sherrill
Post by Martin Galvan
Hi everyone! I'm trying to run a simple program to test how RTEMS
handles concurrency when using POSIX threads. My code is fairly
simple: it creates two pthreads with each one printing its name in a
Thread 1
Thread 1
Thread 2
Thread 2
Thread 1
Thread 1
Thread 2
...
and so on. However, when I try this on RTEMS the second thread will
begin execution only after the first one ends, thus resulting in
Thread 1
Thread 1
Thread 1
...
End of Thread 1.
Thread 2
Thread 2
Thread 2
...
End of Thread 2.
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_MICROSECONDS_PER_TICK 1000 /* 1 millisecond */
#define CONFIGURE_TICKS_PER_TIMESLICE 20 /* 20 milliseconds */
#define CONFIGURE_MAXIMUM_POSIX_THREADS 4
#define CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
Am I doing something wrong here?
_______________________________________________
users mailing list
http://lists.rtems.org/mailman/listinfo/users
--
Joel Sherrill, Ph.D. Director of Research & Development
Ask me about RTEMS: a free RTOS Huntsville AL 35805
Support Available (256) 722-9985
Peter Dufault
2014-09-01 09:47:41 UTC
Permalink
Post by Martin Galvan
void* thread(void* arg)
{
int i;
for (i = 0; i < INT_MAX; i++) {
printf("Thread %d\n", pthread_self());
}
printf("End of thread %d\n", pthread_self());
return 0;
}
void* POSIX_Init()
{
pthread_t id1, id2;
if (pthread_create(&id1, NULL, thread, NULL) != 0) {
perror("Thread 1");
}
if (pthread_create(&id2, NULL, thread, NULL) != 0) {
perror("Thread 2");
}
if (pthread_join(id1, NULL) != 0) {
perror("Join 1");
}
if (pthread_join(id2, NULL) != 0) {
perror("Join 2");
}
puts("Done.");
exit(0);
}
The default scheduling behavior for RTEMS is SCHED_FIFO, which makes sense for real time behavior. In your example you don't have any assurance that the running thread will block and go to the tail of it's priority queue. You could put a sched_yield() after the printf() or you could try using scheduling attributes set to SCHED_RR. If you set the scheduler to SCHED_RR your output could get jumbled and not break at the lines.

In general for well-defined thread behavior you need to handle the synchronization.

There are also other issues: whether your stdout is line-buffered or not, if it's going to a file on a file system that might need some additional flushing primitive beyond fflush() to ensure output, etc. I suspect putting in the sched_yield() will result in "Thread 1 / Thread 2 / Thread 1... " behavior, though.


Peter
-----------------
Peter Dufault
HD Associates, Inc. Software and System Engineering

Loading...