Getting invalid argument from semop - linux

I've set(semget + init to 1) a semaphore in process A. Forked A, and got B.
Forked B and got C (code of processes B,C is at another .c file, so I am passing the semid as a global integer with extern int semid).
Into the process C code, I try to apply down(semid) and getting "invalid argument" error.
What I am doing in the code for down function is this:
struct sembuf sem_d;
sem_d.sem_num = 0;
sem_d.sem_op = -1;
sem_d.sem_flg = 0;
if ( semop(semid, &sem_d, 1) == -1 )
{
perror("error with down function");
return -1;
}
What am I doing wrong?
I've also have reassured that the semid from when the semaphore is initialized is the same before semop.
Also, in process A,B I am using wait(-1).

I'm not sure if you are allowed to use semget() over forks - it's a different process space after all.
semget() is part of the old System V semaphores anyway.
I would recommend to switch over to the POSIX semaphores - sem_open(), sem_wait() and friends and use named semaphores. Then open the same semaphore names in each process.

Related

How an exit code is determined in a multithreaded program when one of the threads fails?

struct func
{
int& i;
func(int& i_):i(i_){}
void operator()()
{
for (unsigned j = 0; j < 1000000; ++j)
{
++i;
}
}
};
int main()
{
int some_local_state = 0;
func my_func(some_local_state);
std::thread my_thread(my_func);
my_thread.detach();
return 0;
}
Output is
(process 1528) exited with code -1073741819
What determines the exit code? What does detaching mean for a Windows process?
In this example, the error code -1073741819 (0xc0020001) is not produced by your executable but by the operating system which decided to kill your process.
You also asked a question (in the comments) about detaching a thread.
This means that you will not use join() on this thread, thus you launch it, but you are not interested in knowing when it finishes its work.
EDIT
In my first answer I misread the example and thought the abrupt termination was due to an invalid memory access through the
uninitialized i reference.
It was wrong since i is actually initialised in order to reference some_local_state.
However, when main() returns some_local_state does not exist anymore while being still referenced by the thread.
Nothing is said about what happens to the detached thread at the exact moment when main() returns.
Does this thread terminate immediately before the local variables of main() disappear? I really have doubts about this...
This probably explains the abnormal termination of the process.

pthread_create exits the program after finishing function

I try to create program that takes power readings about 10 times in one second and start a new thread every second/minute to update mysql database while the main program continues taking readings. But after I use pthread_create function runs once and then program seems to exit. It is my first time trying to do something with pthread and obviously I am doing something wrong. Please help because it seems smart to use new thread to update mysql, so it will not interrupt main program. I will add my code (bit that are important I think)
the function:
void *showreadout(float readout,int l, int s) {
printf("readout: %f loops: %i sec: %i\n",readout,l,s);
return NULL;
}
and stuff from main:
pthread_t thread;
int p = 0, startminute = currentminute(),startsec,u;
float secreadout;
while (startminute == currentminute()) {
startsec = currentsec();
u = 0;
secreadout = 0;
while (startsec == currentsec()) {
secreadout += doloop(pinnumber);
u++;
}
pthread_create(&thread, NULL, showreadout(secreadout/u,u, startsec), NULL);
p++;
}
The problem was that I was trying to send variables with pthread_create() to my function and it worked once but then things seemed to go "tits up" or rather the program just stopped.
I solved it by making global variable for the readout and updated it after end of each second before calling my function with pthread_create() and using global variable in my function. I dont know is it the right way to approach it but it seems to work.

Providing Concurrency Between Pthreads

I am working on multithread programming and I am stuck on something.
In my program there are two tasks and two types of robots for carrying out the tasks:
Task 1 requires any two types of robot and
task 2 requires 2 robot1 type and 2 robot2 type.
Total number of robot1 and robot2 and pointers to these two types are given for initialization. Threads share these robots and robots are reserved until a thread is done with them.
Actual task is done in doTask1(robot **) function which takes pointer to a robot pointer as parameter so I need to pass the robots that I reserved. I want to provide concurrency. Obviously if I lock everything it will not be concurrent. robot1 is type of Robot **. Since It is used by all threads before one thread calls doTask or finish it other can overwrite robot1 so it changes things. I know it is because robot1 is shared by all threads. Could you explain how can I solve this problem? I don't want to pass any arguments to thread start routine.
rsc is my struct to hold number of robots and pointers that are given in an initialization function.
void *task1(void *arg)
{
int tid;
tid = *((int *) arg);
cout << "TASK 1 with thread id " << tid << endl;
pthread_mutex_lock (&mutexUpdateRob);
while (rsc->totalResources < 2)
{
pthread_cond_wait(&noResource, &mutexUpdateRob);
}
if (rsc->numOfRobotA > 0 && rsc->numOfRobotB > 0)
{
rsc->numOfRobotA --;
rsc->numOfRobotB--;
robot1[0] = &rsc->robotA[counterA];
robot1[1] = &rsc->robotB[counterB];
counterA ++;
counterB ++;
flag1 = true;
rsc->totalResources -= 2;
}
pthread_mutex_unlock (&mutexUpdateRob);
doTask1(robot1);
pthread_mutex_lock (&mutexUpdateRob);
if(flag1)
{
rsc->numOfRobotA ++;
rsc->numOfRobotB++;
rsc->totalResources += 2;
}
if (totalResource >= 2)
{
pthread_cond_signal(&noResource);
}
pthread_mutex_unlock (&mutexUpdateRob);
pthread_exit(NULL);
}
If robots are global resources, threads should not dispose of them. It should be the duty of the main thread exit (or cleanup) function.
Also, there sould be a way for threads to locate unambiguously the robots, and to lock their use.
The robot1 array seems to store the robots, and it seems to be a global array. However:
its access is not protected by a mutex (pthread_mutex_t), it seems now that you've taken care of that.
Also, the code in task1 is always modifying entries 0 and 1 of this array. If two threads or more execute that code, the entries will be overwritten. I don't think that it is what you want. How will that array be used afterwards?
In fact, why does this array need to be global?
The bottom line is this: as long as this array is shared by threads, they will have problems working concurrently. Think about it this way:
You have two companies using robots to work, but they're using the same truck (robot1) to move the robots around. How are these two companies supposed to function properly, and efficiently with only one truck?

List all threads within the current process?

I'm trying to implement a syscall which allows me to get the number of threads for the current process. I am new to the Linux kernel, and so my understanding of it is limited.
Currently, I am trying to iterate through all the task_structs, and compare their thread group leader's PID with the current thread group leader's PID:
// ...
int nthreads = 0;
struct task_struct *task_it;
for_each_process(task_it) {
if (task_it->group_leader->pid == current->group_leader->pid) {
nthreads++;
}
}
// ...
However, this doesn't seem to be working (a quick test spawning some pthreads is still giving 1. What about the group_leader is common to all threads in the same process?
The problem with your code is that what the kernel calls a PID (the pid field of task_struct) is what userspace calls a TID (ie. it's what's returned by sys_gettid() and is unique per thread). What userspace calls a PID is called a TGID in the kernel (for "task group ID") - that's what the sys_getpid() syscall returns.
You don't need to actually check the TGID, though - just comparing the struct task_struct * pointers is enough:
if (task_it->group_leader == current->group_leader) {
By the way, you could just iterate over the thread_group list that current is a member of (with while_each_thread()), then you wouldn't need any test at all. Or even better, just use get_nr_threads(current).
Note that all methods that loop over the task lists need to be wrapped in rcu_read_lock(); / rcu_read_unlock(); to be correct.
This chunk of code is a good demonstration.
The following C program creates a list of all processes in the process
table of a node and shows in one column the number of threads for any
single process. Using this tool, it was possible to identify that the
network daemon created a new thread anytime a network problem
occurred. A severe network problem was responsible for the logon
problems.
#include "sys/param.h"
#include "sys/pstat.h"
int main ( void )
{
struct pst_status * psa = NULL;
struct pst_status * prc = NULL;
struct pst_dynamic psd;
long nproc = 0;
long thsum = 0;
long i;
if ( pstat_getdynamic(&psd, sizeof(psd), 1, 0) == -1 )
(void)perror("pstat_getdynamic failed");
// Get the number of active processes from pst_dynamic
nproc = psd.psd_activeprocs;
psa = (struct pst_status *)malloc(nproc * sizeof(struct pst_status));
// Read the info about the active processes into the array 'psa'
if ( pstat_getproc(psa, sizeof(struct pst_status), nproc, 0) == -1 )
(void)perror("pstat_getproc failed");
(void)printf("\n\n------------------------------------------------------------------------------");
(void)printf("\n %5s | %5s |%7s| %5s | %s", "PID", "UID", "Threads", "RSS", "Command");
(void)printf("\n------------------------------------------------------------------------------");
// Report the process info as required
prc = (struct pst_status *)psa;
for (i=0; i < nproc; i++)
{
(void)printf("\n %5ld | ", prc->pst_pid);
(void)printf("%5ld | ", prc->pst_uid);
(void)printf("%5ld | ", prc->pst_nlwps);
(void)printf("%5ld | ", prc->pst_rssize);
(void)printf("%s ", prc->pst_cmd);
thsum += prc->pst_nlwps;
++prc;
}
(void)printf("\n\n*** %ld processes, %ld threads running\n\n", nproc, thsum);
(void)free(psa);
(void)exit(0);
}
Found here:
http://h21007.www2.hp.com/portal/site/dspp/menuitem.863c3e4cbcdc3f3515b49c108973a801?ciid=060818f70fe0211018f70fe02110275d6e10RCRD
Here's another link using task_struct:
http://tuxthink.blogspot.com/2011/03/using-foreachprocess-in-proc-entry.html

Strange behavior of printk in linux kernel module

I am writing a code for linux kernel module and experiencing a strange behavior in it.
Here is my code:
int data = 0;
void threadfn1()
{
int j;
for( j = 0; j < 10; j++ )
printk(KERN_INFO "I AM THREAD 1 %d\n",j);
data++;
}
void threadfn2()
{
int j;
for( j = 0; j < 10; j++ )
printk(KERN_INFO "I AM THREAD 2 %d\n",j);
data++;
}
static int __init abc_init(void)
{
struct task_struct *t1 = kthread_run(threadfn1, NULL, "thread1");
struct task_struct *t2 = kthread_run(threadfn2, NULL, "thread2");
while( 1 )
{
printk("debug\n"); // runs ok
if( data >= 2 )
{
kthread_stop(t1);
kthread_stop(t2);
break;
}
}
printk(KERN_INFO "HELLO WORLD\n");
}
Basically I was trying to wait for threads to finish and then print something after that.
The above code does achieve that target but WITH "printk("debug\n");" not commented. As soon as I comment out printk("debug\n"); to run the code without debugging and load the module through insmod command, the module hangs on and it seems like it gets lost in recursion. I dont why printk effects my code in such a big way?
Any help would be appreciated.
regards.
You're not synchronizing the access to the data-variable. What happens is, that the compiler will generate a infinite loop. Here is why:
while( 1 )
{
if( data >= 2 )
{
kthread_stop(t1);
kthread_stop(t2);
break;
}
}
The compiler can detect that the value of data never changes within the while loop. Therefore it can completely move the check out of the loop and you'll end up with a simple
while (1) {}
If you insert printk the compiler has to assume that the global variable data may change (after all - the compiler has no idea what printk does in detail) therefore your code will start to work again (in a undefined behavior kind of way..)
How to fix this:
Use proper thread synchronization primitives. If you wrap the access to data into a code section protected by a mutex the code will work. You could also replace the variable data and use a counted semaphore instead.
Edit:
This link explains how locking in the linux-kernel works:
http://www.linuxgrill.com/anonymous/fire/netfilter/kernel-hacking-HOWTO-5.html
With the call to printk() removed the compiler is optimising the loop into while (1);. When you add the call to printk() the compiler is not sure that data isn't changed and so checks the value each time through the loop.
You can insert a barrier into the loop, which forces the compiler to reevaluate data on each iteration. eg:
while (1) {
if (data >= 2) {
kthread_stop(t1);
kthread_stop(t2);
break;
}
barrier();
}
Maybe data should be declared volatile? It could be that the compiler is not going to memory to get data in the loop.
Nils Pipenbrinck's answer is spot on. I'll just add some pointers.
Rusty's Unreliable Guide to Kernel Locking (every kernel hacker should read this one).
Goodbye semaphores?, The mutex API (lwn.net articles on the new mutex API introduced in early 2006, before that the Linux kernel used semaphores as mutexes).
Also, since your shared data is a simple counter, you can just use the atomic API (basically, declare your counter as atomic_t and access it using atomic_* functions).
Volatile might not always be "bad idea". One needs to separate out
the case of when volatile is needed and when mutual exclusion
mechanism is needed. It is non optimal when one uses or misuses
one mechanism for the other. In the above case. I would suggest
for optimal solution, that both mechanisms are needed: mutex to
provide mutual exclusion, volatile to indicate to compiler that
"info" must be read fresh from hardware. Otherwise, in some
situation (optimization -O2, -O3), compilers might inadvertently
leave out the needed codes.

Resources