chesterpolo / mongoose

Automatically exported from code.google.com/p/mongoose
MIT License
0 stars 0 forks source link

Almost Working On RTEMS #100

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I have attached my local copy of mongoose.c which builds for RTEMS and
runs long enough to accept the first connection.  Then it blows the stack.

This brings up a few issues:

+ Are the RTEMS ifdef's properly incorporated?
+ Can there be ifdef's to disable SSL and DLLs completely.  So nothing
  related to them builds.
+ How should we configure the per-thread stack size?  This required ~48K
  per thread with Simple HTTPD.  Seems like a natural config option.
+ Should the priority of the mongoose threads be configurable?

+ What is the formula for pthread, mutex, condition variable connection?
Base number plus what per active connection.

It built quickly.  I have tried it on RTEMS, Linux and Windows this week. :)

Original issue reported on code.google.com by joel.she...@gmail.com on 13 Nov 2009 at 9:32

Attachments:

GoogleCodeExporter commented 9 years ago
Attached are patches that I'm using on RTEMS to permit you to specify the stack 
size for pthreads.
1. They are conditional on _POSIX_THREAD_ATTR_STACKSIZE and will apply to 
systems that report they support 
setting the pthread stack size.
2. They add a new option, "stacksize", to specify the size of the stack to use.
3. It splits mg_start() into mg_init() / mg_start_ctx().  This is because the 
first thread is created at mg_start() 
time, and so the option would be too late.  If the first thread is special and 
could use a small stack then thnis 
might not be required.

Original comment by dufa...@hda.com on 20 Apr 2010 at 4:56

Attachments:

GoogleCodeExporter commented 9 years ago
Great, thanks. Setting stack size is useful. IMO, a reasonable generic value is 
2 * sizeof(struct mg_connection)
Quick question: does RTEMS have pthread_rwlock_* functions?

Original comment by valenok on 20 Apr 2010 at 5:16

GoogleCodeExporter commented 9 years ago
Yes, I've never used them but they're there.  I'm sure Joel has tested them 
thoroughly...
By the way, does the first thread need to have as large a stack as the others?  
If not you don't need that 
mg_init()/mg_start_ctx() interface I added.  

Original comment by dufa...@hda.com on 21 Apr 2010 at 4:46

GoogleCodeExporter commented 9 years ago
Thanks.

I don't think that splitting mg_start into two function is useful in the 
mainstream, so I won't merge it.
Stack sizes are more of a concern.

Master thread probably does not need lots of stack, you're right.
What are the usual limitations on stack space on RTEMS?

Original comment by valenok on 21 Apr 2010 at 4:54

GoogleCodeExporter commented 9 years ago
Stack sizes are all over the place.  I'm working with two RTEMS systems right 
now, an MVME5500 with 
512MB of RAM and an MPC5554 with 4MB RAM.   I have the default stack on the 
MPC5554 set to 4K.  Some 
people work with less than that, default stacks can be quite small.

The problem is without the split of mg_start() I can't think of a good way to 
specify the stack size of the 
master thread.  I thought about a few ways before I did the split - add 
something to change the default 
option values (other than at compile time), but you've got the default options 
set as "const" and I like that.  
The only other way I could think of was a non-portable hack - figure out how to 
change the default pthread 
size in RTEMS, call mg_start(), set the default thread size back, and finally 
change the mg_option.  Not 
good.

I also thought a little about adding a callback function for setting thread 
attributes.  Then you could cleanly 
tweek stack size, priority, and even unique attributes that exist only in a 
certain implementation without 
extending the option table.  After the call to pthread_attr_init() if the 
callback pointer was non-null you'd call 
it passing the pthread_attr structure pointer.  That might be cleaner than the 
stacksize option.

I just realized my diff might not be correct.  I derived it from the version 
that was in the RTEMS tree and not 
the latest in SVN, when it applied cleanly to the SVN version I sent it in.  
This afternoon I'll try again with the 
SVN head.

Original comment by dufa...@hda.com on 21 Apr 2010 at 5:23

GoogleCodeExporter commented 9 years ago
2*sizeof(struct mg_connection) won't be large enough for the stack.  The stack 
in the call chain:
process_new_connection->analyze_request->send_directory->send_error->cry->builti
n_error_log-
>mg_fopen is on the order of 
MAX_REQUEST_SIZE+FILENAME_MAX+FILENAME_MAX+BUFSIZ+BUFSIZ+FILENAME_MAX or 
8192+2048+2048+4096+4096+2048=22K.  I had to set my stack to 16K before 
mongoose would work at 
all.
Are some of the large buffers guaranteed to be used only one at a time and so 
can go in the ctx structure?  
If not, maybe passing the store in in the call, or a free list is in order.

Original comment by dufa...@hda.com on 22 Apr 2010 at 11:30

GoogleCodeExporter commented 9 years ago
Hm, yes, 2 * sizeof(mg_connection) might not be enough. In fact, some of the 
functions are recursive.
I'll try to find a tool that shows a call graph with the required stack size.

Original comment by valenok on 22 Apr 2010 at 11:48

GoogleCodeExporter commented 9 years ago
You could always set a break point somewhere you know is pretty far down and 
see how big the stack is.

Back to setting the stack: What do you think of this interface, I've put it in 
locally, it's what I described 
before.  It "punts" anything custom about setting thread attributes back to the 
native environment.  Here's 
the header interface.  One drawback: to always work properly this would require 
including both <unistd.h> 
(for _POSIX_THREADS for these declarations to be included) and <pthread.h> (for 
a declaration of 
pthread_attr_t) before "mongoose.h", similarly to how you must include 
<stdio.h> before "mongoose.h" 
since mongoose.h references FILE *. 
I consider this OK.

#ifdef _POSIX_THREADS
/*
 * User-defined callback function prototype for an attribute callback.
 * When set, this is called immediately before the call to pthread_create() with a
 * pointer to the thread attributes.
 */
typedef void (*mg_attr_callback_t)(pthread_attr_t *attr);
/*
 * Set the attribute callback function.
 */
void mg_set_attr_callback(struct mg_context *, mg_attr_callback_t);
/*
 * Return the attribute callback function.
 */
mg_attr_callback_t mg_get_attr_callback(struct mg_context *);
#endif

Original comment by dufa...@hda.com on 22 Apr 2010 at 12:17

GoogleCodeExporter commented 9 years ago

Original comment by valenok on 7 Sep 2010 at 8:46