Changeset 8e4aa05 for benchmark/io/http/protocol.cfa
- Timestamp:
- Mar 4, 2021, 7:40:25 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 77d601f
- Parents:
- 342af53 (diff), a5040fe (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
benchmark/io/http/protocol.cfa
r342af53 r8e4aa05 5 5 #include <fcntl.h> 6 6 } 7 8 #include <fstream.hfa> 7 9 #include <iofwd.hfa> 8 10 … … 11 13 extern "C" { 12 14 int snprintf ( char * s, size_t n, const char * format, ... ); 13 #include <linux/io_uring.h>15 // #include <linux/io_uring.h> 14 16 } 15 17 #include <string.h> … … 18 20 #include "options.hfa" 19 21 20 const char * volatile date = 0p; 21 22 const char * http_msgs[] = { 23 "HTTP/1.1 200 OK\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: %zu \n\n", 24 "HTTP/1.1 400 Bad Request\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",25 "HTTP/1.1 404 Not Found\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",26 "HTTP/1.1 413 Payload Too Large\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 27 "HTTP/1.1 414 URI Too Long\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 28 };22 #define PLAINTEXT_1WRITE 23 #define PLAINTEXT_NOCOPY 24 25 struct https_msg_str { 26 char msg[512]; 27 size_t len; 28 }; 29 30 const https_msg_str * volatile http_msgs[KNOWN_CODES] = { 0 }; 29 31 30 32 _Static_assert( KNOWN_CODES == (sizeof(http_msgs ) / sizeof(http_msgs [0]))); 31 33 32 const int http_codes[] = { 34 const int http_codes[KNOWN_CODES] = { 35 200, 33 36 200, 34 37 400, 35 38 404, 39 405, 40 408, 36 41 413, 37 42 414, … … 47 52 while(len > 0) { 48 53 // Call write 49 int ret = cfa_write(fd, it, len, 0, -1`s, 0p, 0p); 50 // int ret = write(fd, it, len); 51 if( ret < 0 ) { if( errno != EAGAIN && errno != EWOULDBLOCK) abort( "'answer error' error: (%d) %s\n", (int)errno, strerror(errno) ); } 54 int ret = cfa_send(fd, it, len, 0, CFA_IO_LAZY); 55 if( ret < 0 ) { 56 if( errno == ECONNRESET || errno == EPIPE ) return -ECONNRESET; 57 if( errno == EAGAIN || errno == EWOULDBLOCK) return -EAGAIN; 58 59 abort( "'answer error' error: (%d) %s\n", (int)errno, strerror(errno) ); 60 } 52 61 53 62 // update it/len … … 61 70 /* paranoid */ assert( code < KNOWN_CODES && code != OK200 ); 62 71 int idx = (int)code; 63 return answer( fd, http_msgs[idx] , strlen( http_msgs[idx] ));72 return answer( fd, http_msgs[idx]->msg, http_msgs[idx]->len ); 64 73 } 65 74 66 75 int answer_header( int fd, size_t size ) { 67 const char * fmt = http_msgs[OK200]; 68 int len = 200; 69 char buffer[len]; 70 len = snprintf(buffer, len, fmt, date, size); 76 char buffer[512]; 77 char * it = buffer; 78 memcpy(it, http_msgs[OK200]->msg, http_msgs[OK200]->len); 79 it += http_msgs[OK200]->len; 80 int len = http_msgs[OK200]->len; 81 len += snprintf(it, 512 - len, "%d \n\n", size); 71 82 return answer( fd, buffer, len ); 72 83 } 73 84 74 int answer_plain( int fd, char buffer[], size_t size ) { 75 int ret = answer_header(fd, size); 85 #if defined(PLAINTEXT_NOCOPY) 86 int answer_plaintext( int fd ) { 87 return answer(fd, http_msgs[OK200_PlainText]->msg, http_msgs[OK200_PlainText]->len + 1); // +1 cause snprintf doesn't count nullterminator 88 } 89 #elif defined(PLAINTEXT_1WRITE) 90 int answer_plaintext( int fd ) { 91 char text[] = "Hello, World!\n"; 92 char buffer[512 + sizeof(text)]; 93 char * it = buffer; 94 memcpy(it, http_msgs[OK200]->msg, http_msgs[OK200]->len); 95 it += http_msgs[OK200]->len; 96 int len = http_msgs[OK200]->len; 97 int r = snprintf(it, 512 - len, "%d \n\n", sizeof(text)); 98 it += r; 99 len += r; 100 memcpy(it, text, sizeof(text)); 101 return answer(fd, buffer, len + sizeof(text)); 102 } 103 #else 104 int answer_plaintext( int fd ) { 105 char text[] = "Hello, World!\n"; 106 int ret = answer_header(fd, sizeof(text)); 76 107 if( ret < 0 ) return ret; 77 return answer(fd, buffer, size); 78 } 108 return answer(fd, text, sizeof(text)); 109 } 110 #endif 79 111 80 112 int answer_empty( int fd ) { … … 83 115 84 116 85 [HttpCode code, bool closed, * const char file, size_t len] http_read(int fd, []char buffer, size_t len , io_cancellation * cancel) {117 [HttpCode code, bool closed, * const char file, size_t len] http_read(int fd, []char buffer, size_t len) { 86 118 char * it = buffer; 87 119 size_t count = len - 1; … … 89 121 READ: 90 122 for() { 91 int ret = cfa_re ad(fd, (void*)it, count, 0, -1`s, cancel, 0p);123 int ret = cfa_recv(fd, (void*)it, count, 0, CFA_IO_LAZY); 92 124 // int ret = read(fd, (void*)it, count); 93 125 if(ret == 0 ) return [OK200, true, 0, 0]; 94 126 if(ret < 0 ) { 95 127 if( errno == EAGAIN || errno == EWOULDBLOCK) continue READ; 96 // if( errno == EINVAL ) return [E400, true, 0, 0]; 128 if( errno == ECONNRESET ) return [E408, true, 0, 0]; 129 if( errno == EPIPE ) return [E408, true, 0, 0]; 97 130 abort( "read error: (%d) %s\n", (int)errno, strerror(errno) ); 98 131 } … … 108 141 } 109 142 110 if( options.log ) printf("%.*s\n", rlen, buffer); 143 if( options.log ) { 144 write(sout, buffer, rlen); 145 sout | nl; 146 } 111 147 112 148 it = buffer; … … 119 155 } 120 156 121 voidsendfile( int pipe[2], int fd, int ans_fd, size_t count ) {157 int sendfile( int pipe[2], int fd, int ans_fd, size_t count ) { 122 158 unsigned sflags = SPLICE_F_MOVE; // | SPLICE_F_MORE; 123 159 off_t offset = 0; 124 160 ssize_t ret; 125 161 SPLICE1: while(count > 0) { 126 ret = cfa_splice(ans_fd, &offset, pipe[1], 0p, count, sflags, 0, -1`s, 0p, 0p); 127 // ret = splice(ans_fd, &offset, pipe[1], 0p, count, sflags); 162 ret = cfa_splice(ans_fd, &offset, pipe[1], 0p, count, sflags, CFA_IO_LAZY); 128 163 if( ret < 0 ) { 129 164 if( errno != EAGAIN && errno != EWOULDBLOCK) continue SPLICE1; 165 if( errno == ECONNRESET ) return -ECONNRESET; 166 if( errno == EPIPE ) return -EPIPE; 130 167 abort( "splice [0] error: (%d) %s\n", (int)errno, strerror(errno) ); 131 168 } … … 135 172 size_t in_pipe = ret; 136 173 SPLICE2: while(in_pipe > 0) { 137 ret = cfa_splice(pipe[0], 0p, fd, 0p, in_pipe, sflags, 0, -1`s, 0p, 0p); 138 // ret = splice(pipe[0], 0p, fd, 0p, in_pipe, sflags); 174 ret = cfa_splice(pipe[0], 0p, fd, 0p, in_pipe, sflags, CFA_IO_LAZY); 139 175 if( ret < 0 ) { 140 176 if( errno != EAGAIN && errno != EWOULDBLOCK) continue SPLICE2; 177 if( errno == ECONNRESET ) return -ECONNRESET; 178 if( errno == EPIPE ) return -EPIPE; 141 179 abort( "splice [1] error: (%d) %s\n", (int)errno, strerror(errno) ); 142 180 } … … 145 183 146 184 } 185 return count; 147 186 } 148 187 … … 153 192 #include <thread.hfa> 154 193 194 const char * original_http_msgs[] = { 195 "HTTP/1.1 200 OK\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: ", 196 "HTTP/1.1 200 OK\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 15\n\nHello, World!\n", 197 "HTTP/1.1 400 Bad Request\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 198 "HTTP/1.1 404 Not Found\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 199 "HTTP/1.1 405 Method Not Allowed\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 200 "HTTP/1.1 408 Request Timeout\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 201 "HTTP/1.1 413 Payload Too Large\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 202 "HTTP/1.1 414 URI Too Long\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 203 }; 204 155 205 struct date_buffer { 156 char buff[100];206 https_msg_str strs[KNOWN_CODES]; 157 207 }; 158 208 … … 163 213 164 214 void ?{}( DateFormater & this ) { 165 ((thread&)this){ "Server Date Thread", *options.clopts.instance };215 ((thread&)this){ "Server Date Thread", *options.clopts.instance[0] }; 166 216 this.idx = 0; 167 memset( this.buffers[0].buff, 0, sizeof(this.buffers[0]) );168 memset( this.buffers[1].buff, 0, sizeof(this.buffers[1]) );217 memset( &this.buffers[0], 0, sizeof(this.buffers[0]) ); 218 memset( &this.buffers[1], 0, sizeof(this.buffers[1]) ); 169 219 } 170 220 … … 176 226 or else {} 177 227 228 229 char buff[100]; 178 230 Time now = getTimeNsec(); 179 180 strftime( this.buffers[this.idx].buff, 100, "%a, %d %b %Y %H:%M:%S %Z", now ); 181 182 char * next = this.buffers[this.idx].buff; 183 __atomic_exchange_n((char * volatile *)&date, next, __ATOMIC_SEQ_CST); 231 strftime( buff, 100, "%a, %d %b %Y %H:%M:%S %Z", now ); 232 sout | "Updated date to '" | buff | "'"; 233 234 for(i; KNOWN_CODES) { 235 size_t len = snprintf( this.buffers[this.idx].strs[i].msg, 512, original_http_msgs[i], buff ); 236 this.buffers[this.idx].strs[i].len = len; 237 } 238 239 for(i; KNOWN_CODES) { 240 https_msg_str * next = &this.buffers[this.idx].strs[i]; 241 __atomic_exchange_n((https_msg_str * volatile *)&http_msgs[i], next, __ATOMIC_SEQ_CST); 242 } 184 243 this.idx = (this.idx + 1) % 2; 244 245 sout | "Date thread sleeping"; 185 246 186 247 sleep(1`s);
Note:
See TracChangeset
for help on using the changeset viewer.