【问题标题】:generic stack implementation in linux coreLinux内核中的通用堆栈实现
【发布时间】:2017-09-03 17:36:52
【问题描述】:

我正在为 bcache Linux 模块编写一个补丁,并且很难在 Linux 核心中找到通用的 LIFO 实现。我在defineswithout 上都找到了几个FIFO 实现。然而,后进先出没有什么相似之处。

在哪里可以找到一个?最好 C 不是 asm,也不是基于定义,但任何都应该工作。

如果没有提供抽象的 LIFO,那么最容易实现 LIFO 的结构是什么(例如 Linux 内核中的通用堆栈实现)?

【问题讨论】:

  • 一个数组加上一个索引可能太微不足道而无法概括?
  • "not based on defined" - 你将如何在 C 中实现通用数据结构?你想要带有函数指针的“虚拟方法”吗?我不会把这个开销放在内核中。
  • @wildplasser 我想这将是我的下一步行动。我无法摆脱我正在重新发明一辆自行车的感觉,LIFO 被广泛使用以至于它已经 to be in Linux 内核。

标签: c linux stack


【解决方案1】:

如果 LIFO 具有固定的最大深度,并且不是动态分配的,那么它就像

#define LIFO_MAXDEPTH  16

static spinlock_t   lifo_lock = SPIN_LOCK_UNLOCKED;
static size_t       lifo_count = 0;
static struct item  lifo_entry[LIFO_MAXDEPTH];

int lifo_push(const struct item *from)
{
    spin_lock(&lifo_lock);
    if (lifo_count >= LIFO_MAXDEPTH) {
        spin_unlock(&lifo_lock);
        return -1;
    }

    lifo_entry[lifo_count++] = *from;

    spin_unlock(&lifo_lock);
    return 0;
}

int lifo_pop(struct item *to)
{
    spin_lock(&lifo_lock);
    if (lifo_count < 1) {
        spin_unlock(&lifo_lock);
        return -1;
    }

    *to = lifo_entry[--lifo_count];

    spin_unlock(&lifo_lock);
    return 0;
}

因为我们只需要将其锁定很短的时间,自旋锁就足够了。

如果 LIFO 是动态分配的,事情会变得更加复杂。特别是,因为我们可能不得不调用kmalloc()kfree(),所以我们不能使用自旋锁。您还希望将堆栈拆分为页面大小的块,因为高阶分配可能会失败。然后您必须考虑诸如恶意用户试图使用该工具进行 DOS 攻击等事情。

【讨论】:

  • 感谢您的建议。不幸的是,深度仅在运行时才知道(因为堆栈的深度取决于块大小和缓存大小并且可能很大)。顺便说一句,所有的同步都已经通过 bcache 模块中的互斥体编写了,我只需要在 LIFO 本身周围玩耍 - 推送、弹出、窥视、清理等等。
猜你喜欢
  • 2016-04-05
  • 2020-04-24
  • 2017-07-27
  • 1970-01-01
  • 2015-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多