← Commit list

28e4d2b85

Denys Vlasenko
Denys Vlasenko
2026-01-26
SUCCESS Duration: 143s

Subject

httpd: optimize example CGIs

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0
gcc -Wp,-MD,applets/.applet_tables.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer       -o applets/applet_tables applets/applet_tables.c

Build Log

(log yok)

Commit Diff GitHub →

networking/httpd_indexcgi.c+22 -21
@@ -71,6 +71,19 @@ struct linux_dirent64 {
char d_name[];
};
+static void full_write(int fd, const void *buf, size_t len)
+{
+ ssize_t cc;
+
+ while (len) {
+ cc = write(fd, buf, len);
+ if (cc < 0)
+ return;
+ buf = ((const char *)buf) + cc;
+ len -= cc;
+ }
+}
+
/* Appearance of the table is controlled by style sheet *ONLY*,
* formatting code uses <TAG class=CLASS> to apply style
* to elements. Edit stylesheet to your liking and recompile. */
@@ -144,7 +157,6 @@ enum {
BUFFER_SIZE = 8 * 1024*1024,
//one dirent is typically <= 100 bytes, 1M is enough for ~10k files
//FIXME: change code to *iterate* getdents64 if need to support giant file lists
- HEADROOM = 64,
};
static char *buffer;
@@ -168,33 +180,19 @@ static char *dst;
# define RETURN_DST return dst
#endif
-/* After this call, you have at least size + HEADROOM bytes available
- * ahead of dst */
-static CHARP guarantee(CHARP_DST int size)
-{
- if (buffer + (BUFFER_SIZE-HEADROOM) - dst < size) {
- write(STDOUT_FILENO, buffer, dst - buffer);
- dst = buffer;
- }
- RETURN_DST;
-}
-
/* NB: formatters do not store terminating NUL! */
static CHARP fmt_str(CHARP_DST const char *src)
{
unsigned len = strlen(src);
- SET_DST guarantee(DST len);
dst = mempcpy(dst, src, len);
RETURN_DST;
}
-/* HEADROOM bytes after dst are available after this call */
static CHARP fmt_url(CHARP_DST const char *name)
{
while (*name) {
unsigned c = (unsigned char)*name++;
- SET_DST guarantee(DST 3);
if ((c - '0') > 9 /* not a digit */
&& ((c|0x20) - 'a') > ('z' - 'a') /* not A-Z or a-z */
&& !strchr("._-+@", c)
@@ -208,7 +206,6 @@ static CHARP fmt_url(CHARP_DST const char *name)
RETURN_DST;
}
-/* HEADROOM bytes are available after dst after this call */
static CHARP fmt_html(CHARP_DST const char *name)
{
while (*name) {
@@ -220,7 +217,6 @@ static CHARP fmt_html(CHARP_DST const char *name)
else if (c == '&') {
SET_DST fmt_str(DST "&amp;");
} else {
- SET_DST guarantee(DST 1);
*dst++ = c;
continue;
}
@@ -244,7 +240,6 @@ static CHARP fmt_ull(CHARP_DST unsigned long long n)
RETURN_DST;
}
-/* Does not call guarantee - eats into headroom instead */
static CHARP fmt_02u(CHARP_DST unsigned n)
{
/* n %= 100; - not needed, callers don't pass big n */
@@ -254,7 +249,6 @@ static CHARP fmt_02u(CHARP_DST unsigned n)
RETURN_DST;
}
-/* Does not call guarantee - eats into headroom instead */
static CHARP fmt_04u(CHARP_DST unsigned n)
{
/* n %= 10000; - not needed, callers don't pass big n */
@@ -401,7 +395,7 @@ int main(int argc, char **argv)
SET_DST fmt_ull(DST cdir->D_SIZE);
SET_DST fmt_str(DST "<td class=dt>");
if (sizeof(cdir->D_MTIME) == sizeof(tt))
- ptm = gmtime(&cdir->D_MTIME);
+ ptm = gmtime((time_t*)&cdir->D_MTIME);
else {
tt = cdir->D_MTIME;
ptm = gmtime(&tt);
@@ -413,6 +407,12 @@ int main(int argc, char **argv)
SET_DST fmt_02u(DST ptm->tm_min); *dst++ = ':';
SET_DST fmt_02u(DST ptm->tm_sec);
*dst++ = '\n';
+
+ /* Flush after every 256 files (typically around 50k of output) */
+ if ((dir_list_count & 0xff) == 0) {
+ full_write(STDOUT_FILENO, buffer, dst - buffer);
+ dst = buffer;
+ }
}
SET_DST fmt_str(DST "<tr class=foot><th class=cnt>Files: ");
@@ -424,7 +424,8 @@ int main(int argc, char **argv)
SET_DST fmt_ull(DST size_total);
SET_DST fmt_str(DST "<th class=dt>\n");
/* "</table></body></html>" - why bother? */
- SET_DST guarantee(DST BUFFER_SIZE * 2); /* flush */
+
+ full_write(STDOUT_FILENO, buffer, dst - buffer);
return 0;
}
networking/httpd_ratelimit_cgi.c+3 -16
@@ -39,31 +39,18 @@ httpd_ratelimit_cgi.c -o httpd_ratelimit_cgi
#include <sys/stat.h> /* mkdir */
#include <limits.h>
-static ssize_t full_write(int fd, const void *buf, size_t len)
+static void full_write(int fd, const void *buf, size_t len)
{
ssize_t cc;
- ssize_t total;
-
- total = 0;
while (len) {
cc = write(fd, buf, len);
- if (cc < 0) {
- if (total) {
- /* we already wrote some! */
- /* user can do another write to know the error code */
- return total;
- }
- return cc; /* write() returns -1 on failure. */
- }
-
- total += cc;
+ if (cc < 0)
+ return;
buf = ((const char *)buf) + cc;
len -= cc;
}
-
- return total;
}
static void full_write2(int fd, const char *msg, const char *msg2)