in include/linux/spinlock_types.h
the definition of spinlock_t like below
typedef struct spinlock {
union {
struct raw_spinlock rlock;
struct {
u8 __padding[];
struct lockdep_map dep_map;
};
};
} spinlock_t;
why the "__padding[]" and "dep_map" variable should put inside a struct which has no name
but not just like below?
typedef struct spinlock {
union {
struct raw_spinlock rlock;
u8 __padding[];
struct lockdep_map dep_map;
};
} spinlock_t;
is there any special meaning?
thank you
Because it is union of two structures and the other structure is enabled during debugging.
What you are trying to do is creating structure members that are not needed at all.And you should understand in union of two structures we can use one at a time.
typedef struct spinlock {
union {
struct raw_spinlock rlock;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map))
struct {
u8 __padding[LOCK_PADSIZE];
struct lockdep_map dep_map;
};
#endif
};
} spinlock_t;
Related
I'm trying to recreate a C struct with mixed bitfield members and "normal" members in Rust for FFI.
I've read that the bitflags crate would be the one to go with, unfortunately I find the documentation lacking on the regards how the syntax actually works.
The bitflags crate makes it easier to create bitmasks in a similar style as in C using enums. The bitfield crate claims to create bitfields that can be accessed, however I have no idea how it works.
I have a C structure like this:
struct mixed {
unsigned int flag_1_1 : 1;
unsigned int flag_2_7 : 7;
unsigned int flag_3_8 : 8;
unsigned int some_val1;
unsigned int some_val2;
unsigned int flag_4_16 : 16;
};
I have no clue on how to represent it in Rust, I'd use the crate libc to have access to c_uint, but other than that, I'm currently pretty much out of ideas and finding other code that does this has not proven successful:
#[repr(transparent)] // do I also need repr(C) ?
struct mixed {
flags_1_3: mixed_flags_1_3;
some_val1: c_uint;
some_val2: c_uint;
flags_4: mixed_flags_4;
}
bitfield!(
#[repr(transparent)] // do I also need repr(C), here too?
struct mixed_flags_1_3(u16 /* what about this parameter? */) {
u8; // what does this mean?
/* get/field, set: first bit, last bit; */
flag_1_1, _: 0, 0;
flag_2_7, _: 7, 1;
flag_3_8, _: 15, 8;
}
)
bitfield!(
#[repr(transparent)]
struct mixed_flags_4(u8) {
u8;
flag_4_16, _: 15, 0;
}
)
These are just guesses, how do I create a correct representation?
In cases like this you can look at genearted code by bindgen:
$ bindgen test.h
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
storage: Storage,
align: [Align; 0],
}
//skipped code with access method for bit fields
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct mixed {
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize], u8>,
pub some_val1: ::std::os::raw::c_uint,
pub some_val2: ::std::os::raw::c_uint,
pub _bitfield_2: __BindgenBitfieldUnit<[u8; 2usize], u16>,
pub __bindgen_padding_0: u16,
}
Using rustc -- -Z unstable-options --pretty=expanded I think I could figure out that the macro does, and this seems to yield something that could be correct, however this is probably only compatible when the compiler does not try to pad or reorder the bitfields in the struct.
#[repr(transparent)] // do I also need repr(C) ?
struct mixed {
flags_1_3: mixed_flags_1_3;
some_val1: c_uint;
some_val2: c_uint;
flags_4: mixed_flags_4;
}
bitfield!(
#[repr(transparent)] // do I also need repr(C), here too?
// Results in a "tuple struct", ie. u16 = total size of bitfields
struct mixed_flags_1_3(u16) {
// All the following fields value should be treated as an
// unsigned int when accessed
c_uint;
/* get/field, set: first bit, last bit; */
flag_1_1, _: 0, 0;
flag_2_7, _: 7, 1;
// One could change the type again here, if one wanted to:
// u16
flag_3_8, _: 15, 8;
}
)
bitfield!(
#[repr(transparent)]
struct mixed_flags_4(u16) {
c_uint;
flag_4_16, _: 15, 0;
}
)
But for now at least I think I will just use libclang and bindgen as dependencies and generate my bindings automatically, due to the aforementioned problems with platform compat.
I would like to wrap a Rust struct in a C++ class.
Rust:
#[repr(C)]
pub struct RustStruct {
num: i32,
// other members..
}
pub extern "C" fn update(rust_struct: *mut RustStruct) {
(*rust_struct).num = 1i32;
}
extern "C" {
void update(void*);
}
C++:
class Wrapper {
public:
Wrapper();
// ..
private:
void* rustStruct;
// ..
};
Wrapper::Wrapper() {
update(rustStruct); // crash
}
int main() {
std::cout << "Testing..";
}
I understand why this wouldn't work. My question is: how can I achieve what I'm basically trying to do (wrap a rust struct in a c++ class)?
There is a mix of multiple FFIs concepts in your answer, so first let me recommend that your read the Reference.
There are two ways to achieve what you wish, you can either:
use a POD struct (Plain Old Data), aka C-compatible struct
use an opaque pointer (void* in C)
Mixing them, as you did, does not make sense.
Which to pick?
Both solutions have advantages and disadvantages, it's basically an expressiveness versus performance trade-off.
On the one hand, opaque pointers are more expressive: they can point to any Rust type. However:
they require dynamic memory allocation
they require being manipulated by Rust functions (so always indirectly from C or C++)
On the other hand, POD struct do not require either of those, but they are limited to only a subset of types expressible in Rust.
How to use a POD?
This is the easiest, actually, so let's start with it!
In Rust:
#[repr(C)]
pub struct RustStruct {
num: i32,
// other members, also PODs!
}
In C++
struct RustStruct {
int32_t num;
// other members, also with Standard Layout
// http://en.cppreference.com/w/cpp/types/is_standard_layout
};
class Wrapper {
public:
private:
RustStruct rustStruct;
};
Note that I just got along with your question stricto censu here, you could actually merge the two in a single C++ class:
class RustStruct {
public:
private:
int32_t num;
// other members, also with Standard Layout
// http://en.cppreference.com/w/cpp/types/is_standard_layout
};
Just avoid virtual methods.
How to use an opaque pointer?
This gets trickier:
Only the Rust code may correctly create/copy/destruct the type
Beware of leaking...
So, we need to implement a lot of functions in Rust:
#![feature(box_raw, box_syntax)]
use std::boxed;
pub struct RustStruct {
num: i32,
// other members, anything goes
}
pub extern "C" fn createRustStruct() -> *mut RustStruct {
boxed::into_raw(box RustStruct::new())
}
pub extern "C" fn destroyRustStruct(o: *mut RustStruct) {
boxed::from_raw(o);
}
Alright... now on to C++:
struct RustStruct;
RustStruct* createRustStruct();
void destroyRustStruct(RustStruct*);
class Wrapper {
public:
Wrapper(): rustStruct(RustStructPtr(createRustStruct())) {}
private:
struct Deleter {
void operator()(RustStruct* rs) const {
destroyRustStruct(rs);
}
};
typedef std::unique_ptr<RustStruct, Deleter> RustStructPtr;
RustStructPtr rustStruct;
}; // class Wrapper
So, yes, a bit more involved, and Wrapper is not copyable either (copy has to be delegated to Rust too). Anyway, this should get you started!
Note: if you have a lot of opaque pointers to wrap, a templated C++ class taking the copy/destroy functions as template parameters could alleviate a lot of boiler plate.
I want to implement multiple hrtimers, but I'm not sure how to use all of them with same callback function. For example I have array of type my_struct where one of the field is a struct hrtimer.
When I enter the callback function how to determine which element of the array is calling it?
Use the container_of macro:
struct my_struct {
int my_something;
struct hrtimer my_timer;
...
};
enum hrtimer_restart my_callback(struct hrtimer *hrtimer)
{
struct my_struct my = container_of(hrtimer, struct my_struct, my_timer);
my->my_something = 42;
...
}
i'm trying to study the linux kernel and reading the kernel code,
but i can't understand the structure they use for the page structure as shown below:
i mean,why they use union nested in the struct which nested in the union
(the code is simplified...)
struct page {
unsigned long flags;
struct address_space *mapping;
struct {
union {
pgoff_t index;
void *freelist;
};
union {
unsigned counters;
struct {
union {
atomic_t _mapcount;
struct {
unsigned inuse:16;
unsigned objects:15;
unsigned frozen:1;
};
};
atomic_t _count;
};
};
};
}
It is used to bring clarity into the code. It will be easier to read and understand if members are grouped.
Since you are not using the 'sub-structures' in any other data-structure, they are nested. Else, they would be declared separate and included as members, like below:
struct list_based{
pgoff_t index;
void *freelist;
};
struct page {
unsigned long flags;
struct address_space *mapping;
struct list_based lpage;
};
struct sector {
unsigned long sub sect;
struct list_based lsect;
};
I know if we have task_struct, surly we can get the contained sched_entity because it's one field in the task struct. But can we get the pointer to the task_struct given the shed_entity? Following is the sched_entity structure:
struct sched_entity {
struct load_weight load; /* for load-balancing */
struct rb_node run_node;
struct list_head group_node;
unsigned int on_rq;
u64 exec_start;
u64 sum_exec_runtime;
u64 vruntime;
u64 prev_sum_exec_runtime;
u64 nr_migrations;
#ifdef CONFIG_SCHEDSTATS
struct sched_statistics statistics;
#endif
#ifdef CONFIG_FAIR_GROUP_SCHED
struct sched_entity *parent;
/* rq on which this entity is (to be) queued: */
struct cfs_rq *cfs_rq;
/* rq "owned" by this entity/group: */
struct cfs_rq *my_q;
#endif
};
It seems that there is no place where I can get the task_struct. My final goal is to get the sched_entity of the task group_leader containing the task with this shed_entity :>
The Linux kernel code provides a standard way to take a pointer to an element contained within a structure, and get back a pointer to the containing structure: the container_of macro, which is used extensively throughout the kernel.
In this case, if you have a struct sched_entity *foo, you can get the enclosing task_struct with:
struct task_struct *task = container_of(foo, struct task_struct, se);
(Obviously this is only safe if you know for sure that the original struct sched_entity * pointer is pointing to a struct sched_entity which is inside a struct task_struct, so be careful...)