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 don't think there's a problem right now, but if the size of the
global_score or process_score changed by any non-multiple of the pointer
alignment then we'd have problems. Same if we tried to stuff anything else
in the shared mem segment behind the worker_score array. Seems like to
be safe we should pad out those sizes. How does the attached patch look?

Also, how can we detect the pointer alignment in an autoconf test, so
that we're not wasting so much padding on archs that support finer-grained
alignment?

-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;

Reply via email to