Skip to content

Commit

Permalink
Fix nasa#525, ensure POSIX stack size meets requirements
Browse files Browse the repository at this point in the history
The pthread_attr_setstacksize() function stipulates that it
may fail if the user-supplied stack size is not at least
PTHREAD_STACK_MIN and also possibly a multiple of page size.

This partially reverts previous PR nasa#508 and adds back rounding
up to PTHREAD_STACK_MIN and also adds rounding up to a system
page size.  However the check for zero stack still remains
at the shared level so attempts to create a task with zero
stack will still fail.  This allows internal helper threads
to be created with a default minimum stack size, however.
  • Loading branch information
jphickey committed Jun 29, 2020
1 parent 33471c7 commit 85f734d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/os/posix/inc/os-posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ typedef struct
pthread_key_t ThreadKey;
sigset_t MaximumSigMask;
sigset_t NormalSigMask;
size_t PageMask;
POSIX_PriorityLimits_t PriLimits;
int SelectedRtScheduler;
} POSIX_GlobalVars_t;
Expand Down
78 changes: 61 additions & 17 deletions src/os/posix/src/os-impl-tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@
#include "os-shared-task.h"
#include "os-shared-idmap.h"

/*
* Defines
*/
#ifndef PTHREAD_STACK_MIN
#define PTHREAD_STACK_MIN (8*1024)
#endif

/* Tables where the OS object information is stored */
OS_impl_task_internal_record_t OS_impl_task_table [OS_MAX_TASKS];

Expand Down Expand Up @@ -212,6 +219,7 @@ int32 OS_Posix_TaskAPI_Impl_Init(void)
bool sched_fifo_valid;
POSIX_PriorityLimits_t sched_rr_limits;
bool sched_rr_valid;
size_t pagesz;

/* Initialize Local Tables */
memset(OS_impl_task_table, 0, sizeof(OS_impl_task_table));
Expand Down Expand Up @@ -416,6 +424,24 @@ int32 OS_Posix_TaskAPI_Impl_Init(void)
}
#endif

pagesz = sysconf(_SC_PAGESIZE);
if (pagesz > 0)
{
/*
* convert to a mask. Should already be a power of 2,
* but if not, make it so.
*/
--pagesz;
pagesz |= (pagesz >> 1);
pagesz |= (pagesz >> 2);
pagesz |= (pagesz >> 4);
pagesz |= (pagesz >> 8);
pagesz |= (pagesz >> 16);

POSIX_GlobalVars.PageMask = pagesz;
}


return OS_SUCCESS;
} /* end OS_Posix_TaskAPI_Impl_Init */

Expand Down Expand Up @@ -446,14 +472,41 @@ int32 OS_Posix_InternalTaskCreate_Impl(pthread_t *pthr, uint32 priority, size_t
return(OS_ERROR);
}


/*
** Test to see if the original main task scheduling priority worked.
** If so, then also set the attributes for this task. Otherwise attributes
** are left at default.
/*
* Adjust the stack size parameter.
*
* POSIX has additional restrictions/limitations on the stack size of tasks that
* other RTOS environments may not have. Specifically POSIX says that the stack
* size must be at least PTHREAD_STACK_MIN and may also need to be a multiple of the
* system page size.
*
* Rounding up means the user might get a bigger stack than they requested, but
* that should not break anything aside from consuming extra memory.
*/
if (POSIX_GlobalVars.EnableTaskPriorities)
{
if (stacksz < PTHREAD_STACK_MIN)
{
stacksz = PTHREAD_STACK_MIN;
}

stacksz = (stacksz + POSIX_GlobalVars.PageMask) & ~POSIX_GlobalVars.PageMask;

/*
** Set the Stack Size
*/
return_code = pthread_attr_setstacksize(&custom_attr, stacksz);
if (return_code != 0)
{
OS_DEBUG("pthread_attr_setstacksize error in OS_TaskCreate: %s\n",strerror(return_code));
return(OS_ERROR);
}

/*
** Test to see if the original main task scheduling priority worked.
** If so, then also set the attributes for this task. Otherwise attributes
** are left at default.
*/
if (POSIX_GlobalVars.EnableTaskPriorities)
{
/*
** Set the scheduling inherit attribute to EXPLICIT
*/
Expand All @@ -464,15 +517,6 @@ int32 OS_Posix_InternalTaskCreate_Impl(pthread_t *pthr, uint32 priority, size_t
return(OS_ERROR);
}

/*
** Set the Stack Size
*/
return_code = pthread_attr_setstacksize(&custom_attr, stacksz);
if (return_code != 0)
{
OS_DEBUG("pthread_attr_setstacksize error in OS_TaskCreate: %s\n",strerror(return_code));
return(OS_ERROR);
}

/*
** Set the scheduling policy
Expand Down Expand Up @@ -503,7 +547,7 @@ int32 OS_Posix_InternalTaskCreate_Impl(pthread_t *pthr, uint32 priority, size_t
return(OS_ERROR);
}

} /* End if user is root */
} /* End if user is root */

/*
** Create thread
Expand Down

0 comments on commit 85f734d

Please sign in to comment.