On Thu, Mar 14, 2002 at 10:00:23PM -0500, Cliff Woolley wrote:
> I don't know what it was that made me convince myself it was broken. I
> need to go back and look more carefully. It was something like I thought
> that aligning an array was wrong because the elements of the array would
> be out of whack, but that doesn't seem right because the compiler should
> align an individual struct correctly so that it can be placed back to back
> with ITSELF and maintain alignment. It's placing structures back to back
> with other structures that could cause headaches. So the patch could well
> be correct, though as you say, right now the sizes are magically correct
> anyway. I'll look into this more closely as soon as I can.
I think it's fine right now, but only as long as the sizes of the
worker_score, process_score, and global_score stay as multiples of the
pointer alignment. Just to be safe, I think we should pad these out.
My attached patch seems to work for me, but I don't have a picky enough
chip to test.
Also, can we detect the pointer alignment in an autoconf test, so we
don't waste so much space in the padding?
-aaron
Index: server/scoreboard.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/scoreboard.c,v
retrieving revision 1.60
diff -u -u -r1.60 scoreboard.c
--- server/scoreboard.c 27 Feb 2002 04:10:19 -0000 1.60
+++ server/scoreboard.c 15 Mar 2002 06:48:37 -0000
@@ -132,9 +132,10 @@
{
ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
- scoreboard_size = sizeof(global_score);
- scoreboard_size += sizeof(process_score) * server_limit;
- scoreboard_size += sizeof(worker_score) * server_limit * thread_limit;
+ scoreboard_size = APR_ALIGN_DEFAULT(sizeof(global_score));
+ scoreboard_size += APR_ALIGN_DEFAULT(sizeof(process_score)) * server_limit;
+ scoreboard_size += APR_ALIGN_DEFAULT(sizeof(worker_score)) * server_limit
+ * thread_limit;
return scoreboard_size;
}
@@ -145,17 +146,19 @@
ap_calc_scoreboard_size();
ap_scoreboard_image =
- calloc(1, sizeof(scoreboard) + server_limit * sizeof(worker_score *));
+ calloc(1, APR_ALIGN_DEFAULT(sizeof(scoreboard))
+ + server_limit * APR_ALIGN_DEFAULT(sizeof(worker_score *)));
more_storage = shared_score;
ap_scoreboard_image->global = (global_score *)more_storage;
- more_storage += sizeof(global_score);
+ more_storage += APR_ALIGN_DEFAULT(sizeof(global_score));
ap_scoreboard_image->parent = (process_score *)more_storage;
- more_storage += sizeof(process_score) * server_limit;
+ more_storage += APR_ALIGN_DEFAULT(sizeof(process_score)) * server_limit;
ap_scoreboard_image->servers =
- (worker_score **)((char*)ap_scoreboard_image + sizeof(scoreboard));
+ (worker_score **)((char*)ap_scoreboard_image
+ + APR_ALIGN_DEFAULT(sizeof(scoreboard)));
for (i = 0; i < server_limit; i++) {
ap_scoreboard_image->servers[i] = (worker_score *)more_storage;
- more_storage += thread_limit * sizeof(worker_score);
+ more_storage += thread_limit * APR_ALIGN_DEFAULT(sizeof(worker_score));
}
ap_assert(more_storage == (char*)shared_score + scoreboard_size);
ap_scoreboard_image->global->server_limit = server_limit;