Re: Compiling C++ modules

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Martin Mares wrote:
Hello!

But it executed C++ code within a few cycles of entering the reset vector (no standard BIOS), including but not limited to: programming the memory controller (430MX chipset), servicing interrupts, hardware accelerated 2D graphics (C&T 65550), IDE driver, simple filesystem, simple windowing GUI, network driver (Tulip) etc.

I really don't claim it's impossible to write kernels in C++ -- it's
clearly possible given that everything you can do in C, you can do in
C++ as well. But what I argued about is whether kernel programming in C++
can be easier and more efficient, which is why I wanted you to show
some examples. Real code speaks better than thousand theories.


Here are three versions of do_sendfile(). When you read it, please assume you know light_file_ptr as well as you know f{get,put}_light, etc.

The (IMO) improvement is not dramatic since this is fairly much straight line code.

static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
			   size_t count, loff_t max)
{
	struct file * in_file, * out_file;
	struct inode * in_inode, * out_inode;
	loff_t pos;
	ssize_t retval;
	int fput_needed_in, fput_needed_out;

	/*
	 * Get input file, and verify that it is ok..
	 */
	retval = -EBADF;
	in_file = fget_light(in_fd, &fput_needed_in);
	if (!in_file)
		goto out;
	if (!(in_file->f_mode & FMODE_READ))
		goto fput_in;
	retval = -EINVAL;
	in_inode = in_file->f_dentry->d_inode;
	if (!in_inode)
		goto fput_in;
	if (!in_file->f_op || !in_file->f_op->sendfile)
		goto fput_in;
	retval = -ESPIPE;
	if (!ppos)
		ppos = &in_file->f_pos;
	else
		if (!(in_file->f_mode & FMODE_PREAD))
			goto fput_in;
	retval = rw_verify_area(READ, in_file, ppos, count);
	if (retval < 0)
		goto fput_in;
	count = retval;

	retval = security_file_permission (in_file, MAY_READ);
	if (retval)
		goto fput_in;

	/*
	 * Get output file, and verify that it is ok..
	 */
	retval = -EBADF;
	out_file = fget_light(out_fd, &fput_needed_out);
	if (!out_file)
		goto fput_in;
	if (!(out_file->f_mode & FMODE_WRITE))
		goto fput_out;
	retval = -EINVAL;
	if (!out_file->f_op || !out_file->f_op->sendpage)
		goto fput_out;
	out_inode = out_file->f_dentry->d_inode;
	retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
	if (retval < 0)
		goto fput_out;
	count = retval;

	retval = security_file_permission (out_file, MAY_WRITE);
	if (retval)
		goto fput_out;

	if (!max)
		max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);

	pos = *ppos;
	retval = -EINVAL;
	if (unlikely(pos < 0))
		goto fput_out;
	if (unlikely(pos + count > max)) {
		retval = -EOVERFLOW;
		if (pos >= max)
			goto fput_out;
		count = max - pos;
	}

	retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);

	if (retval > 0) {
		current->rchar += retval;
		current->wchar += retval;
	}
	current->syscr++;
	current->syscw++;

	if (*ppos > max)
		retval = -EOVERFLOW;

fput_out:
	fput_light(out_file, fput_needed_out);
fput_in:
	fput_light(in_file, fput_needed_in);
out:
	return retval;
}



static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
			   size_t count, loff_t max)
{
	loff_t pos;
	ssize_t retval;

	/*
	 * Get input file, and verify that it is ok..
	 */
	light_file_ptr in_file(in_fd);
	if (!in_file.valid())
		return -EBADF;
	if (!in_file->readable())
		return -EBADF;
	retval = -EINVAL;
	struct inode *in_inode = in_file->dentry()->inode();
	if (!in_inode)
		return -EINVAL;
	// I'm assuming here that the default sendfile() returns -EINVAL
	if (!ppos)
		ppos = &in_file->f_pos;
	else
		if (!(in_file->mode() & FMODE_PREAD))
			return -ESPIPE;
	retval = rw_verify_area(READ, in_file, ppos, count);
	if (retval < 0)
		return retval;
	count = retval;

	retval = security_file_permission (in_file, MAY_READ);
	if (retval)
		return retval;

	/*
	 * Get output file, and verify that it is ok..
	 */
	light_file_ptr out_file(out_fd);
	if (!out_file)
		return -EBADF;
	if (!(out_file->writable())
		return -EBADF;
	// Again, assuming default sendpage returns -EINVAL
	struct inode *out_inode = out_file->dentry()->inode();
	retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
	if (retval < 0)
		return retval;
	count = retval;

	retval = security_file_permission (out_file, MAY_WRITE);
	if (retval)
		return retval;

	if (!max)
		max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);

	pos = *ppos;
	if (unlikely(pos < 0))
		return -EINVAL;
	if (unlikely(pos + count > max)) {
		if (pos >= max)
			return -EOVERFLOW;
		count = max - pos;
	}

	retval = in_file->sendfile(ppos, count, file_send_actor, out_file);

	if (retval > 0) {
		current->rchar += retval;
		current->wchar += retval;
	}
	current->syscr++;
	current->syscw++;

	if (*ppos > max)
		return -EOVERFLOW;

	return retval;
}

// now, with exceptions
static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
			   size_t count, loff_t max)
{
	loff_t pos;

	/*
	 * Get input file, and verify that it is ok..
	 */
	light_file_ptr in_file(in_fd);
	in_file->verify_readable();
	struct inode *in_inode = in_file->dentry()->inode();
	if (!in_inode)
		throw EINVAL;
	// I'm assuming here that the default sendfile() returns -EINVAL
	if (!ppos)
		ppos = &in_file->f_pos;
	else
       in_file->verify_preadable();
	count = in_file->verify_area(READ, ppos, count);

	in_file->security_verify_permission(MAY_READ);

	/*
	 * Get output file, and verify that it is ok..
	 */
	light_file_ptr out_file(out_fd);
	out_file->verify_writable();
	// Again, assuming default sendpage returns -EINVAL
	struct inode *out_inode = out_file->dentry()->inode();
	count = out_file->verify_area(WRITE, &out_file->f_pos, count);

	out_file->security_verify_permission(MAY_WRITE);

	if (!max)
		max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);

	pos = *ppos;
	if (unlikely(pos < 0))
		throw EINVAL;
	if (unlikely(pos + count > max)) {
		if (pos >= max)
			throw EOVERFLOW;
		count = max - pos;
	}

	count = in_file->sendfile(ppos, count, file_send_actor, out_file);

	current->rchar += count;
	current->wchar += count;
	current->syscr++;
	current->syscw++;

	if (*ppos > max)
		throw EOVERFLOW;

	return count;
}


--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux