examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

aio.cpp (1498B)


      1 #include <iostream>
      2 #include <vector>
      3 #include <iomanip>
      4 
      5 #include <aio.h>
      6 #include <fcntl.h>
      7 #include <sys/stat.h>
      8 #include <dirent.h>
      9 
     10 struct x
     11 {
     12 	struct aiocb a;
     13 	dirent e;
     14 	char buf[];
     15 };
     16 
     17 int main(int argc, char* argv[])
     18 {
     19 	DIR* d = opendir(".");
     20 	int dfd = dirfd(d);
     21 
     22 	std::vector<struct aiocb*> liop;
     23 
     24 	while (auto e = readdir(d))
     25 	{
     26 		if (DT_REG != e->d_type)
     27 			continue;
     28 
     29 		int f = openat(dfd, e->d_name, O_RDONLY);
     30 
     31 		struct stat s;
     32 		fstat(f, &s);
     33 
     34 		struct x* buf = (struct x*)malloc(sizeof(struct x) + s.st_size);
     35 		buf->a = {f, LIO_READ, 0, &buf->buf, (size_t)s.st_size, {SIGEV_NONE}, 0};
     36 		buf->e = *e;
     37 
     38 		liop.push_back(&buf->a);
     39 	}
     40 
     41 	lio_listio(LIO_NOWAIT, liop.data(), liop.size(), NULL);
     42 
     43 	int outstanding = liop.size();
     44 	int cycles = 0;
     45 
     46 	while (outstanding)
     47 	{
     48 		++cycles;
     49 		aio_suspend(liop.data(), liop.size(), NULL);
     50 		for (auto& iop : liop)
     51 		{
     52 			if (!iop)
     53 				continue;
     54 
     55 			size_t b = iop->aio_nbytes;
     56 			char* s = (char*)const_cast<void*>(iop->aio_buf), *end = s + b;
     57 			struct x* x = (struct x*)(s - offsetof(struct x, buf));
     58 			unsigned n = 0;
     59 
     60 			if (int err = aio_error(iop); err == EINPROGRESS)
     61 				continue;
     62 			else if (err)
     63 				exit(1);
     64 
     65 			iop = nullptr;
     66 			--outstanding;
     67 			while (s < end)
     68 				if (*s++ == '\n')
     69 					++n;
     70 
     71 			using std::cout, std::setw;
     72 
     73 			cout << setw(20) << x->e.d_name << ": " << setw(6) << b << " bytes, " << setw(4) << n << " lines, cycle " << cycles << '\n';
     74 		}
     75 	}
     76 
     77 	std::cout << "Read after " << cycles << " cycles\n";
     78 	return 0;
     79 }
     80