Can there be two 'uvm_tlm_b_target_socket' and two corresponding 'b_transport' implementation in a single object? - uvm

I have a requirement where I need to have two uvm_tlm_b_target_socket in class as it going to receive transaction from two different agents. I need to process the data received from two sockets differently so I cannot have a single implementation of b_transport task. Is there anything equivalent for target socket to terminator of analysis ports were we can use uvm_analysis_imp_decl macro which allow us to have a different implementation of write function? In the class reference manual I could find this macro uvm_blocking_transport_imp_decl but couldn't find an example of how to use this. In summary I am trying to do this
uvm_tlm_b_target_socket A;
umv_tlm_b_target_socket B;
// b_transport task implementation for socket "A"
task b_transport;
// b_transport task implementation for socket "B"
task b_transport;

uvm_tlm_b_target_socket when instantiated needs to be provided two parameters.
1) base class where the implementation - b_transport resides
2) the other is the data item itself.
uvm_tlm_b_target_socket #(receiver, data_item) A;
You can only have 1 transport_b function in your receiver class .
But you can use a wrapper class to connect the other functions in your receiver class to other target sockets.
typedef class receiver; // name of the parent class processing the transport call.
class connect_transport ; // does not need to be a component but if you need it can - extends uvm_component;
receiver m_parent; // parent class
function new(string name = "receiver", receiver parent = null);
m_parent = parent; // connect the parent class
endfunction
task b_transport(data_item data, uvm_tlm_time delay);
// transport_b for B.
m_parent.b_transport_b(data,delay); // call the function in the parent class.
endtask
endclass
in the receiver class
class receiver extends umm_component ;
`uvm_component_utils(receiver)
connect_transport c1;
.....
uvm_tlm_b_target_socket #(receiver, data_item) A; // connects to the local b_transport function
uvm_tlm_b_target_socket #(connect_transport, data_item) B; // connect to the wrapper class
function new(string name = "receiver", uvm_component parent = null);
super.new(name, parent);
A = new("A", this);
c1 = new ("c1",this); // create the connecting class
B = new("B", this,c1); // connect the target socket to the connecting class
endfunction
//for socket B
task b_transport_b(data_item data, uvm_tlm_time delay);
......
end task
// will be connected to A socket.
task b_transport(data_item data, uvm_tlm_time delay);
......
end task
endclass
You can wrap this into a macro , and have an _imp_decl kind of implementation.
You could also implement the check directly in the connect_transport.

Aside from the classical TLM2 sockets, there are also *_transport_imps. As far as I could tell, these do the same thing as sockets. You use the *_decl macro just like you use uvm_analysis_imp_decl:
class some_class;
`uvm_blocking_transport_imp_decl(_a)
`uvm_blocking_transport_imp_decl(_a)
uvm_transport_imp_a A;
umv_transport_imp_b B;
task b_transport_a(...);
task b_transport_b(...);
endclass

Related

Windows Filtering Platform: ClassifyFn BSOD at DISPATCH_LEVEL

I'm trying to implement a simple firewall which filters network connections made by Windows processes.
The firewall should either allow/block the connection.
In order to intercept connections by any process, I created a kernel driver which makes use of Windows Filtering Platform.
I registered a ClassifyFn (FWPS_CALLOUT_CLASSIFY_FN1) callback at the filtering layer FWPM_LAYER_ALE_AUTH_CONNECT_V4:
FWPM_CALLOUT m_callout = { 0 };
m_callout.applicableLayer = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
...
status = FwpmCalloutAdd(filter_engine_handle, &m_callout, NULL, NULL);
The decision regarding connection allow/block should be taken by userlevel.
I communicate with Userlevel using FltSendMessage,
which cannot be used at IRQL DISPATCH_LEVEL.
Following the instructions of the Microsoft documentation regarding how to process callouts asynchronously,
I do call FwpsPendOperation0 before calling FltSendMessage.
After the call to FltSendMessage, I resume packet processing by calling FwpsCompleteOperation0.
FwpsPendOperation0 documentation states that calling this function should make possible to operate calls at PASSIVE_LEVEL:
A callout can pend the current processing operation on a packet when
the callout must perform processing on one of these layers that may
take a long interval to complete or that should occur at IRQL =
PASSIVE_LEVEL if the current IRQL > PASSIVE_LEVEL.
However, when the ClassifyFn callback is called at DISPATCH_LEVEL, I do sometimes still get a BSOD on FltSendMessage (INVALID_PROCESS_ATTACH_ATTEMPT).
I don't understand what's wrong.
Thank you in advance for any advice which could point me to the right direction.
Here is the relevant code of the ClassifyFn callback:
/*************************
ClassifyFn Function
**************************/
void example_classify(
const FWPS_INCOMING_VALUES * inFixedValues,
const FWPS_INCOMING_METADATA_VALUES * inMetaValues,
void * layerData,
const void * classifyContext,
const FWPS_FILTER * filter,
UINT64 flowContext,
FWPS_CLASSIFY_OUT * classifyOut)
{
NTSTATUS status;
BOOLEAN bIsReauthorize = FALSE;
BOOLEAN SafeToOpen = TRUE; // Value returned by userlevel which signals to allow/deny packet
classifyOut->actionType = FWP_ACTION_PERMIT;
remote_address = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_ADDRESS].value.uint32;
remote_port = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_PORT].value.uint16;
bIsReauthorize = IsAleReauthorize(inFixedValues);
if (!bIsReauthorize)
{
// First time receiving packet (not a reauthorized packet)
// Communicate with userlevel asynchronously
HANDLE hCompletion;
status = FwpsPendOperation0(inMetaValues->completionHandle, &hCompletion);
//
// FltSendMessage call here
// ERROR HERE:
// INVALID_PROCESS_ATTACH_ATTEMP BSOD on FltMessage call when at IRQL DISPATCH_LEVEL
//
FwpsCompleteOperation0(hCompletion, NULL);
}
if (!SafeToOpen) {
// Packet blocked
classifyOut->actionType = FWP_ACTION_BLOCK;
}
else {
// Packet allowed
}
return;
}
You need to invoke FltSendMessage() on another thread running at PASSIVE_LEVEL. You can use IoQueueWorkItem() or implement your own mechanism to process it on a system worker thread created via PsCreateSystemThread().

Lua C API - attaching data to a coroutine

Is there a way to attach data to a coroutine, or at least to somehow identify different coroutines?
I am trying to implement a timer API where the timers are controlled by the host, that looks something like the following on the Lua side:
function callback()
local timer = ElapsedTimer()
...
end
function main()
local timer = CreateTimer(...)
StartTimer(timer, callback, ...)
end
The StartTimer() call sends the timer and callback to the C side, and the C side will eventually call the callback in a new coroutine.
The call to ElapsedTimer() needs to return data that is specific to this coroutine/thread, i.e. in this case the timer.
In pseudo code:
int StartTimer(lua_State* L) {
auto timer = ...;
auto coroutine = ???
coroutine.userdata = &timer; // But probably store an actual structure with more pointers
return 0;
}
int ElapsedTimer(lua_State* L) {
auto coroutine = ???
auto timer = (Timer*)coroutine.userdata;
lua_pushlightuserdata(L, timer)
return 1;
}
This is what userdata is for:
int StartTimer(lua_State* L) {
TimerStruct timer = (TimerStruct*)lua_newuserdata(L, sizeof(TimerStruct));
//allocates some memory and returns pointer to it
timer->//...
// lua_setuservalue will let you bind the callback to the timer
return 1; //actually return it
}
Also it is going to be easier to pass the timer along
function callback(timer)
...
end
That way the lua code doesn't need to query that value. It already got it.
I just now realized I need to use lua_newthread to create the coroutine, which means I have a separate lua_State object.
This means I can always create a mapping between the coroutine's state and whatever data I want in the host language (e.g. in a map data structure)

ns2 rebroadcasting packet when timer is expired

i need to rebroadcast packet when a waiting timer is expired, i follow steps defined at How to add timer in aodv using ns2 , i define agent and timer classes; the cross reference; initialization of timer object in agent constructor; and finally expire(Event*) for class B_suppression. when the execution reach
agent->rebroadcast((Packet*)p, 0); it abort with following message 'invalid SDVCAST packet type'. is casting from Event to Packet causes the problem?
class SDVCAST;
class B_suppression_Timer : public TimerHandler {
friend class SDVCAST;
public:
B_suppression_Timer (SDVCAST *s){agent = s;};
virtual void expire (Event *p);
private:
SDVCAST *agent;
};
class SDVCAST: public Agent
{ //define object from timer
B_suppression_Timer bstimer;
}
//initialized timer in Constructor of the SDVCAST
SDVCAST::SDVCAST(nsaddr_t id) : Agent(PT_SDVCAST),
bstimer(this){
}
// start timer
void
SDVCAST::weightepersistence(Packet *p, double delay){
bstimer.resched(delay);
}
// define expire of bstimer
void
B_suppression_Timer::expire(Event *p){
agent->rebroadcast((Packet*)p, 0);
}
Add the new packet type PT_SDVCAST to common/packet.h
static const packet_t PT_ SDVCAST = 73;
// insert new packet types here
static packet_t PT_NTYPE = 74; // This MUST be the LAST one
.
.
type == PT_SDVCAST)
.
.
name_[PT_SDVCAST]= "SDVCAST"
And maybe add SDVCAST to tcl/lib/ns-packet.tcl, ns-default.tcl , ns-agent.tcl etc.
EDIT : Answer to "Segmentation fault"
"The implementation of the Packet data structure of NS2 does not math
the realities. The packet in ns2 simulation keeps all packet headers
for any protocols implemented in NS2. For example, a DSR routing
packet may keep DSDV, AODV, or even a PING application header. For
this reason, till today, a packet used in ns2 simulation, would have a
header size around 40~64KB. And NO packet would be deleted to release
the memory it holds until the end of the simulation. So for a typical
simulation with 100 nodes in ns2 around 1M packets exchanged (of
course, you may reuse the packets already being freed through
Packet::free(Packet*). To learn the implementation of it, please check
file common/packet{.h,.cc} ), you may hold 10% of it, 100K packets,
and you may use a memory at least 100K*64KB -> 6.4GB, which definitely
would crash your computer (even it is a super server)."
Etc. etc. See http://www.linuxquestions.org/questions/linux-networking-3/ns2-and-aqua-sim-4175507630/#3
http://www.linuxquestions.org/questions/tags/segmentation%20fault%20ns2/

In Linux, how do you use device_create within an existing class?

Note: I'm listing this problem as it is today, I'm not opposed to changing the implementation (moving the creation of the class to a common area for example) if it makes things easier... I'm just not sure how to do it. :End Note
I've got two linux kernel modules and I'm trying to update the /sys entries for them. Searching around on google and other sources, I've seen lots of code along the lines of:
static dev_t MyDev;
static struct class *c1;
static int __init start_func(void)
{
...
MyDev = MKDEV(nMajor, MINOR_VERSION);
register_chrdev_region(MyDev, 1, MODULE_NAME);
c1 = class_create(THIS_MODULE, "chardrv");
device_create(c1, NULL, MyDev, NULL, MODULE_NAME);
....
And I've verified for my first module this code works, and that it correctly creates a:
/sys/class/chardrv/<MODULE_NAME>
entry. What I'd like to know is how do you create a device in an existing class. In other words, one of my modules created this new chardrv class, now I want my other module to be able to also register its devices under the same class.
I can't call class_create() again (in the second module), because that "chardrv" class already exists...
So I can run a check to see if /sys/class/chardrv exists, and this can help me decide if I need to call class_create() or not, that's not a problem. Lets put some pseudo code in here to clarify:
if ( path "/sys/class/chardrv" does not exist)
new_class = class_create("chardrv")
else
new_class = some how get class "chardrv" handle, or properties, or whatever
device_create(new_class, ...)
So as per this example, if my class already exists, and I just want to add my new device into it from a second module I assume I need to create a class structure and somehow populate it with the correct "chardrv class" attributes then call device_create as before, but I'm not sure how to do that.
To use the device_create function with the same class, just pass it a pointer to the same class.
Since you want to call device_create in a different module than the one in which you create the class, you'll need to export the symbol for the pointer to the class. You can use the EXPORT_SYMBOL macro to do this.
For example:
module1.c:
extern struct class *c1; /* declare as extern */
EXPORT_SYMBOL(c1); /* use EXPORT_SYMBOL to export c1 */
static dev_t mod1_dev;
static int __init start_func(void)
{
...
/* define class here */
c1 = class_create(THIS_MODULE, "chardrv");
/* create first device */
device_create(c1, NULL, mod1_dev, NULL, "mod1_dev");
....
}
module2.c
extern struct class *c1; /* declare as extern */
static dev_t mod2_dev;
static int __init start_func(void)
{
...
/* c1 is defined in module 1 */
/* create second device */
device_create(c1, NULL, mod2_dev, NULL, "mod2_dev");
....
}
Note: You'll need to insert module1 before module2 since the class pointer is defined and exported in module1.
That should create the directories you are expecting:
/sys/class/chardrv/mod1_dev
/sys/class/chardrv/mod2_dev
By the way, if you are getting an Invalid parameters error when you try to load the second module, you might have to add a KBUILD_EXTRA_SYMBOLS line to your Makefile.
To follow your example code, you would simply call device_create() again, passing the same class, eg:
MyDev = MKDEV(nMajor, MINOR_VERSION);
register_chrdev_region(MyDev, 1, MODULE_NAME);
c1 = class_create(THIS_MODULE, "chardrv");
device_create(c1, NULL, MyDev, NULL, MODULE_NAME);
...
device_create(c1, NULL, MyDev2, NULL, "mydev2");
You should definitely not need to check the path in order to determine if the class has been created. You are creating it in your code, so simply test for c1 == NULL or use a flag if you must.
Just create the class in the module init function of your first module, export the - global - class symbol with EXPORT_SYMBOL and use it from the other module.
Since the owner of the class is your first module, every time you add a device to that class the first module's reference counter will be increased: you cannot unload it while anyone is using it.
Linux kernel won't allow to do that. This is the ERROR you will get.
**[ 865.687824] kobject_add_internal failed for net with -EEXIST, don't try to register things with the same name in the same directory.
[ 865.687835] Pid: 6382, comm: insmod Tainted: P W O 3.2.16.1JeshuLinux #1
[ 865.687840] Call Trace:
[ 865.687849] [<c1584382>] ? printk+0x2d/0x2f
[ 865.687859] [<c12a5438>] kobject_add_internal+0x138/0x1d0
[ 865.687869] [<c12a5a11>] kset_register+0x21/0x50
[ 865.687879] [<c137b63d>] __class_register+0xcd/0x1b0
[ 865.687888] [<f8d0a0aa>] hello_init+0x4a/0x80 [sysfs_Dev]
[ 865.687897] [<c1003035>] do_one_initcall+0x35/0x170
[ 865.687909] [<f8d0a060>] ? enable_show+0x40/0x40 [sysfs_Dev]
[ 865.687919] [<c10928d0>] sys_init_module+0x2c0/0x1b50
[ 865.687941] [<c159485f>] sysenter_do_call+0x12/0x28
[ 865.687947] Registering Class Failed**
If you want to understand sysfs read: [mochel.pdf](www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf)

How to create a Singleton in C?

What's the best way to create a singleton in C? A concurrent solution would be nice.
I am aware that C isn't the first language you would use for a singleton.
First, C is not suitable for OO programming. You'd be fighting all the way if you do. Secondly, singletons are just static variables with some encapsulation. So you can use a static global variable. However, global variables typically have far too many ills associated with them. You could otherwise use a function local static variable, like this:
int *SingletonInt() {
static int instance = 42;
return &instance;
}
or a smarter macro:
#define SINGLETON(t, inst, init) t* Singleton_##t() { \
static t inst = init; \
return &inst; \
}
#include <stdio.h>
/* actual definition */
SINGLETON(float, finst, 4.2);
int main() {
printf("%f\n", *(Singleton_float()));
return 0;
}
And finally, remember, that singletons are mostly abused. It is difficult to get them right, especially under multi-threaded environments...
You don't need to. C already has global variables, so you don't need a work-around to simulate them.
It's the same as the C++ version pretty much. Just have a function that returns an instance pointer. It can be a static variable inside the function. Wrap the function body with a critical section or pthread mutex, depending on platform.
#include <stdlib.h>
struct A
{
int a;
int b;
};
struct A* getObject()
{
static struct A *instance = NULL;
// do lock here
if(instance == NULL)
{
instance = malloc(sizeof(*instance));
instance->a = 1;
instance->b = 2;
}
// do unlock
return instance;
};
Note that you'd need a function to free up the singleton too. Especially if it grabs any system resources that aren't automatically released on process exit.
EDIT: My answer presumes the singleton you are creating is somewhat complex and has a multi-step creation process. If it's just static data, go with a global like others have suggested.
A singleton in C will be very weird . . . I've never seen an example of "object oriented C" that looked particularly elegant. If possible, consider using C++. C++ allows you to pick and choose which features you want to use, and many people just use it as a "better C".
Below is a pretty typical pattern for lock-free one-time initialization. The InterlockCompareExchangePtr atomically swaps in the new value if the previous is null. This protects if multiple threads try to create the singleton at the same time, only one will win. The others will delete their newly created object.
MyObj* g_singleton; // MyObj is some struct.
MyObj* GetMyObj()
{
MyObj* singleton;
if (g_singleton == NULL)
{
singleton = CreateNewObj();
// Only swap if the existing value is null. If not on Windows,
// use whatever compare and swap your platform provides.
if (InterlockCompareExchangePtr(&g_singleton, singleton, NULL) != NULL)
{
DeleteObj(singleton);
}
}
return g_singleton;
}
DoSomethingWithSingleton(GetMyObj());
Here's another perspective: every file in a C program is effectively a singleton class that is auto instantiated at runtime and cannot be subclassed.
Global static variables are your private class members.
Global non static are public (just declare them using extern in some header file).
Static functions are private methods
Non-static functions are the public ones.
Give everything a proper prefix and now you can use my_singleton_method() in lieu of my_singleton.method().
If your singleton is complex you can write a generate_singleton() method to initialize it before use, but then you need to make sure all the other public methods check if it was called and error out if not.
I think this solution might be the simplest and best for most use cases...
In this example, I am creating a single instance global dispatch queue, which you'd definitely do, say, if you were tracking dispatch source events from multiple objects; in that case, every object listening to the queue for events could be notified when a new task is added to the queue. Once the global queue is set (via queue_ref()), it can be referenced with the queue variable in any file in which the header file is included (examples are provided below).
In one of my implementations, I called queue_ref() in AppDelegate.m (main.c would work, too). That way, queue will be initialized before any other calling object attempts to access it. In the remaining objects, I simply called queue. Returning a value from a variable is much faster than calling a function, and then checking the value of the variable before returning it.
In GlobalQueue.h:
#ifndef GlobalQueue_h
#define GlobalQueue_h
#include <stdio.h>
#include <dispatch/dispatch.h>
extern dispatch_queue_t queue;
extern dispatch_queue_t queue_ref(void);
#endif /* GlobalQueue_h */
In GlobalQueue.c:
#include "GlobalQueue.h"
dispatch_queue_t queue;
dispatch_queue_t queue_ref(void) {
if (!queue) {
queue = dispatch_queue_create_with_target("GlobalDispatchQueue", DISPATCH_QUEUE_SERIAL, dispatch_get_main_queue());
}
return queue;
}
To use:
#include "GlobalQueue.h" in any Objective-C or C implementation source file.
Call queue_ref() to use the dispatch queue. Once queue_ref() has been called, the queue can be used via the queue variable in all source files
Examples:
Calling queue_ref():
dispatch_queue_t serial_queue_with_queue_target = dispatch_queue_create_with_target("serial_queue_with_queue_target", DISPATCH_QUEUE_SERIAL, **queue_ref()**);
Calling queue:
dispatch_queue_t serial_queue_with_queue_target = dispatch_queue_create_with_target("serial_queue_with_queue_target", DISPATCH_QUEUE_SERIAL, **queue**));]
Just do
void * getSingleTon() {
static Class object = (Class *)malloc( sizeof( Class ) );
return &object;
}
which works in a concurrent environment too.

Resources