Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cfe2cos, the mega-merge #333

Open
wants to merge 156 commits into
base: ppos
Choose a base branch
from
Open

cfe2cos, the mega-merge #333

wants to merge 156 commits into from

Conversation

Others
Copy link
Contributor

@Others Others commented Mar 20, 2018

Summary of this Pull Request (PR)

The cFE is a complex piece of software, consequently our support implementation is quite complex. I will attempt to summarize what is going on with each change.

cFE_booter Support Code

  • Summary: To get from cos_init to the actual cFE is a bit of code, most of which is inspired by the posix implementation. We need to set up all of our data structures, start our scheduler, and make sure the filesystem is in good order. It's spread across of few files -- but again, not too complicated. We also boost the stack size so that the cFE doesn't blow the small stack. You can trace configuration logic from cFE_entrypoint.c The only other interesting stuff is in cFE_util.c.
  • Component files: cFE_booter/cFE_entrypoint.c cFE_booter/cFE_util.c cFE_booter/cFE_util.h parts of cFE_booter/osapi.c and cFE_booter/ostask.c include/shared/consts.h
  • Known Issues: The first code we wrote. It's a bit overly complex and stupid. It's written in a very formal style, which we quickly diverged from.

General OSAL Method Implementations

  • Summary: The most straightforward of the straightforward. Some of these are a bit hacky, but the code quality is fine. Many of these methods are irrelevant and unimplemented.
  • Component files: cFE_booter/osapi.c cFE_booter/psp.c cFE_booter/ostimer.c cFE_booter/osnetwork.c
  • Known Issues:

Copied Files

  • Summary: Shared OSAL code we just copied out of the cFE. Unmodified, doesn't need review.
  • Component files: cFE_booter/cfe_psp_*
  • Known Issues:

App Loading

  • Summary: Code to work as glue between how the cFE thinks of apps, and how composite thinks of components. Method glue code found elsewhere.
  • Component files: cFE_booter/osloader.c
  • Known Issues: Creating a new app is a bit of a janky process.

cFE Tasks + Scheduling

  • Summary: My baby. Glue for making the cFE task API compatible with composite threads. Relies on a lot of sl code under the hood. Probably needs checking for races.
  • Component files: cFE_booter/ostask.c cFE_booter/ostask.h cFE_booter/sl_mod_fprr.c cFE_booter/sl_mod_policy.h cFE_booter/sl_thd_static_backend.c
  • Known Issues: The semaphore implementation is pure garbage. (Luckily they're not really used.) We should talk about zero allocation semaphores.

OSAL Filesystem APIS

  • Summary: This is all Joe's doing, he'll leave a comment on it.
  • Component files: cFE_booter/osfiles.c cFE_booter/osfilesys.c cFE_booter/osfilesys.h cFE_booter/tar.c cFE_booter/tar.h
  • Known Issues:

Queue Implementation

  • Summary: Zach's doing. Not much interesting here, and I haven't looked at it in a long time. Appears to work fine.
  • Component files: cFE_booter/osqueue.c
  • Known Issues:

Major Build System Changes

  • Summary: Integrating the cFE under composite took a bit of make wrangling. We kept most of our original build logic--in python--but it now runs totally under composite's make. I think most of the custom stuff is well commented.
  • Component files: .gitignore .gitmodules src/Makefile extern/make.py
  • Known Issues: Half of it is in python. My makefoo is weak, so some of this is a bit of a cludge. I just don't know how to do it better.

cFE App Component Wrappers

  • Summary: We wrap every cFE app in a component, and each of these components needs a little bit of helper code. Lots of mostly unavoidable code duplication.
  • Component files: no_interface/sch_lab/* no_interface/sample_lib/* no_interface/sample_app/*
  • Known Issues:

cFE emulation for apps

  • Summary: We need to provide a way for apps to call into the cFE, but intercepting the calls and writing parts into shared memory.
  • Component files: src/components/Makefile.comp cFE_booter/cFE_emu_support.c lib/cFE_emu.c lib/Makefile include/cFE_emu.h
  • Known Issues: I've just realized that this should've been done through c stubs. I'll fix that, so don't bother commenting about it.

cFE_booter Build System

  • Summary: The cFE booter needs some some special build logic. It isn't anything too complicated, just integrating a few external object files.
  • Component files: cFE_booter/.gitignore cFE_booter/Makefile
  • Known Issues:

Running the cFE

  • Summary: These are our runscripts and Vagrantfile, how the cFE actually gets going. Not that interesting or important.
  • Component files: tools/Vagrantfile runscripts/cFE_booter.sh runscripts/llboot_cFE.sh
  • Known Issues:

Other Outstanding Issues

  • The cFE unit tests are currently broken. This probably should be fixed, but I'm unsure how much work it is. Likely can be done after the deadline.
  • llbooter/boot_deps.h and llbooter/llbooter.c are modified to map an extra page per component. This sucks, but without it the cFE breaks.
  • A bunch of stub files are changed. (As well as include/cos_asm_simple_stacks.h) This is because their composite versions are utterly broken and don't respect consts.h. I don't implement the most elegant solution, but w/e.

Intent for your PR

Choose one (Mandatory):

  • This PR is for a code-review and is intended to get feedback, but not to be pulled yet.
  • This PR is mature, and ready to be integrated into the repo.

Reviewers (Mandatory):

(Specify @<github.com username(s)> of the reviewers. Ex: @user1, @user2)
@gparmer @base0x10 @phanikishoreg

Code Quality

As part of this pull request, I've considered the following:

Style:

  • Comments adhere to the Style Guide (SG)
  • Spacing adhere's to the SG
  • Naming adhere's to the SG
  • All other aspects of the SG are adhered to, or exceptions are justified in this pull request
  • I have run the auto formatter on my code before submitting this PR (see doc/auto_formatter.md for instructions)

Code Craftsmanship:

  • I've made an attempt to remove all redundant code
  • I've considered ways in which my changes might impact existing code, and cleaned it up
  • I've formatted the code in an effort to make it easier to read (proper error handling, function use, etc...)
  • I've commented appropriately where code is tricky
  • I agree that there is no "throw-away" code, and that code in this PR is of high quality

Testing

I've tested the code using the following test programs (provide list here):

  • the cFE

Others and others added 30 commits May 31, 2017 15:40
There are known issues, but it should be fine for now
This commit also removes the redundant scheddev directory
@Others
Copy link
Contributor Author

Others commented Mar 23, 2018

I've addressed most of the above comments, will investigate the others. I also got rid of the cFE_emu library, and used the existing c_stubs mechanism.

@gparmer In terms of review ordering, this order would be great:

  • cFE_booter Support Code
  • cFE Tasks + Scheduling
  • General OSAL Method Implementations
  • cFE emulation for apps (now with c_stubs!)
  • Queue Implementation

Otherwise the original order of the summaries is a proxy for my desire to have that part reviewed. (Although, I think the filesystem should go last. It's already been reviewed after all.)

Thanks!


int emu_backend_request_memory(spdid_t client);

int32 emu_CFE_ES_GetGenCount(spdid_t client);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use the cos_inv_token() in the server component for the client's spdid instead.

Copy link
Collaborator

@gparmer gparmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to go, and I'm half way through ostask.c, but I figured I'd leave these comments for now. Will continue when I can.

ADDITIONAL_LIBS=-lcobj_format -lcos_kernel_api -lcos_defkernel_api -lsl_capmgr -lsl_sched -lheap -lsl_lock

include ../../Makefile.subsubdir
CFLAGS += -I./gen -I ./test/shared $(CPPFLAGS)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't think there's supposed to be a space between -I .test.... I'm wondering what this test dir is. We'll see!

#include <cos_component.h>
#include <cos_debug.h>
#include <cos_types.h>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You said you want feedback on style so: no spaces between many of these.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We follow the std => cos => interface => cFE => internal header convention. Otherwise it becomes very confusing where each header is coming from. Especially since we have 5 header sources. Is this something the cos style guide takes a strong stance on?

int
emu_backend_request_memory(spdid_t client)
{
vaddr_t our_addr = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty line after definitions

int id = memmgr_shared_page_alloc(&our_addr);
assert(our_addr);
shared_regions[client] = (void *)our_addr;
return id;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line before final return.

emu_CFE_EVS_Register(spdid_t client)
{
union shared_region *s = shared_regions[client];
return CFE_EVS_Register(s->cfe_evs_register.filters, s->cfe_evs_register.NumEventFilters,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same thing about blank line after definitions. Won't repeat too many times, to keep the comment # down.

cycles_t now, start;

rdtscll(start);
start += sl_usec2cyc(HZ_PAUSE);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we uniformly 64 bit here? If not, could overflow easily.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uniformly 64 bit.


while (1) {
rdtscll(now);
if (now > start) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

start is not a good name for the variable being used here. Would use deadline as deadline = start + sl_usec2cyc(HZ_PAUSE).

We need to think through how to have asserts for all of the overflow possibilities everywhere. I'm concerned this is why your scheduling is wonky.

void
OS_SchedulerStart(cos_thd_fn_t main_delegate)
{
sl_init(SL_MIN_PERIOD_US);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defs at head of block

struct sl_thd * main_delegate_thread = sl_thd_alloc(main_delegate, NULL);
union sched_param_union sp = {.c = {.type = SCHEDP_PRIO, .value = MAIN_DELEGATE_THREAD_PRIORITY}};
sl_thd_param_set(main_delegate_thread, sp.v);
main_delegate_thread_id = sl_thd_thdid(main_delegate_thread);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"delegate thread" is a little bit of a strange name. Not really sure what "delegate" has to do with all of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's called main_delegate_thread. It's the thread we delegate main execution to. Do you have a better name in mind?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read it as, "of all the delegate threads, it is the main one". Both grammatical parsings are correct.

Maybe just a comment somewhere when it is first used to clarify.

it. */
}

sl_thd_block_periodic(0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to make sure we aren't spinning in this loop for some strange interaction in the system, it might be smart to count how many times we've iterated without triggering the now > start condition, and assert if it goes above some level (say 64).

Copy link
Collaborator

@gparmer gparmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ostask done.

struct sl_thd * main_delegate_thread = sl_thd_alloc(main_delegate, NULL);
union sched_param_union sp = {.c = {.type = SCHEDP_PRIO, .value = MAIN_DELEGATE_THREAD_PRIORITY}};
sl_thd_param_set(main_delegate_thread, sp.v);
main_delegate_thread_id = sl_thd_thdid(main_delegate_thread);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read it as, "of all the delegate threads, it is the main one". Both grammatical parsings are correct.

Maybe just a comment somewhere when it is first used to clarify.

task_info->osal_task_prop.priority = MAIN_DELEGATE_THREAD_PRIORITY;
task_info->osal_task_prop.OStask_id = (uint32)sl_thd_thdid(main_delegate_thread);

struct sl_thd * timer_thd = sl_thd_alloc(timer_fn_1hz, NULL);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defs at head of block

void
osal_task_entry_wrapper(void *task_entry)
{
((osal_task_entry)task_entry)();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we define this type, it should be osal_task_entry_t.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, this is a cFE definition


if (priority > 255 || priority < 1) { return OS_ERR_INVALID_PRIORITY; }

struct sl_thd *thd = sl_thd_alloc(osal_task_entry_wrapper, function_pointer);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def....block....blah ;-)

union sched_param_union sp = {.c = {.type = SCHEDP_PRIO, .value = priority}};
sl_thd_param_set(thd, sp.v);

struct cfe_task_info *task_info = &cfe_tasks[sl_thd_thdid(thd)];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha, our thdid function has a pretty redundant name.

OS_MutSemDelete(uint32 sem_id)
{
int32 result = OS_SUCCESS;
sl_lock_take(&mutex_data_lock);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty line before


sl_lock_take(&mutex_data_lock);

if (sem_id == NULL || sem_name == NULL) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move outside of lock along with next error check

}
}

/* The name was not found in the table,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/*
 * ...
 */


sl_lock_take(&semaphore_data_lock);

if (sem_id == NULL || sem_name == NULL) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move these error checks out of the lock

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since these checks are repetitive, you might want to move them into a function.

OS_SemaphoreDelete(struct semaphore *semaphores, uint32 max_semaphores, uint32 sem_id)
{
int32 result = OS_SUCCESS;
sl_lock_take(&semaphore_data_lock);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty line

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants