Here's the question and the problem I'm facing.
I had a task to create a new kernel function in OpenBSD (into syscalls.master). It is called sys_eventopen(int id). The thing is that into sys_generic.c where the function should be implemented, right into the implementation I need to modify the value of a struct variable like this:
struct resource{
int id=0;
int is_busy=0;
}res;
The thing is that I want to be able to access the res resource into the implementation of the sys_eventopen(). I want to know whether it's possible to declare a global variable into the sys_generic.c so that I can access it into the function or rewrite all the functions so that I could send that variable as a parameter. Thanks in advance.
Related
I've use quite a bit of JavaScript so far. If you were to use an object constructor in JavaScript, you have access to the this constructor.
So my question relates to trying to use a similar concept in C. I created a struct that I want to be able to self reference:
struct Storage {
void (*delete)();
}
So if I were to allocate a Storage class:
struct Storage *myStruct = malloc(sizeof(struct Storage));
Let's say I'm trying to delete myStruct. If I have some delete function that I point to (with myStruct->delete = deleteStructure), I would like to do something like this:
myStruct.delete();
which would then free() the struct through a self referencing variable inside of said delete function. I'm wondering if there would be a way to have the delete function look like:
void deleteStructure() {
free( /* "this" or some equivalent C self-reference */ );
}
My assumption from research so far is that this is not possible since this is usually only in object oriented programming languages. If this is not possible, I'm wondering what would be the semantically correct way to do this. I'm hoping to make the usage of this delete functionality rather simplistic from a user interface perspective. The only way I understand this to work would be passing a reference to the structure like:
void deleteStructure(struct Storage *someStructure) {
free(someStructure);
}
which would then require deletion to be done as follows:
deleteStructure(myStruct);
To sum up: is there a way to make a delete function that uses self references in C, and if not, what would be the most semantically correct way to delete a structure in the most user friendly way?
No. You cannot even define a function for a struct.
struct Storage {
void (*delete)();
}
simply stores a pointer to a void function. That could be any void function and when it is being called, it has no connection to Storage whatsoever.
Also note that in your code, every instance of the struct stores one pointer to a void function. You could initialize them so that they all point to the same function, in which case you would simply waste 64 bit per instance without any real benefit. You could also make them point to completely different functions with different semantics.
As per #UnholySheep's comment, the correct semantical use of a struct with connection to a C function will follow the structure:
struct Storage {
/* Some definitions here */
}
void deleteStructure(struct Storage *someStructure) {
free( /* all inner structure allocations */ );
free(someStructure);
}
Here's more about passing structs by reference.
In Go source I have
type T struct {
// some data
}
func (t *T)M(arg0 SomeType1) {
// some computations
}
var Obj *T
In C sources I have
// SomeType1C is equivalent to SomeType1.
typedef void (*CallbackFunc)(SomeType1C);
// callback will be called !after! register_callback function returns.
void register_callback(CallbackFunc callback);
I would like to use Obj.M as callback for register_callback in C.
On MS Windows for winapi I pass smth like C.CallbackFunc(unsafe.Pointer(syscall.NewCallback(Obj.M))) to register_callback for this (not sure is it fully correct, but at least this works). But where is no NewCallback for non-Windows systems.
PS:
I'm sure that callback is registered after T is initialised and removed before T is removed.
I may have multiple instances of T and some of them may be used to callback's 'source' at same time (so T is not some kind of singltone).
Function pointer callbacks in GoLang's wiki uses gateway function, but I don't see how to adequate use it with struct's method.
Base idea:
Use exported callback as a proxy between C and Go:
//export callback
func callback(data0 SomeType1C, data1 Data){ // data1 - data passed to register_callback_with_data
obj := convertDataToObj(data1)
obj.M(data0)
}
and register it like this:
register_callback_with_data(callback, convertObjToData(obj));
Where are 3 ways: wrong (and easy), limited (medium) and right (hard).
Wrong (and easy) way:
Pass pointer to Go struct into C (as in original answer). This is totally wrong because Go runtime can move struct in memory. Usually this operation is transparent (all Go pointers will be updated automatically). But pointers in C memory to this struct will not be updated and program may crash/UB/... when tries to use it. Do not use this way.
Limited (medium) way:
Similar to previous, but with Go struct allocated in C memory:
Obj = (*T)(C.calloc(C.size_t(unsafe.Sizeof(T{}))))
In this case Obj can not be moved by Go runtime because it is in C memory. But now if Obj has pointers to Go memory (fields with *-variables, maps, slices, channels, function-pointers, ...) then this also may cause crash/UB/... This is because:
if there are no (other) Go pointers to the same variable (memory), then Go runtime thinks that this memory is free and can be reused,
or, if there is other Go pointer to same variable (memory), then Go can move this variable in memory.
So, use this way only if struct has no pointers to Go memory. Usually this means that struct contains only primitive fields (ints, floats, bool).
Right (and hard) way:
Assign id (of integer type for example) for each object of type T and pass this id into C. In exported callback you should convert id back to object. This is right way with no limitation, so this way may be used always. But this way requires to maintain some array/slice/map to convert between objects and ids. Moreover, this convertation may require some synchronization for thread-safe (so see sync.Mutex and sync.RWMutex).
Original answer:
Not best answer and has restrictions, but no other suggested. In my case I can pass additional data to register_callback. This data will be passed back to callback on each call. So I pass unsafe.Pointer(Obj) as data and use gateway function:
//export callback
func callback(data SomeType1C, additionalData unsafe.Pointer){
obj := (*T)(additionalData) // Get original Obj (pointer to instance of T)
dataGo := *(*SomeType1)(unsafe.Pointer(&data)) // Cast data from C to Go type
obj.M(dataGo)
}
and register it like this:
register_callback_with_data(callback, unsafe.Pointer(Obj));
PS: but still want to know how to do this better in general case (without additional data).
I've been writing code, and I'm in a point where I should have another program calling my library. I should make a reference counter for the output of my library. Basic idea as I have understood is that, I need to have reference counter struct inside my struct that I want to pass around. So my questions are following:
What should I keep in mind when making a reference counter?
What are complete don'ts when making a reference counter?
Is there really detailed examples where to start with this?
Thank you for your answers in advance!
Reference counting allows clients of your library to keep reference objects created by your library on the heap and allows you to keep track of how many references are still active. When the reference count goes to zero you can safely free the memory used by the object. It is a way to implement basic "garbage collection".
In C++, you can do this more easily, by using "smart pointers" that manage the reference count through the constructor and destructor, but it sounds like you are looking to do it in C.
You need to be very clear on the protocol that you expect users of your libraries to follow when accessing your objects so that they properly communicate when a new reference is created or when a reference is no longer needed. Getting this wrong will either prematurely free memory that is still being referenced or cause memory to never be freed (memory leak).
Basically, You include a reference count in your struct, that gets incremented each time that your library returns the struct.
You also need to provide a function that releases the reference:
struct Object {
int ref;
....
}
Object* getObject (...) {
Object *p = .... // find or malloc the object
p->ref++;
return p;
}
void releaseReference (Object* p) {
p->ref--;
if (p->ref == 0) free(p);
}
void grabReference (Object* p) {
p->ref++;
}
Use grabReference() if a client of your library passes a reference to another client (in the above example, the initial caller of your library doesn't need to call grabReference())
If your code is multi-threaded then you need to make sure that you handle this correctly when incrementing or decrementing references
I have a function that is connected to the "changed" signal for a combobox in gtk, which in turn calls another function read_button_config.
The read_button_config takes the main window, a combobox and a vcontainer which I had not declared globally as parameters
Which way is better for passing these parameters:
- declaring the parameters globally
- passing the parameters as a struct to the first function, and passing the struct members to the read_button_config function?
Please let me know why you think either is better, I want to know what is a better way for future development
Which way is better for passing these parameters: - declaring the
parameters globally - passing the parameters as a struct to the first
function, and passing the struct members to the read_button_config
function?
The latter is the preferred way; that is the purpose of the user_data parameter to signal functions, after all.
Declaring them globally isn't bad. Rather, using the user_data is idiomatic. It's a bit harder since you have to manage the memory for the user_data yourself, but using user_data keeps your code modules more self-contained. You will need to decide what you want to do.
– andlabs
I have written a Simulink S-function (Level 2) in C. The resulting block has one output and one parameter. This parameter is stored in a variable, which is defined at file scope, right after setting up the block:
#define NUM_PARAMS 1
#define NUM_INPORTS 0
#define NUM_OUTPORTS 1
unsigned short int MASK_INDEX;
I assign it within mdlInitializeSizes, and do some operations on its value:
static void mdlInitializeSizes(SimStruct *S) {
// Check Parameters
ssSetNumSFcnParams(S, NUM_PARAMS);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return;
}
MASK_INDEX = *mxGetPr(ssGetSFcnParam(S, 0));
(...) operations
}
My problem is, that the variable MASK_INDEX seems to be global, and shared among all blocks of the same type. Therefore, it holds the same value for all blocks.
As a workaround, I reload it every time, and re-do the operations, for example:
static void mdlOutputs(SimStruct *S, int_T tid) {
MASK_INDEX = *mxGetPr(ssGetSFcnParam(S, 0));
(...) operations
}
How can I get a true "local variable", so that I don't have to repeat all this every time?
You haven't mentioned where you've declared MASK_INDEX, but from your description it sounds like it's at file scope. If so, then yes, this variable will be shared across all instances. This is not isolated to S-Functions in any way, it's how shared libraries on most, if not all, platforms behave. A single instance of the shared library will be loaded by an application, in this case MATLAB; consequently there is only one copy of global variables.
The easiest option is to use ssGetSFcnParam every time you want to access the parameter. If you dig into those S-Function macros, they're simply accessing fields of the SimStruct, so it's unlikely repeated access will result in performance degradation. I've even seen macros being used to wrap common use cases such as the one you have.
If you really want to go about caching the dialog parameter, the easiest is probably to use ssSetUserData. Declare a struct containing a MASK_INDEX member (you don't have to use a struct but this approach is more extensible). Dynamically allocate an instance using mxMalloc within mdlStart and assign it to the block's user data. Make sure you set SS_OPTION_CALL_TERMINATE_ON_EXIT in the ssSetOptions call in mdlInitializeSizes. Then define the mdlTerminate function within which you'll access the allocated struct using ssGetUserData and mxFree it. Now you can access the struct members within mdlOutputs using ssGetUserData.
There are other, more advanced options as well, such as work vectors, probably a PWork vector.
Another option, if your parameter is tunable, is using runtime parameters, which let you cache, and optionally transform, a block's dialog parameters.
In your case, I'd just stick with using ssGetSFcnParam every time within mdlOutputs.