On Sun, 23 Aug 2015 19:00:21 -0700, you wrote:

>>
>>
>>
>>
>> *Now *that* should not happen, if it's a context change then you're
>> dealing with a different stack.  These calls should return to where they
>> were when the interrupt/call happened.*
>>
>>
>> * By changing the call table, I can see changing the priorities, but to
>> actually throw away interrupts and things that are on the stack makes no
>> sense.*
>>
>
>Actually you're 100% correct here. What I described can be done with
>embedded devices, but running bare metal code. *That* I've seen
>demonstrations for. Running Linux, the program would produce an exception
>most likely. Too much code on my brain right now . . .
>
>So, knowing my own code I do know what happens. When thinking about it for
>more than 2 seconds heh.
>
>
>   - Process is reading from the canbus, callback happens.
>   - callback function call pops onto the stack, effectively stalling the
>   canbus reads.
>   - callback does it's thing, pops off the stack.
        Well, you're certainly right that the callback is messing
things up.  If I assume the same callback, then the callback is
certainly changing data.  If you can set the right breakpoint, you can
tag the situation *if* the breakpoint also knows that the process is
reading from the CAN bus.

Had you considered disabling that callback function until the read
from the CANbus is finished?  Would it be practical?  That's where the
semaphore might help a lot.

what variables could be common between the two routines?

Harvey

>   - canbus read resumes, sees the data it out of sequence, dumps the data,
>   and waits for a new packet set.
>   - rinse / repeat several times a second.
>
>The end result is that the canbus data never sees the light of day so to
>speak.
>
>On Sun, Aug 23, 2015 at 6:25 PM, Harvey White <ma...@dragonworks.info>
>wrote:
>
>> On Sun, 23 Aug 2015 17:57:58 -0700, you wrote:
>>
>> >Harvey,
>> >
>> >I guess I kind of put what I was trying to say badly. Probably more than
>> >once, as I was rereading some of my posts, and there re a few typos /
>> >incomplete words.
>>
>> That's ok.  I make misteaks too....
>> >
>> >Anyway, what I mean by "not thread safe" in the context of libmongoose is
>> -
>> >Same thread. Or any mechanism ( perhaps fork(), and same executable
>> threads
>> >) that share a common stack. I'm not all that well versed in many Linux
>> API
>> >calls, but I do have a good many years of programming experience in
>> >multiple languages. Meaning: I can usually code my way out of a wet paper
>> >sack - given enough time  hehe ;)
>>
>> Right, same situation here in a sense, but I've been working my way
>> through writing programs that actually *run* under FreeRTOS, and there
>> have been surprises....
>> >
>> >The rationale behind this behavior assuming I understand the library well
>> >enough is that a websockets needs to be reasonably quick, and offer
>> >asynchronous communications. And again this is my assumption . . .yeah
>> yeah
>> >murphy, and mother of all . . .  I get that ;) Problem is, libmongoose is
>> >roughly 10k lines of code, possibly more, and I really did not want to
>> >digest that much code from someone else - YET.
>> >
>>
>> That's the problem about using someone else's code.  If you code it,
>> you deal with the limits of your own ignorance.  If you use someone
>> else's code, then you deal with yours... and theirs.  Part of the
>> difficulty is knowing which is which.
>>
>> That's why in what I do for embedded systems, I use only FreeRTOS and
>> (perhaps) FatFS.  FreeRTOS has caused it's own share of problems, due
>> to some things they assume, and many more that I do....
>>
>> >So the callback rate is adjustable. Another problem arises here. If the
>> >callback is too slow, it interferes with the whole control loop - Slows it
>> >down. Kind of a chicken or the egg situation overall.
>>
>> That's a digital control problem, sampled data systems, etc.
>>
>> >
>> >The reason why I posted on this problem, was that I was hoping I was going
>> >to get a simple answer like " hey dummie, you're forgetting to call
>> >fflush() . . ." or something simple like that. Which I know of, but do not
>> >completely understand. fflush() for this situation I do not think applies.
>> >but . . .
>>
>> Sorry that I cannot help you there.  In this situation, while I may
>> know a bit about operating systems, I do not necessarily know how
>> Linux (or specifically libmongoose) *does* what it does.  I know the
>> principles from having written an OS, and also from having taught it,
>> but the specific implementations are another matter.   So, for that
>> matter, is terminology  .... Never ran into "callback" before.  I
>> think I understand what it is, but just never used that name.
>>
>> Did that many many years ago under other names.
>>
>> >
>> >Shared memory synchronization has been on my mind for a couple months now.
>> >But only recently ( last night ) did I find a good document on semaphores.
>> >Not just some cheap example, with little to no explanation. But covering
>> >multiples use cases, multiple ways, with a decent explanation. Which is to
>> >say, i found the typical using a system wide resource, plus using a system
>> >call - All to clog up my app, and app performance a bit constraining.
>>
>> You could roll your own, if you want.  Advantage of OS is that it's
>> done and works, disadvantage may be speed.  Advantage of your own is
>> that it's simple and may be fast.   Disadvantage is that it may not
>> work.
>>
>> You could simply turn on and off interrupts by declaring the code
>> atomic.  Just be sure that you do not have wait loops in there or any
>> sort of wait condition.  It'll keep a context switch from happening in
>> critical code (which can mess up hardware no end, trust me....)
>>
>> >Hence
>> >I was using a two field struct to represent my shared memory file up until
>> >a week ago. a byte to perform something akin to a binary semaphore, and
>> the
>> >rest to store data. Pagefile size being 4k on both x86, and ARM
>> >implementation I've used . . . no way I need that much memory. But it's
>> the
>> >minimum.
>>
>> At least you have more memory on these processors.  I've dealt with
>> less.
>>
>> >
>> >So back to "smashing the stack". As I understand it. a single executable
>> >that runs procedural, you do not have to worry much about this happening.
>> >Function calls pop in and out of the stack as they should.
>>
>> Yep.
>>
>> >
>> >However, when you have multiple "non blocking" calls ( I only know of
>> >callbacks ), with a bit of local data in each, this becomes a bit of a
>> >problem. A preempting call can, and will knock any functions "higher" than
>> >main off the stack by changing the call table.
>>
>> Now *that* should not happen, if it's a context change then you're
>> dealing with a different stack.  These calls should return to where
>> they were when the interrupt/call happened.
>>
>> By changing the call table, I can see changing the priorities, but to
>> actually throw away interrupts and things that are on the stack makes
>> no sense.
>>
>>
>>
>> >This is actually relatively
>> >new to me as well. As with high level object oriented language this isn't
>> a
>> >problem. At least I've never had this problem - But can see how this could
>> >in fact impact C++, which would really be C code in nature.
>>
>> Except that the people who coded C++ improved it, and that can make a
>> difference.  I've written many lines of C code for embedded processors
>> (GCC C, and the MEGA or XMEGA processors) and have not run into this
>> kind of behavior.  It sounds like a context switch, which gives a
>> different stack, and then a failure to restore context, which *could*
>> explain that.  It's a bug, though, at least to me.
>>
>> >
>> >Anyway I've seen demonstrations / explanations of this before, but never
>> >really experienced it first hand until a couple month ago. When first
>> >trying to implement libmongoose into my own code.
>>
>> I'd be suspicious of libmongoose, if for no other reason than I do not
>> understand how a callback (as I understand it, calling a function by a
>> table lookup, done that lots....) could mess up the system like that.
>> Granted, they are not OS calls, and should be within a thread, but
>> still.....
>>
>> >
>> >Anyway, I'm going to implement Semaphores tonight and see how well it
>> >works. I suspect that I'll run into similar problems I had with my own
>> >implementation ( binary file locking ), and see odd behavior - Such as
>> >missing data, and odd process stalling - But I'll find out.
>>
>> I can only wish you luck on that one.  I can't see Linux or any
>> variety implementing the kind of behavior you describe, but that means
>> nothing to an implementation that does that very thing.
>>
>> Process stalling is caused by deadlocks, or interrupt starvation,
>> where the process starves because higher priority processes keep
>> hogging the available time slots.  Those can be fixed....
>>
>> Please keep me informed on your progress, as I'm still puzzled about
>> this .....
>>
>> Thanks
>>
>> Harvey
>>
>> >
>> >On Sun, Aug 23, 2015 at 5:24 PM, Harvey White <ma...@dragonworks.info>
>> >wrote:
>> >
>> >> On Sun, 23 Aug 2015 16:32:03 -0700, you wrote:
>> >>
>> >> >>
>> >> >> *Linux (someone please correct me if I am wrong) *has* to be thread*
>> >> >> * safe.*
>> >> >>
>> >> >> * The problem I see is that you are not using the parts of the OS
>> that*
>> >> >> * are designed to keep you from messing things up.*
>> >> >>
>> >> >>
>> >> >> *malloc, or perhaps a version that the OS uses that turns OFF*
>> >> >> * interrupts and deals with the memory manager in the chips, should
>> >> only*
>> >> >> * allocate memory within the program's space, or once that memory is*
>> >> >> * allocated, automatically assign it to that program.*
>> >> >>
>> >> >> * An operating system is about managing resources, giving them to a*
>> >> >> * program, and making the whole thing graceful.*
>> >> >>
>> >> >
>> >> >Harvey,
>> >> >
>> >> >You do understand what happens when you have a function that's on the
>> >> >stack, that uses local variables, when suddenly a callback interrupts
>> that
>> >> >function call ? Not only does that function call cease to exist, but
>> all
>> >> >local variable data is gone. What's more, the function does not even
>> >> >resume. As it's been popped off the stack.
>> >>
>> >> Hmmm, seriously enough, I've not seen that behavior and it doesn't
>> >> make all that much sense to me about how it works.
>> >>
>> >> I'd have thought that if you call another function, even if it's the
>> >> same in a recursive call *and* the function is reentrant, then I'd
>> >> expect everything on the stack to be where I left it.
>> >>
>> >> I have code that essentially calls a function based on a table entry
>> >> (of the desired function) that is referred to by an index.
>> >>
>> >> It works well.
>> >>
>> >> So this particular behavior is a bit odd to me, since it says that the
>> >> stack is not behaving the way I'd think it was.
>> >>
>> >> I'm not sure that this is behaving like a sensible call (even an
>> >> interrupt or context change).
>> >>
>> >> What's the rationale for this kind of behavior?
>> >>
>> >> >My comment about malloc() was
>> >> >tongue in cheek. As it would not even help. Anyway, there probably is a
>> >> >workaround for this situation that I'm currently not aware of.
>> >>
>> >> Depends on whether or not this is an expected behavior and why it
>> >> happens.
>> >>
>> >> Most of my experience is with embedded microprocessors and FreeRTOS as
>> >> an operating system, although I have written a time slicing
>> >> cooperative operating system which did work, just more effort than I
>> >> wanted to do to make it pre-emptive.
>> >>
>> >> I'm puzzled right now....
>> >>
>> >>
>> >> >
>> >> >This is why libmongoose is not thread safe, and cannot coexist in the
>> same
>> >> >executable as my canbus manipulation routines. This is standard
>> behavior
>> >> >for libmongoose according to that I've read. Even the maintainer says
>> it's
>> >> >not thread safe, if memory serves me correctly.
>> >> >
>> >>
>> >> Ah, now if not thread safe, then uses static variables or volatiles,
>> >> which I can see.  That could be the answer, but I'm used to writing
>> >> either re-entrant code (down to the device drivers) or knowing whether
>> >> or not the routine is re-entrant and controlling access by semaphores
>> >> or mutexes as needed.
>> >>
>> >> Mostly the non-reentrant code had to be initialized (i.e setting up
>> >> heap structures when first called), and the easiest way to do that is
>> >> to have a static variable for the heap structures.  Up to me to see
>> >> that it is not called in a re-entrant manner, since it will clobber
>> >> the heap structure's data on the second call.
>> >>
>> >> Harvey
>> >>
>> <snip>
>>
>> --
>> For more options, visit http://beagleboard.org/discuss
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "BeagleBoard" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to beagleboard+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to beagleboard+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to