nezachem 616 Practically a Posting Shark

The following is a piece of my dateIOManip.h:

struct fullManip {};
ostream &operator << (ostream &out, fullPtr) {
    Date::Flags[&out] = "full";
    return out;
}

-Josh

Never ever put any definition with global linkage in the include file. An include file may contain only declarations.

nezachem 616 Practically a Posting Shark

I'm trying to write my own system calls. I have a .c file where I'm putting the system calls. My system calls use a struct, so I have declared a global variable that is an array of my struct. Lets just call it

//Stuff is the name of the struct I declared.
Stuff myStuff[100];

I have a function inside of my .c file called "init_Stuff". In order for the stuct to behave properly when a system call it made, init_Stuff must be called one time before any of the system calls will work. From within one of my system calls, I could just say "if the structs aren't initialized yet, go initialize them". But I'm wondering if there is a more elegant/normal way to just call init_Stuff right away. I also have a Makefile that currently just creates an object file of my .c file.

Declare (and define) it with the __init qualifier:

#include <linux/init.h>
void __init init_Stuff();

and call it from linux/init/main.c:start_kernel()

BestJewSinceJC commented: Thanks again +5
nezachem 616 Practically a Posting Shark

Going through the heavyweight processes of assembling the code into an executable and then starting a huge virtual machine emulator is something I want to avoid.

Why?

The thing is that I really just want to analyze the logic of an assembly program automatically using a separate C/C++ program.

A separate C/C++ program, capable of analyzing the logic of an assembly program, especially in an automatic manner, is no lighter than an eimulator.

nezachem 616 Practically a Posting Shark

Did you look at this?

Kanoisa commented: Nice link thanks, really helped me out +5
nezachem 616 Practically a Posting Shark

I seriously doubt that what you are looking for exists. Your goal is achieved by a combination of an assembler, a simulator, and a debugger (the latter two are usually bundled together).
You don't need to modify the simulator code. The process is to assemble your program, load it into a simulator, and run under debugger control. The debugger lets you execute a program line by line, view memory and registers, and even modify them. That's as I understand is what you want.

nezachem 616 Practically a Posting Shark

Let me see if I can clarify what I want.

I want to take a string of numbers (2009-0330) from c and basically have some script variable equal to the same numbers so I can then use these numbers in my script.

Does that answer your question?

Not really. Some example would be helpful. If you want to pass parameters to the script, you may form the command line dynamically via sprintf() .

nezachem 616 Practically a Posting Shark

I don't know what is wrong. You do. Does it not compile? does it crash at runtime? does it not produce the desired results?

nezachem 616 Practically a Posting Shark

Error code 2 is ERROR_FILE_NOT_FOUND. If the path you entered contains spaces, the statement

cin >> way[50];

will only read the first "word" of the path. Use getline().

nezachem 616 Practically a Posting Shark

And that's exactly what I've done... One more question though.. what is the order of events/changes to the client and the server that should take place after a condition like a child process of some client got killed or terminated abnormally, or even went through the request normally..
I don't get how should the server take appropriate actions regarding a return from the child process.

Really, that's an application logic. It all depends on what your server is doing, what sort of the protocol is agreed upon, what per-child state is kept in the parent, etc, etc.

nezachem 616 Practically a Posting Shark

I cannot figure out which client does this terminated child process belong to (i.e. the child process that was initially forked to process that particular client's request...)

It would be really helpful if you have any ideas..
Thank you

Nothing but a pid-to-client map, which you have to maintain manually.

nezachem 616 Practically a Posting Shark

My apologies for snipping out too much of my code and not providing details.

Accepted.

For us to be on a same page, can you provide a minimal compilable snippet which exhibits the behaviour you observe?

2) So ... should I do a realloc on my_args (and my_env ) to add a NULL pointer after the last string?

Absolutely yes.

3) from the man page: execve() executes the program pointed to by filename. filename must be either a binary executable, or a script starting with a line of the form "#! interpreter [arg]". In the latter case, the interpreter must be a valid pathname for an executable which is not itself a script, which will be invoked as interpreter [arg] filename.

<An attempt to explain deleted. My wording rather confuses than clarifies matters. I'll return to it later>

5) Constant declarations lead to portability problems. I cannot afford portability problems. Besides, I may not know the values of these environment varibles (or how many I might need to supply) prior to run time.

Frankly, I don't see any portability problems here. The second point is very valid, so please disregard my advice.

nezachem 616 Practically a Posting Shark

Tried to handle SIGCHLD the following way, and my server terminated after "detecting an interrupt signal":

void sigchld_handler(int code){
         if (code == 0){
                  printf("Child terminated normally with code %d\n", code);
         }
         else {
                  printf("Child terminated abnormally with code %d\n", code);
         }
}

void fork_function(){

       struct sigaction signal;
       signal.sa_flags = 0;
       signal.sa_handler = sigchld_handler;
       sigaction(SIGCHLD, &signal, NULL);

       int pid = fork();

       // Parent code
       if ( pid > 0 ){
                // Do whatever
       }

       // Child code
       else if ( pid == 0){
               // Executes the program provided by the client by calling exec...
       }
}

A few problems here.
First, fprintf() is not safe to call from a signal handler. See a Notes section of man 2 signal.
Second, the argument to the handler is not a termination code, but a signal which triggered the handler, SIGCHLD in this case. To obtain the exit status, you still need to wait. The signal just guarantees that some child has died, so wait has something meaningful to report.
Third, you don't have to setup the handler at each fork. The handler is not per-child. However, you have to reset the sigaction form within the handler itself. At some platforms, setting a signal up is a one-time deal. Once triggered, it drops back to some default state, which may explain the behaviour you observed.
Finally, remember that signals are not queued. The handler must expect that more than one child terminated, and wait for them in the loop. Of …

nezachem 616 Practically a Posting Shark

The way you describe it, no. You cannot fork into another system.
Usually you may assume that a target is running xinetd or some equivalent, and that it is properly configured. It will do the forking and execing on your behalf. Man xinetd and xinetd.conf.

nezachem 616 Practically a Posting Shark

Few things are obvious right away:
1. cmdstr is not initialized.
2. my_env and my_args are not terminated by NULL.
3. A first element of my_args is a program name. The way you set the arguments up is not fatal, but highly unconventional.
4. You must test the value returned by realloc.
5. You are working too hard. I'd just go with

char * my_env[] = {
    env_ROOT,
    env_EXTRALIBS,
    ....
    env_PATH,
    0
};

and a similar setup for my_args.

nezachem 616 Practically a Posting Shark

The postincrement is defined to return int . The preincrement is defined to return int& . In other words, y++ yields an lvalue, and ++y does not. That is, the result of y++ cannot be referenced. It can be const referenced however.

void foo(int & x);
void bar(const int & x);
void baz(int x)
{
	foo(x++);
	bar(x++);
}

testing.cpp(5) : error C2664: 'foo' : cannot convert parameter 1 from 'int' to 'int &'
testing - 1 error(s), 0 warning(s)

As you can see, no complaints on bar .

PS: All speculations based on the exact moment when the value of y changes are wrong. Remember, the function call is a sequence point. It means that when the call happens, all side effects are already completed - no matter which form of the increment is used.

PPS:
The rationale on this difference between pre and post forms of increment is approximately following:
Results of some expressions, such as a = b , ++i , x += y are bound to a variable. Loosely speaking, they have their respective addresses. Results of some other expressions, such as a + b , i++ , etc are not bound to anything. They just exist. There's no address which may refer to them.

nezachem 616 Practically a Posting Shark

if fclose(thefile) is closing all references to the file opened

fclose doesn't close references. It closes a FILE object.
It doesn't matter how many pointers point a particular one. It was opened once, and it must be closed also once.

nezachem 616 Practically a Posting Shark

I've added a counter on the number of connections added, which is incremented every time a new connection is added, but didn't work as expected, because each client would initiate an extra random connection/request after its initial request has been processed, and therefore the server exits before it processes the amount of connections allowed.

The server doesn't need to exit immediately. After accepting a desired number of connections, do not put the listening socket into rdset.

I'm also supposed to check how the forked child process terminates, in order to determine what kind of response should the server send back to the client, but its difficult to do without using a wait system call in the server, that allows me to check the status of the child process after it terminates, but I cannot use that since it would make the server "wait".

Handle SIGCHLD.

nezachem 616 Practically a Posting Shark

First of all,

(f1(x1)*sin(x1)+f2(x1,y1)*(cos(x1)-3*sin(x1)))/3*sin(x1)*(cos(y1)+cos(x1)*cos(y1))

is
((f1(x1)*sin(x1)+f2(x1,y1)*(cos(x1)-3*sin(x1)))/3)*sin(x1)*(cos(y1)+cos(x1)*cos(y1))
I don't think it is your intention.

Second, even assuming correct parenthesis placement, I can't see how you came up with this. I am getting something very different. Again, if you show step by step your math, that would clarify things a lot.

On a side note, I'd recommend to keep the algorithm related code as generic as possible. What I mean is that you factored functions out of the algorithm, yet hardcoded derivatives. Try to implement the algorithm in terms of functions and derivatives, and have derivatives calculated in separate routines. You will see how much more clean and manageable the code will become.

nezachem 616 Practically a Posting Shark

Line 21 doesn't do what you want it to do. Look closely.

PS: Such implementation of swap is very dangerous. In this program it's all right, but in general it may really hurt you.

nezachem 616 Practically a Posting Shark

I recently unrolled an insertion sort and on 60 items it was twice as slow as the looped version. I'm guessing that's because it was too big for the instruction cache, being 1032 KB.

The correct question would be "it was too big for the instruction cache line". I don't know how large is the cache line on your system, but usually it is no more than 512 bytes. It is quite reasonable to expect that an unrolled code doesn't fit a cache line, and suffers all the consequences of extra cache misses, as Salem already explained.

nezachem 616 Practically a Posting Shark

The err calculation (line 19) is meaningless. You need to watch not x^2+y^2 as you do, but f1^2 + f2^2. The goal is to get f1 and f2 to approach 0, isn't it?
The dy calculation (line 16) is wrong. How did you come up with this formula?
What is the purpose of lines 23-29? They would be executed once, after the loop has finished, that is the required accuracy already achieved.

nezachem 616 Practically a Posting Shark

Where did you get this? You must be an archaeologist. The code truly belongs to the past millenium.

The error comes from make, which tries to call lint. Lint is morally obsolete tool (again from seventies), which purpose was to validate the program syntax in such details the old compilers didn't bother to check. You have two choices. Either edit a makefile to remove the lint invocation, or do another digging session to find and install lint.

Ancient Dragon commented: Haven't used lint for over 25 years :) +27
mitrmkar commented: LOL +5
nezachem 616 Practically a Posting Shark

Thou shalt not while(!myfile.eof()) .

Since Dave Sinkula is silent, let me take on this:

while(!myfile.eof())
        {
                        myfile >> circle1 >> op >> circle2;
                        do_something();
        }

Consider the last good iteration. It consumed all the bytes from myfile, but didn't try to read beyond its limits. The end of file hasn't been seen; eof condition has not been set. The loop enters the next round. Of course, the very first read now hits end of file, and whatever you attempt to read is garbage.

nezachem 616 Practically a Posting Shark

Hi all,

I am in the process of optimizing my code and I was wondering what the fastest way is to compute trig functions.

libm

I profiled my code and to my astonishment discovered that one of the most time-consuming processes is computing cos(theta) and sin(theta) using the implementation of cos() and sin() in the cmath library.

What else does your code doing?

Are there other libraries that function better or should I consider computing these functions as truncated Taylor series'?

No. Taylor series is by no means optimal.

Incidentally, (maybe this is common knowledge), it turned out that the most time consuming process was using the pow() function! Lesson learned for me: never use pow!

Kartik

Show your profiles.

nezachem 616 Practically a Posting Shark

Line 55. How current is initialized?

nezachem 616 Practically a Posting Shark

not program output..but the content of the file PJ657_output.txt

that is the contents of PJ657_output.txt

He surely meant PJ657_Shapes.txt; it has been posted in the very first post:

input file is as follows
R 42 10
T 10 20
c 10
s 20
D 10 10 (this line is intentional and should return ERROR)

And the answer is that you do not handle the erroneous input. None of the ifs/else ifs gets satisfied, and the code prints the data obtained earlier - one print for each character in the D line.

nezachem 616 Practically a Posting Shark

Just to be on a safe side: after you added the flags, did the project files actually recompile?

nezachem 616 Practically a Posting Shark

First of all, congratulations. Yacc can recover from shift-reduce, whereas reduce-reduce is lethal.

Now, let's look why it happens. One of the sources of the conflict is

Expression		:	Expression PLUSOP Expression

Consider an expression a + b + c. There are 2 ways to parse it:
1. a + Expression
2. Expression + c
The first path would be shift (accept a as Term, and shift to the rest. The second path is reduce (accept a+b, and reduce it to Expression). Again, you didn't tell it which is correct.

There are 2 ways to overcome such shift-reduces. First, you can use %left and %right directives. Second, introduce more non-terminals, like I did with AdditiveExpression.

Reading my original code, it appears, to me, that if a '(' is seen at any time, then the parser needs to have the sub-tree begin with the top-level non-terminal.

It may even do so. The question, unanswered, is what to do when a ')' is encountered.

PS: You are going to have misterious problems with lines 16 and 19. Better start using %union right away.

nezachem 616 Practically a Posting Shark

Writing (line 25) is almost OK (I think that a "+1" was added in an act of desperation, it is not needed there).
Reading (line 30) is a problem. First, a readbuffer is not initialized, so the segfault is imminent. Second, you only reading 4 bytes of the message. Fix those and we can proceed further.

To answer your original question, yes you can. You just need to be careful.

Salem commented: Nice +19
nezachem 616 Practically a Posting Shark

Ignoring the specific case in question this statement is wrong as a generalisation.

For instance the compiler is required to change the constant 0 when used in a pointer context into the platforms representation of the NULL pointer, which note is not required to be all bits 0.

Strictly speaking, the standard doesn't require that; it only says that a 0 in a pointer context is guaranteed to compare unequal (6.3.2.3) etc etc. A 7.17 clause, which 6.3.2.3 refers to explains how a NULL macro shall be expanded. The standard doesn't mandate rewriting 0 in pointer context to what NULL would expand to.

The compiler is specificly required to change the observable logic in just the way you have claimed it has no right to.

Barring the debugger, how such change could be observed?

nezachem 616 Practically a Posting Shark

.

nezachem 616 Practically a Posting Shark

And how do you think that crt0.o file got generated? It was either with the compiler or an assembler, maybe a combination of the two.

I don't think you understand what we are talking about.

Let me rehash:
From a C standard point of view, success is signified by main returning 0. From a particular platform, a success is signified by application returning EXIT_SUCCESS, which may be different from 0. The question is, at which point a zero returned by main turns into that something different.
When one says "it is a compiler magic", it is implied that a compiler massages a return value into something else. This is what I object.
My point is that the zero returned from main is changed into platform appropriate SUCCESS at runtime, that is by the code separate from and not associated to and not adulterated by the compiler, the assembler, or any other component of a toolchain. Surely this code was compiled and assembled once.
Now what is your point?

nezachem 616 Practically a Posting Shark

Sure it can. On the proper system, when the program returns 0 to 'the system', the compiler adds exit code to the program to convert that 0 to the proper value before returning control to the system. It's code added between program code exit ( return 0; ) and actual program shutdown and system re-entrance.

Perhaps we are using a word compiler too liberally. As I said above, and you just confirmed, the conversion happens in one of the crt*.o files. These files are added by the linker. In a strict sense the compiler compiles a translation unit it into an object form - and may not (doesn't have a right to) change any observable logic. A return 0 compiles into return 0.

nezachem 616 Practically a Posting Shark

The compiler must convert it...

The compiler can't possibly do that. The conversion happens at runtime, by crt0 or something else.

nezachem 616 Practically a Posting Shark

I do not quite understand what do you mean by "back to the top level". You'd rather go recursively down, building the same tree. And yes, an expression grammar is inherently recursive.

nezachem 616 Practically a Posting Shark

Usually it is handled with primary expression, for example,

Expression
    : AdditiveExpression
    | PrimaryExpression
;
AdditiveExpression
    : Term
    | Term '+' Expression
;
PrimaryExpression
    : IDENTIFIER
    | NUMERIC_LITERAL
    | '(' Expression ')'
;
nezachem 616 Practically a Posting Shark

I understand, vaguely, what a reduce/reduce conflict is, but I don't understand why I'm getting one in my Yacc Parser. Can anyone help me out?

Expr			: 	LEFTPAR Expr RIGHTPAR			{ };
Term			: 	LEFTPAR Expr RIGHTPAR			{ };
Factor		:	LEFTPAR Expr RIGHTPAR			{ };
End			:	LEFTPAR Expr RIGHTPAR	                { };

How LEFTPAR Expr RIGHTPAR should be reduced? You give 4 ways to do it, and yacc cannot decide.

nezachem 616 Practically a Posting Shark

You think wrong. As a function argument, numbers is a pointer. Try to print N_cp.

nezachem 616 Practically a Posting Shark

Line 30 is suspicious. sizeof(numbers) yields a size of a pointer to double.

nezachem 616 Practically a Posting Shark

But are you telling me there is no mechanism by which the OS regains control of the CPU if a user application attempts to hog it and not give it back? I wouldn't be so persistent, except that my professor alluded to as much in class. I just haven't been able to figure out what that mechanism is.

The OS doesn't need a CPU. It is totally passive. The OS code executes only on behalf of the application process (leaving aside external interrupts). It may "regain control" from an application - only to grant it to another task.
If no task is ready to execute, there's no reason to take the control - there's nobody to give it to.
In fact, the while(1) is a legitimate implementation of a "null task" (on any architecture lacking waiti instruction). The system sits in such a loop until an external event triggers another task ready. At this moment the OS - since it is OS who processes the interrupt - will do the its rescheduling magic. The timeslicing, if implemented, is also a part of this mechanism.

nezachem 616 Practically a Posting Shark
void rules (bool rules[])
{
	bool nextLine[78];
...
}

What argument is passed to rules ? Does is relate to nextLine ?

nezachem 616 Practically a Posting Shark

My book says there are 3 ways to switch from user mode to kernel mode: an interrupt, a trap, and a system call. Since an interrupt can be only done through hardware, and since my book says a trap is a 'software generated interrupt', which is the same thing it says for a system call

A subtle difference between a software interrupt and a trap is that the latter is an exception (not an interrupt), but in any case them both are synchronous to an application flow. An application stuck in while(1) cannot do either.

. . what does the kernel do if a user application simply refuses to relinquish control of the CPU (as in Salem's case of while(1))? It would seem that the kernel cannot do anything in this case.

True. It cannot do anything. It is not supposed to do anything.

edit: I understand the info you've said to me, as I've been reading about that in my book at the same time. The OS has system calls made available so that user programs can ask for services that they otherwise wouldn't be privy to. But it still doesn't answer the question of 'what happens when a process refuses to give up the CPU'.

An idea of a system call (in any incarnation thinkable) is not about giving up a CPU. It is all about separating OS from an application. Even a single-task OS may (and should, and usually does) provide services in a protected …

nezachem 616 Practically a Posting Shark

Salem's answer is correct but it I am afraid it misses the point. An implicit question is "why a system call needs an interrupt?" Why can't an application just call a kernel procedure?

To answer these you have to realize that (a) a kernel procedure may issue privileged instructions not available for the user mode and (b) a kernel address space is usually different from the user's. An interrupt solves both problems since it elevates the execution mode.

The details really depend on a particular architecture.

since the CPU can only execute one instruction at a time, how does it work? For example, lets say a program X was hogging the CPU resources. The OS would have to execute a software interrupt to regain control of the CPU

This is conceptually wrong. It is an application which does a software interrupt to enter into OS.

nezachem 616 Practically a Posting Shark

Your understanding is generally correct.
The only problem is that the script filename is not the last argument ( argv[argc - 1] ) but rather the third:

nezachem@Home ~/tmp/dani/shebang $ ./script -z
argv[0]->/home/nezachem/tmp/dani/shebang/gg
argv[1]->-1 -2 -3 -4
argv[2]->./script
argv[3]->-z
could not open -z

Otherwise I would also add that #! is in fact a magic number, which tells exec() to execute a file by means of an interpreter - exactly as you've described.

PS: some unix variants may parse the "-1 -2 -3 -4" fragment into distinct arguments.

nezachem 616 Practically a Posting Shark

(Also note that the little face in the original example are created automatically by the blog software when I type colon colon asterisk (to indicate data pointer such as : ::*)

You may consider using code tags, such as ::* . In fact, it is a requirement for this forum.

nezachem 616 Practically a Posting Shark

I'm trying to create this pattern: http://mathworld.wolfram.com/Rule60.html

I cannot get my code to print this. It runs, it just does not print the right pattern. I know I am doing something wrong, I'm just not sure what.

int main()
{
	//Declare variables
	bool line[78];
	bool nextLine[78];
        void firstline();
        void coutline();
	void rules();
        void coutnextline();
	int r;


        //Create first line
        firstline();
...
//Create first line
void firstline ()
{
//declare variables
        bool line [78];
 ...
void coutline()
{
//declare variables
        bool line [78];

The bool line[78] declared in main() has nothing to do with bool line[78] delared in firstline() and other functions. All of them are distinct entities. firstline() initializes some local memory, which ceases to exist as soon as firstline returns. coutline() prints some uninitialized garbage. Etc.

You should either make your lines global (bad solution) or wrap them in a class (slightly better) or pass them around as parameters.

I didn't look at your generating code. At this moment it is irrelevant.

nezachem 616 Practically a Posting Shark
double *ptr;
spe_in_mbox_ write(thread_args[i].spe_context,(uint32_t*)&ptr,SPE_MBOX...)

its that second parameter thats bugging me giving me a bus error.


Thanks

It would be immensely helpful to see an actual code and an actual error message. For now I see a missing count argument.

nezachem 616 Practically a Posting Shark

You test 2 conditions (lines 18 and 21). One of them is supposed to filter out incorrect attempts. Another is supposed to accept correct ones. Logically, they should be mutual negations. The way they are written they are not. Hint.
Besides, why do you want to test both?

nezachem 616 Practically a Posting Shark

To begin with, remove semicolons at lines 100, 107, 112 and 119.

nezachem 616 Practically a Posting Shark

Take a look at SO_REUSEADDR socket option. For a record, I didn't recommend using it.